diff --git a/docs/helpers.md b/docs/helpers.md index 57eaa41d0..006b8e853 100644 --- a/docs/helpers.md +++ b/docs/helpers.md @@ -6,35 +6,69 @@ docsify extends Markdown syntax to make your documents more readable. ## Callouts -### Important content +Docsify supports [GitHub style](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) callouts (also known as "admonitions" or "alerts"). -Important content like: + +> [!CAUTION] +> **Caution** callouts communicate negative potential consequences of an action. -```markdown -!> **Time** is money, my friend! -``` + +> [!IMPORTANT] +> **Important** callouts communicate information necessary for users to succeed. -is rendered as: + +> [!NOTE] +> **Note** callouts communicate information that users should take into account. -!> **Time** is money, my friend! + +> [!TIP] +> **Tip** callouts communicate optional information to help a user be more successful. -### Tips + +> [!WARNING] +> **Warning** callouts communicate potential risks user should be aware of. -General tips like: +**Markdown** + ```markdown -?> _TODO_ unit test +> [!CAUTION] +> **Caution** callouts communicate negative potential consequences of an action. + +> [!IMPORTANT] +> **Important** callouts communicate information necessary for users to succeed. + +> [!NOTE] +> **Note** callouts communicate information that users should take into account. + +> [!TIP] +> **Tip** callouts communicate optional information to help a user be more successful. + +> [!WARNING] +> **Warning** callouts communicate potential risks user should be aware of. ``` -are rendered as: +### Legacy Style ⚠️ -?> _TODO_ unit test +The following Docsify v4 callout syntax has been deprecated and will be removed in a future version. + +!> **Important** callouts communicate information necessary for users to succeed. + +?> **Tip** callouts communicate optional information to help a user be more successful. + +**Markdown** + +```markdown +!> **Important** callouts communicate information necessary for users to succeed. + +?> **Tip** callouts communicate optional information to help a user be more successful. +``` ## Link attributes ### disabled -```md +```markdown [link](/demo ':disabled') ``` @@ -42,7 +76,7 @@ are rendered as: Sometimes we will use some other relative path for the link, and we have to tell docsify that we don't need to compile this link. For example: -```md +```markdown [link](/demo/) ``` @@ -50,13 +84,13 @@ It will be compiled to `link` and will load `/demo/README Now you can do that -```md +```markdown [link](/demo/ ':ignore') ``` You will get `link`html. Do not worry, you can still set the title for the link. -```md +```markdown [link](/demo/ ':ignore title') link @@ -64,14 +98,14 @@ You will get `link`html. Do not worry, you can still set th ### target -```md +```markdown [link](/demo ':target=_blank') [link](/demo2 ':target=_self') ``` ## Task lists -```md +```markdown - [ ] foo - bar - [x] baz @@ -91,19 +125,19 @@ You will get `link`html. Do not worry, you can still set th ### Class names -```md +```markdown ![logo](https://docsify.js.org/_media/icon.svg ':class=someCssClass') ``` ### IDs -```md +```markdown ![logo](https://docsify.js.org/_media/icon.svg ':id=someCssId') ``` ### Sizes -```md +```markdown ![logo](https://docsify.js.org/_media/icon.svg ':size=WIDTHxHEIGHT') ![logo](https://docsify.js.org/_media/icon.svg ':size=50x100') ![logo](https://docsify.js.org/_media/icon.svg ':size=100') @@ -119,7 +153,7 @@ You will get `link`html. Do not worry, you can still set th ## Heading IDs -```md +```markdown ### Hello, world! :id=hello-world ``` diff --git a/docs/ui-kit.md b/docs/ui-kit.md index 1d32275a1..0c9057dfd 100644 --- a/docs/ui-kit.md +++ b/docs/ui-kit.md @@ -53,6 +53,40 @@ ## Callouts +### Github Style + + +> [!CAUTION] +> **Caution** callouts communicate negative potential consequences of an action. + + +> [!IMPORTANT] +> **Important** callouts communicate information necessary for users to succeed. + + +> [!NOTE] +> **Note** callouts communicate information that users should take into account. + + +> [!TIP] +> **Tip** callouts communicate optional information to help a user be more successful. + + +> [!WARNING] +> **Warning** callouts communicate potential risks user should be aware of. + +**Nested** + + +> [!CAUTION] +> **Caution** callouts communicate negative potential consequences of an action. +> > [!IMPORTANT] +> > **Important** callouts communicate information necessary for users to succeed. +> > > [!NOTE] +> > > **Note** callouts communicate information that users should take into account. + +#### Legacy Docsify Style + !> **Important** callout with `inline code` and additional placeholder text used to force the content to wrap and span multiple lines. diff --git a/src/core/render/compiler.js b/src/core/render/compiler.js index d01e65aea..e35412541 100644 --- a/src/core/render/compiler.js +++ b/src/core/render/compiler.js @@ -13,6 +13,7 @@ import { import { imageCompiler } from './compiler/image.js'; import { highlightCodeCompiler } from './compiler/code.js'; import { paragraphCompiler } from './compiler/paragraph.js'; +import { blockquoteCompiler } from './compiler/blockquote.js'; import { taskListCompiler } from './compiler/taskList.js'; import { taskListItemCompiler } from './compiler/taskListItem.js'; import { linkCompiler } from './compiler/link.js'; @@ -232,6 +233,7 @@ export class Compiler { return `${str}`; }; + origin.blockquoteCompiler = blockquoteCompiler({ renderer }); origin.code = highlightCodeCompiler({ renderer }); origin.link = linkCompiler({ renderer, diff --git a/src/core/render/compiler/blockquote.js b/src/core/render/compiler/blockquote.js new file mode 100644 index 000000000..5f00951de --- /dev/null +++ b/src/core/render/compiler/blockquote.js @@ -0,0 +1,36 @@ +export const blockquoteCompiler = ({ renderer }) => + (renderer.blockquote = function ({ tokens }) { + const calloutData = + tokens[0].type === 'paragraph' && + // 0: Match "[!TIP] My Title" + // 1: Mark "[!TIP]" + // 2: Type "TIP" + tokens[0].raw.match(/^(\[!(\w+)\])/); + + let openTag = '
'; + let closeTag = '
'; + + if (calloutData) { + const calloutMark = calloutData[1]; // "[!TIP]" + const calloutType = calloutData[2].toLowerCase(); // "tip" + const token = tokens[0].tokens[0]; + + // Remove callout mark from tokens + ['raw', 'text'].forEach(key => { + token[key] = token[key].replace(calloutMark, '').trimStart(); + }); + + // Remove empty paragraph + if (tokens.length > 1 && !token.raw.trim()) { + tokens = tokens.slice(1); + } + + openTag = `
`; + closeTag = `
`; + } + + const body = this.parser.parse(tokens); + const html = `${openTag}${body}${closeTag}`; + + return html; + }); diff --git a/src/core/render/tpl.js b/src/core/render/tpl.js index 3cb990e95..8e0449e80 100644 --- a/src/core/render/tpl.js +++ b/src/core/render/tpl.js @@ -112,6 +112,9 @@ export function tree( return tpl.replace('{inner}', innerHTML); } +/** + * @deprecated + */ export function helper(className, content) { return /* html */ `

