Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion scripts/autogen_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,38 @@ def make_outline(md_source):
)
return outline

def add_copy_buttons_to_code(html_content):
def add_button(match):
full_match = match.group(0)

if 'style="white-space:pre;overflow-x:auto' in full_match:
return full_match

if "┏━━━━━━" in full_match or "Total params:" in full_match:
return full_match

copy_button_html = (
'<div class="code__container">'
'<button class="code__copy--button">'
'<i class="icon--copy"></i>'
'<span class="code__copy--tooltip">Copy</span>'
'</button>'
)
return f'{copy_button_html}{full_match}</div>'

combined_pattern = r'(<div class="k-default-codeblock">.*?</div>)|(<pre[^>]*>.*?</pre>)'

def handle_match(m):
if m.group(1):
return m.group(1)
else:
return add_button(m)

return re.sub(combined_pattern, handle_match, html_content, flags=re.DOTALL)


def render_markdown_to_html(md_content):
return markdown.markdown(
html_content = markdown.markdown(
md_content,
extensions=[
"fenced_code",
Expand All @@ -96,6 +125,8 @@ def render_markdown_to_html(md_content):
},
},
)
html_content = add_copy_buttons_to_code(html_content)
return html_content


def set_active_flag_in_nav_entry(entry, relative_url):
Expand Down
65 changes: 65 additions & 0 deletions theme/css/docs.css
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,71 @@ pre {
font-size: 100%;
}

.code__container {
position: relative;
display: block;
overflow: visible;
}

.code__copy--button {
position: absolute;
right: 0;
top: 0;
background-color: rgba(255, 255, 255, 0.1);
border: none;
border-radius: 4px;
cursor: pointer;
width: 32px;
height: 32px;
z-index: 10;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.2s;
}

.code__container pre {
margin: 0;
padding: 28px 45px 24px 24px;
overflow-x: auto;
border-radius: 8px;
line-height: 1.5;
}

.code__copy--button .icon--copy {
filter: invert(1);
width: 18px;
height: 18px;
opacity: 0.6;
}

.code__copy--button:hover {
background-color: rgba(255, 255, 255, 0.2);
}

.code__copy--button:hover .icon--copy {
opacity: 1;
}

.code__copy--tooltip {
font-size: 11px;
padding: 4px 8px;
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 40px;
display: none;
border-radius: 4px;
z-index: 101;
white-space: nowrap;
background-color: #ffffff;
color: var(--text-red);
}

.code__copy--button.active .code__copy--tooltip {
display: block;
}

hr {
margin-top: 2rem;
margin-bottom: 2rem;
Expand Down
17 changes: 14 additions & 3 deletions theme/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@ const copyButtons = document.querySelectorAll('.code__copy--button');
copyButtons.forEach((button) => {
button.addEventListener('click', () => {
const parent = button.parentNode;
const text = parent.querySelector('.language-python').innerText;
let text = parent.querySelector('code').innerText;

if (text.includes('>>>')) {
text = text.split('\n')
.filter(line => /^(>>>|\.\.\.)/.test(line.trim()))
.map(line => line.replace(/^(>>>|\.\.\.) ?/, ""))
.join('\n');
}

const inputElement = document.createElement('textarea');
console.log('text', text);
inputElement.value = text;
Expand All @@ -34,9 +42,12 @@ copyButtons.forEach((button) => {
document.execCommand('copy');
inputElement.remove();

button.querySelector('.code__copy--tooltip').style.display = 'block';
const tooltip = button.querySelector('.code__copy--tooltip');
tooltip.textContent = 'Copied!';
tooltip.style.display = 'block';
setTimeout(() => {
button.querySelector('.code__copy--tooltip').style.display = 'none';
tooltip.textContent = 'Copy';
tooltip.style.display = 'none';
}, 2000);
});
});
Expand Down
Loading