diff --git a/.buildinfo b/.buildinfo index 96715d5d..474530f2 100644 --- a/.buildinfo +++ b/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 8427171e2350e8c0be3fff507b9c34b6 +config: 650570dee05afa6059462e088be39c01 tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/_sources/getting_started/example_scenes.rst.txt b/_sources/getting_started/example_scenes.rst.txt index 4a9aa4f1..6c3a72bb 100644 --- a/_sources/getting_started/example_scenes.rst.txt +++ b/_sources/getting_started/example_scenes.rst.txt @@ -450,8 +450,7 @@ CoordinateSystemExample # system defined by them. f_always(dot.move_to, lambda: axes.c2p(1, 1)) self.play( - axes.animate.scale(0.75), - axes.animate.to_corner(UL), + axes.animate.scale(0.75).to_corner(UL), run_time=2, ) self.wait() diff --git a/_static/check-solid.svg b/_static/check-solid.svg new file mode 100644 index 00000000..9cbca868 --- /dev/null +++ b/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_static/copybutton.css b/_static/copybutton.css index 75b17a83..3a863dd6 100644 --- a/_static/copybutton.css +++ b/_static/copybutton.css @@ -1,29 +1,31 @@ /* Copy buttons */ -a.copybtn { +button.copybtn { position: absolute; - top: .2em; - right: .2em; - width: 1em; - height: 1em; - opacity: .3; - transition: opacity 0.5s; - border: none; + top: .3em; + right: .5em; + width: 1.7rem; + height: 1.7rem; + opacity: 0; + transition: opacity 0.3s, border .3s; user-select: none; + padding: 0; + border: none; + outline: none; +} + +button.copybtn img { + width: 100%; } div.highlight { position: relative; } -a.copybtn > img { - vertical-align: top; - margin: 0; - top: 0; - left: 0; - position: absolute; +.highlight:hover button.copybtn { + opacity: .7; } -.highlight:hover .copybtn { +.highlight button.copybtn:hover { opacity: 1; } diff --git a/_static/copybutton.js b/_static/copybutton.js index 65a59167..bf5ea1ce 100644 --- a/_static/copybutton.js +++ b/_static/copybutton.js @@ -17,6 +17,24 @@ const messages = { 'copy_to_clipboard': 'In die Zwischenablage kopieren', 'copy_success': 'Kopiert!', 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copié dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', } } @@ -26,6 +44,8 @@ if( document.documentElement.lang !== undefined locale = document.documentElement.lang } +const path_static = `${DOCUMENTATION_OPTIONS.URL_ROOT}_static/`; + /** * Set up copy/paste for code blocks */ @@ -54,12 +74,18 @@ const clearSelection = () => { } // Changes tooltip text for two seconds, then changes it back -const temporarilyChangeTooltip = (el, newText) => { - const oldText = el.getAttribute('data-tooltip') +const temporarilyChangeTooltip = (el, oldText, newText) => { el.setAttribute('data-tooltip', newText) setTimeout(() => el.setAttribute('data-tooltip', oldText), 2000) } +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + img = el.querySelector("img"); + img.setAttribute('src', `${path_static}check-solid.svg`) + setTimeout(() => img.setAttribute('src', `${path_static}copy-button.svg`), 2000) +} + const addCopyButtonToCodeCells = () => { // If ClipboardJS hasn't loaded, wait a bit and try again. This // happens because we load ClipboardJS asynchronously. @@ -76,9 +102,9 @@ const addCopyButtonToCodeCells = () => { const pre_bg = getComputedStyle(codeCell).backgroundColor; const clipboardButton = id => - ` - ${messages[locale]['copy_to_clipboard']} - ` + `` codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) }) @@ -88,11 +114,15 @@ function escapeRegExp(string) { // Callback when a copy button is clicked. Will be passed the node that was clicked // should then grab the text and replace pieces of text that shouldn't be used in output -function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true) { +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { var regexp; var match; + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + // create regexp to capture prompt and remaining line if (isRegexp) { regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') @@ -102,24 +132,31 @@ function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onl const outputLines = []; var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; for (const line of textContent.split('\n')) { match = line.match(regexp) - if (match) { - promptFound = true - if (removePrompts) { + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { outputLines.push(match[2]) } else { outputLines.push(line) } - } else { - if (!onlyCopyPromptLines) { - outputLines.push(line) - } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) } } // If no lines with the prompt were found then just use original lines - if (promptFound) { + if (lineGotPrompt.some(v => v === true)) { textContent = outputLines.join('\n'); } @@ -133,7 +170,7 @@ function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onl var copyTargetText = (trigger) => { var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); - return formatCopyText(target.innerText, '', false, true, true) + return formatCopyText(target.innerText, '', false, true, true, true, '', '') } // Initialize with a callback so we can modify the text before copy @@ -142,11 +179,12 @@ var copyTargetText = (trigger) => { // Update UI with error/success messages clipboard.on('success', event => { clearSelection() - temporarilyChangeTooltip(event.trigger, messages[locale]['copy_success']) + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) }) clipboard.on('error', event => { - temporarilyChangeTooltip(event.trigger, messages[locale]['copy_failure']) + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) }) } diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js index 57caa558..b9168c55 100644 --- a/_static/copybutton_funcs.js +++ b/_static/copybutton_funcs.js @@ -4,11 +4,15 @@ function escapeRegExp(string) { // Callback when a copy button is clicked. Will be passed the node that was clicked // should then grab the text and replace pieces of text that shouldn't be used in output -export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true) { +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { var regexp; var match; + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + // create regexp to capture prompt and remaining line if (isRegexp) { regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') @@ -18,24 +22,31 @@ export function formatCopyText(textContent, copybuttonPromptText, isRegexp = fal const outputLines = []; var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; for (const line of textContent.split('\n')) { match = line.match(regexp) - if (match) { - promptFound = true - if (removePrompts) { + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { outputLines.push(match[2]) } else { outputLines.push(line) } - } else { - if (!onlyCopyPromptLines) { - outputLines.push(line) - } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) } } // If no lines with the prompt were found then just use original lines - if (promptFound) { + if (lineGotPrompt.some(v => v === true)) { textContent = outputLines.join('\n'); } diff --git a/development/about.html b/development/about.html index faedcdd3..78117bed 100644 --- a/development/about.html +++ b/development/about.html @@ -1,7 +1,7 @@ - + @@ -9,8 +9,8 @@ - - + +