${content.slice(5).trim()}

`; } diff --git a/src/themes/addons/core-dark.css b/src/themes/addons/core-dark.css index 790b75cef..4f856b819 100644 --- a/src/themes/addons/core-dark.css +++ b/src/themes/addons/core-dark.css @@ -28,9 +28,46 @@ color-scheme: dark; } +/* Cover */ +/* ========================================================================== */ .cover-main { a.button.secondary { color: var(--color-text); border-color: rgba(255, 255, 255, 0.5); } } + +/* Markdown */ +/* ========================================================================== */ +.markdown-section { + .callout { + &[class] { + --callout-bg: unset; + } + + &.caution { + --callout-border-color: #991b1b; /* Tailwind: red 800 */ + } + + &.important { + --callout-border-color: #5b21b6; /* Tailwind: violet 800 */ + } + + &.note { + --callout-border-color: var(--theme-color-4); + } + + &.tip { + --callout-border-color: #115e59; /* Tailwind: teal 800 */ + } + + &.warning { + --callout-border-color: #a16207; /* Tailwind: yellow 700 */ + } + + code, + pre:where([data-lang]) { + background: var(--color-mono-min); + } + } +} diff --git a/src/themes/shared/_markdown.css b/src/themes/shared/_markdown.css index b328c001e..c62f8ea6c 100644 --- a/src/themes/shared/_markdown.css +++ b/src/themes/shared/_markdown.css @@ -126,13 +126,29 @@ text-align: center; } + > :first-child { + margin-top: 0; + } + + > :last-child { + margin-bottom: 0; + } + code, strong { color: inherit; } code { - background: rgba(0, 0, 0, 0.08); + background: rgba(0, 0, 0, 0.05); + } + + pre:where([data-lang]) { + background: rgba(255, 255, 255, 0.4); + } + + .callout { + margin-block: var(--margin-block); } } @@ -226,7 +242,7 @@ padding: 0 !important; padding-block: 1.5rem !important; padding-inline: 1.5rem !important; - background: inherit; + background: transparent; color: inherit; font-size: inherit; white-space: inherit; diff --git a/src/themes/shared/_vars.css b/src/themes/shared/_vars.css index 72ed013e4..ffb242265 100644 --- a/src/themes/shared/_vars.css +++ b/src/themes/shared/_vars.css @@ -81,20 +81,20 @@ --button-border-radius : 100vh; --button-color : #fff; --button-padding : 0.3em 1.25em 0.315em 1.25em; - --callout-bg : ; + --callout-bg : var(--color-mono-1); --callout-border-color : ; - --callout-border-radius : 0 var(--border-radius) var(--border-radius) 0; - --callout-border-width : 0 0 0 4px; + --callout-border-radius : var(--border-radius); + --callout-border-width : 1px; --callout-charm-bg : ; --callout-charm-border-radius : 100vh; - --callout-charm-color : ; - --callout-charm-content : ; - --callout-charm-font-size : 1.2em; - --callout-charm-inset : 50% auto auto -2px; - --callout-charm-size : 1.3em; - --callout-charm-translate : -50% -50%; + --callout-charm-color : #fff; + --callout-charm-content : ''; + --callout-charm-font-size : 16px; + --callout-charm-inset : 1em auto auto 15px; + --callout-charm-size : 26px; + --callout-charm-translate : 0; --callout-color : ; - --callout-padding : 1em 1em 1em var(--callout-charm-size); + --callout-padding : 1em 1em 1em calc(25px + var(--callout-charm-size)); --code-bg : var(--color-mono-1); --code-color : ; --codeblock-bg : var(--code-bg); @@ -181,22 +181,38 @@ /* Scoped Variables */ /* ========================================================================== */ -/* Callout: Important */ -.callout.important { - --callout-bg : var(--color-mono-1); - --callout-border-color : #f66; - --callout-charm-bg : var(--callout-border-color); - --callout-charm-color : #fff; - --callout-charm-content: '!'; - --callout-color : ; -} +.callout { + &.caution { + /* Tailwind: red 50/200/500 */ + --callout-bg : #fef2f2; + --callout-border-color: #fecaca; + --callout-charm-bg : #ef4444 center no-repeat url('data:image/svg+xml,'); + } + + &.important { + /* Tailwind: violet 50/200/500 */ + --callout-bg : #f5f3ff; + --callout-border-color: #ddd6fe; + --callout-charm-bg : #8b5cf6 center no-repeat url('data:image/svg+xml,'); + } + + &.note { + --callout-bg : var(--theme-color-1); + --callout-border-color: var(--theme-color-2); + --callout-charm-bg : var(--theme-color) center no-repeat url('data:image/svg+xml,'); + } -/* Callout: Important */ -.callout.tip { - --callout-bg : var(--theme-color-1); - --callout-border-color : var(--theme-color); - --callout-charm-bg : var(--callout-border-color); - --callout-charm-color : #fff; - --callout-charm-content: 'i'; - --callout-color : ; -} \ No newline at end of file + &.tip { + /* Tailwind: teal 50/200/500 */ + --callout-bg : #f0fdfa; + --callout-border-color: #99f6e4; + --callout-charm-bg : #14b8a6 center no-repeat url('data:image/svg+xml,'); + } + + &.warning { + /* Tailwind: amber 50/200/300 */ + --callout-bg : #fffbeb; + --callout-border-color: #fde68a; + --callout-charm-bg : #fcd34d center no-repeat url('data:image/svg+xml,'); + } +}