diff --git a/docs/images/copyCode.png b/docs/images/copyCode.png index 9453e2c5ec..6cf282a49f 100644 Binary files a/docs/images/copyCode.png and b/docs/images/copyCode.png differ diff --git a/docs/images/wrapCodeOff.png b/docs/images/wrapCodeOff.png new file mode 100644 index 0000000000..bd1349a576 Binary files /dev/null and b/docs/images/wrapCodeOff.png differ diff --git a/docs/images/wrapCodeOn.png b/docs/images/wrapCodeOn.png new file mode 100644 index 0000000000..1e06f59154 Binary files /dev/null and b/docs/images/wrapCodeOn.png differ diff --git a/docs/images/wrapCodeOnWordBreak.png b/docs/images/wrapCodeOnWordBreak.png new file mode 100644 index 0000000000..3984a5290b Binary files /dev/null and b/docs/images/wrapCodeOnWordBreak.png differ diff --git a/docs/userGuide/plugins/codeBlockCopyButtons.mbdf b/docs/userGuide/plugins/codeBlockCopyButtons.mbdf index f1452f813e..ba1ba51779 100644 --- a/docs/userGuide/plugins/codeBlockCopyButtons.mbdf +++ b/docs/userGuide/plugins/codeBlockCopyButtons.mbdf @@ -1,6 +1,6 @@ ### Plugin: `codeBlockCopyButtons` -This plugin adds a 'copy' button to fenced code blocks so that readers can copy the code easily. +This plugin adds a *copy* button to fenced code blocks so that readers can copy the code easily. To enable it, simply add `codeBlockCopyButtons` to your site's plugins. @@ -13,6 +13,6 @@ To enable it, simply add `codeBlockCopyButtons` to your site's plugins. } ``` -This is what it'll look like once added +This is what it'll look like once added: diff --git a/docs/userGuide/plugins/codeBlockWrapButtons.mbdf b/docs/userGuide/plugins/codeBlockWrapButtons.mbdf new file mode 100644 index 0000000000..84822dc942 --- /dev/null +++ b/docs/userGuide/plugins/codeBlockWrapButtons.mbdf @@ -0,0 +1,28 @@ +### Plugin: `codeBlockWrapButtons` + +This plugin adds a *wrap text* button to fenced code blocks so that readers can read long lines of code without scrolling sideways. + +To enable it, simply add `codeBlockWrapButtons` to your site's plugins. + +```js {heading="site.json"} +{ + ... + "plugins": [ + "codeBlockWrapButtons" + ], +} +``` + +This is what it'll look like once added: + + + +Clicking the *wrap text* button will result in the following: + + + +In case a single long word is encountered, it will be split across multiple lines similar to the following: + + + +--Note: the default `foo` code was replaced with [_Lorem ipsum_](https://en.wikipedia.org/wiki/Lorem_ipsum) text for demonstration purposes.-- diff --git a/docs/userGuide/syntax/code.mbdf b/docs/userGuide/syntax/code.mbdf index 4802d37c80..9158932a68 100644 --- a/docs/userGuide/syntax/code.mbdf +++ b/docs/userGuide/syntax/code.mbdf @@ -168,6 +168,17 @@ A _copy_ button can be added to code blocks using the `codeBlockCopyButtons` plu
+##### Wrap text button + +A _wrap text_ button can be added to code blocks using the `codeBlockWrapButtons` plugin: + + + + + + +
+ #### Inline Code ##### Syntax coloring diff --git a/docs/userGuide/usingPlugins.md b/docs/userGuide/usingPlugins.md index 57fbf958b0..e3aac8d2e1 100644 --- a/docs/userGuide/usingPlugins.md +++ b/docs/userGuide/usingPlugins.md @@ -58,6 +58,7 @@ MarkBind has a set of built-in plugins that can be used immediately without inst + diff --git a/packages/core-web/src/styles/markbind.css b/packages/core-web/src/styles/markbind.css index 03d57314a3..061cf38acb 100644 --- a/packages/core-web/src/styles/markbind.css +++ b/packages/core-web/src/styles/markbind.css @@ -24,6 +24,7 @@ pre > code.hljs { background-clip: padding-box; /* for IE9+, Firefox 4+, Opera, Chrome */ border-radius: 5px; counter-reset: line; + width: 100%; } pre > code.hljs[heading] { @@ -201,6 +202,7 @@ li.footnote-item:target { text-align: right; top: 0; width: 3em; + height: 100%; } /* hide popover, tooltip content */ @@ -241,41 +243,46 @@ li.footnote-item:target { opacity: 1; } -/* "Copy" code block button */ +/* "Copy" and "wrap text" code block buttons */ pre { position: relative; + display: flex; } -button.copy-btn { +.function-btn-container { + display: grid; + height: max-content; +} + +button.function-btn { border: none; background-color: transparent; color: darkgray; cursor: pointer; display: inline-block; padding: 0.35rem; - position: absolute; - right: 0.1rem; - top: 0.1rem; text-align: center; white-space: nowrap; } -.copy-btn:hover { +.function-btn:hover { transition: all 0.5s ease; - box-shadow: 0 0 0.25rem rgba(173, 173, 173, 0.8); + color: gray; } -.copy-btn-body { +.function-btn-body { align-items: center; display: flex; } -.copy-btn svg { +.function-btn svg { fill: currentColor; } -.copy-btn:focus { - box-shadow: 0 0 0.125rem rgba(173, 173, 173, 0.8); +/* Wrap class used for "wrap text" button. */ +code.wrap { + white-space: pre-wrap; + word-wrap: break-word; } /* Octicon sizing */ diff --git a/packages/core/src/plugins/codeBlockButtonsAssets/codeBlockButtonsContainer.js b/packages/core/src/plugins/codeBlockButtonsAssets/codeBlockButtonsContainer.js new file mode 100644 index 0000000000..6f7f23fccd --- /dev/null +++ b/packages/core/src/plugins/codeBlockButtonsAssets/codeBlockButtonsContainer.js @@ -0,0 +1,18 @@ +const cheerio = module.parent.require('cheerio'); +const CONTAINER_HTML = '
'; + +function isFunctionBtnContainer(node) { + return cheerio(node).hasClass('function-btn-container'); +} + +function doesFunctionBtnContainerExistInNode(node) { + return cheerio(node) + .children() + .is((index, element) => isFunctionBtnContainer(element)); +} + +module.exports = { + CONTAINER_HTML, + isFunctionBtnContainer, + doesFunctionBtnContainerExistInNode, +}; diff --git a/packages/core/src/plugins/codeBlockCopyButtons.js b/packages/core/src/plugins/codeBlockCopyButtons.js index 67c4155b8d..31fb283e99 100644 --- a/packages/core/src/plugins/codeBlockCopyButtons.js +++ b/packages/core/src/plugins/codeBlockCopyButtons.js @@ -1,4 +1,9 @@ const cheerio = module.parent.require('cheerio'); +const { + CONTAINER_HTML, + doesFunctionBtnContainerExistInNode, + isFunctionBtnContainer, +} = require('./codeBlockButtonsAssets/codeBlockButtonsContainer'); const COPY_ICON = ` -
+ const html = ``; @@ -26,7 +31,7 @@ function getButtonHTML() { const copyCodeBlockScript = ``; + +module.exports = { + getScripts: () => [wrapCodeBlockScript], + processNode: (pluginContext, node) => { + if (node.name === 'pre' && !doesFunctionBtnContainerExistInNode(node)) { + cheerio(node).append(CONTAINER_HTML); + } else if (isFunctionBtnContainer(node)) { + cheerio(node).append(getButtonHTML()); + } + }, +};