feat: GitHub style callouts (#2487)

Co-authored-by: Koy Zhuang <koy@ko8e24.top>
Co-authored-by: Luffy <52o@qq52o.cn>
This commit is contained in:
John Hildenbiddle 2025-08-31 23:53:59 -05:00 committed by GitHub
parent 9bc58c9ca2
commit 2e59b0f50c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 324 additions and 96 deletions

View File

@ -75,7 +75,6 @@ function writeEmojiJS(emojiData) {
const isExistingPage = fs.existsSync(filePaths.emojiJS);
const emojiJS = isExistingPage && fs.readFileSync(filePaths.emojiJS, 'utf8');
const newEmojiJS = [
'/* eslint-disable */\n',
'// =============================================================================',
'// DO NOT EDIT: This file is auto-generated by an /build/emoji.js',
'// =============================================================================\n',

View File

@ -67,7 +67,7 @@ To create section headers:
You need to create a `.nojekyll` in `./docs` to prevent GitHub Pages from ignoring files that begin with an underscore.
!> Docsify only looks for `_sidebar.md` in the current folder, and uses that, otherwise it falls back to the one configured using `window.$docsify.loadSidebar` config.
> [!IMPORTANT] Docsify only looks for `_sidebar.md` in the current folder, and uses that, otherwise it falls back to the one configured using `window.$docsify.loadSidebar` config.
Example file structure:
@ -98,7 +98,7 @@ You can specify `alias` to avoid unnecessary fallback.
</script>
```
!> You can create a `README.md` file in a subdirectory to use it as the landing page for the route.
> [!IMPORTANT] You can create a `README.md` file in a subdirectory to use it as the landing page for the route.
## Set Page Titles from Sidebar Selection

View File

@ -29,7 +29,7 @@ Uncompressed resources are available by omitting the `.min` from the filename.
Specifying the latest major version allows your site to receive all non-breaking enhancements ("minor" updates) and bug fixes ("patch" updates) as they are released. This is good option for those who prefer a zero-maintenance way of keeping their site up to date with minimal risk as new versions are published.
?> When a new major version is released, you will need to manually update the major version number after the `@` symbol in your CDN URLs.
> [!TIP] When a new major version is released, you will need to manually update the major version number after the `@` symbol in your CDN URLs.
<!-- prettier-ignore -->
```html
@ -44,7 +44,7 @@ Specifying the latest major version allows your site to receive all non-breaking
Specifying an exact version prevents any future updates from affecting your site. This is good option for those who prefer to manually update their resources as new versions are published.
?> When a new version is released, you will need to manually update the version number after the `@` symbol in your CDN URLs.
> [!TIP] When a new version is released, you will need to manually update the version number after the `@` symbol in your CDN URLs.
<!-- prettier-ignore -->
```html

View File

@ -303,7 +303,7 @@ Key `bindings` are defined as case insensitive string values separated by `+`. M
The `callback` function receive a [keydown event](https://developer.mozilla.org/en-US/docs/Web/API/Element/keydown_event) as an argument.
!> Let site visitors know your custom key bindings are available! If a binding is associated with a DOM element, consider inserting a `<kbd>` element as a visual cue (e.g., <kbd>alt</kbd> + <kbd>a</kbd>) or adding [title](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title) and [aria-keyshortcuts](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-keyshortcuts) attributes for hover/focus hints.
> [!IMPORTANT] Let site visitors know your custom key bindings are available! If a binding is associated with a DOM element, consider inserting a `<kbd>` element as a visual cue (e.g., <kbd>alt</kbd> + <kbd>a</kbd>) or adding [title](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/title) and [aria-keyshortcuts](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-keyshortcuts) attributes for hover/focus hints.
```js
window.$docsify = {
@ -378,7 +378,7 @@ window.$docsify = {
Website logo as it appears in the sidebar. You can resize it using CSS.
!> Logo will only be visible if `name` prop is also set. See [name](#name) configuration.
> [!IMPORTANT] Logo will only be visible if `name` prop is also set. See [name](#name) configuration.
```js
window.$docsify = {
@ -921,7 +921,7 @@ For more details, see [#1131](https://github.com/docsifyjs/docsify/issues/1131).
## themeColor ⚠️ :id=themecolor
!> Deprecated as of v5. Use the `--theme-color` [theme property](themes#theme-properties) to [customize](themes#customization) your theme color.
> [!IMPORTANT] Deprecated as of v5. Use the `--theme-color` [theme property](themes#theme-properties) to [customize](themes#customization) your theme color.
- Type: `String`
@ -935,7 +935,7 @@ window.$docsify = {
## topMargin ⚠️ :id=topmargin
!> Deprecated as of v5. Use the `--scroll-padding-top` [theme property](themes#theme-properties) to specify a scroll margin when using a sticky navbar.
> [!IMPORTANT] Deprecated as of v5. Use the `--scroll-padding-top` [theme property](themes#theme-properties) to specify a scroll margin when using a sticky navbar.
- Type: `Number|String`
- Default: `0`

View File

@ -4,7 +4,7 @@
If you need custom navigation, you can create a HTML-based navigation bar.
!> Note that documentation links begin with `#/`.
> [!IMPORTANT] Note that documentation links begin with `#/`.
```html
<!-- index.html -->
@ -51,7 +51,7 @@ To create drop-down menus:
- [chinese](/zh-cn/)
```
!> You need to create a `.nojekyll` in `./docs` to prevent GitHub Pages from ignoring files that begin with an underscore.
> [!IMPORTANT] You need to create a `.nojekyll` in `./docs` to prevent GitHub Pages from ignoring files that begin with an underscore.
`_navbar.md` is loaded from each level directory. If the current directory doesn't have `_navbar.md`, it will fall back to the parent directory. If, for example, the current path is `/guide/quick-start`, the `_navbar.md` will be loaded from `/guide/_navbar.md`.

View File

@ -14,14 +14,14 @@ It is recommended that you save your files to the `./docs` subfolder of the `mai
![GitHub Pages](_images/deploy-github-pages.png)
!> You can also save files in the root directory and select `main branch`.
You'll need to place a `.nojekyll` file in the deploy location (such as `/docs` or the gh-pages branch)
> [!IMPORTANT] You can also save files in the root directory and select `main branch`.
> You'll need to place a `.nojekyll` file in the deploy location (such as `/docs` or the gh-pages branch)
## GitLab Pages
If you are deploying your master branch, create a `.gitlab-ci.yml` with the following script:
?> The `.public` workaround is so `cp` doesn't also copy `public/` to itself in an infinite loop.
> [!TIP] The `.public` workaround is so `cp` doesn't also copy `public/` to itself in an infinite loop.
```YAML
pages:
@ -37,11 +37,11 @@ pages:
- master
```
!> You can replace script with `- cp -r docs/. public`, if `./docs` is your Docsify subfolder.
> [!IMPORTANT] You can replace script with `- cp -r docs/. public`, if `./docs` is your Docsify subfolder.
## Firebase Hosting
!> You'll need to install the Firebase CLI using `npm i -g firebase-tools` after signing into the [Firebase Console](https://console.firebase.google.com) using a Google Account.
> [!IMPORTANT] You'll need to install the Firebase CLI using `npm i -g firebase-tools` after signing into the [Firebase Console](https://console.firebase.google.com) using a Google Account.
Using a terminal, determine and navigate to the directory for your Firebase Project. This could be `~/Projects/Docs`, etc. From there, run `firebase init` and choose `Hosting` from the menu (use **space** to select, **arrow keys** to change options and **enter** to confirm). Follow the setup instructions.

View File

@ -75,7 +75,7 @@ Example:
If you embed the file as `iframe`, `audio` and `video`, then you may need to set the attributes of these tags.
?> Note, for the `audio` and `video` types, docsify adds the `controls` attribute by default. When you want add more attributes, the `controls` attribute need to be added manually if need be.
> [!TIP] Note, for the `audio` and `video` types, docsify adds the `controls` attribute by default. When you want add more attributes, the `controls` attribute need to be added manually if need be.
```md
[filename](_media/example.mp4 ':include :type=video controls width=100%')
@ -101,13 +101,13 @@ Embedding any type of source code file, you can specify the highlighted language
[](_media/example.html ':include :type=code text')
?> How to set highlight? You can see [here](language-highlight.md).
> [!TIP] How to set highlight? You can see [here](language-highlight.md).
## Embed a gist
You can embed a gist as markdown content or as a code block - this is based on the approach at the start of [Embed Files](#embed-files) section, but uses a raw gist URL as the target.
?> **No** plugin or app config change is needed here to make this work. In fact, the "Embed" `script` tag that is copied from a gist will _not_ load even if you make plugin or config changes to allow an external script.
> [!TIP] **No** plugin or app config change is needed here to make this work. In fact, the "Embed" `script` tag that is copied from a gist will _not_ load even if you make plugin or config changes to allow an external script.
### Identify the gist's metadata
@ -132,7 +132,7 @@ Here are two examples based on the sample gist:
- https://gist.githubusercontent.com/anikethsaha/f88893bb563bb7229d6e575db53a8c15/raw/content.md
- https://gist.githubusercontent.com/anikethsaha/f88893bb563bb7229d6e575db53a8c15/raw/script.js
?> Alternatively, you can get a raw URL directly clicking the _Raw_ button on a gist file. But, if you use that approach, just be sure to **remove** the revision number between `raw/` and the filename so that the URL matches the pattern above instead. Otherwise your embedded gist will **not** show the latest content when the gist is updated.
> [!TIP] Alternatively, you can get a raw URL directly clicking the _Raw_ button on a gist file. But, if you use that approach, just be sure to **remove** the revision number between `raw/` and the filename so that the URL matches the pattern above instead. Otherwise your embedded gist will **not** show the latest content when the gist is updated.
Continue with one of the sections below to embed the gist on a Docsify page.

View File

@ -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:
<!-- prettier-ignore -->
> [!CAUTION]
> **Caution** callouts communicate negative potential consequences of an action.
<!-- prettier-ignore -->
> [!IMPORTANT]
> **Important** callouts communicate information necessary for users to succeed.
<!-- prettier-ignore -->
> [!NOTE]
> **Note** callouts communicate information that users should take into account.
<!-- prettier-ignore -->
> [!TIP]
> **Tip** callouts communicate optional information to help a user be more successful.
<!-- prettier-ignore -->
> [!WARNING]
> **Warning** callouts communicate potential risks user should be aware of.
**Markdown**
<!-- prettier-ignore -->
```markdown
!> **Time** is money, my friend!
> [!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.
```
is rendered as:
### Legacy Style ⚠️
!> **Time** is money, my friend!
The following Docsify v4 callout syntax has been deprecated and will be removed in a future version.
### Tips
!> Legacy **Important** callouts are deprecated.
General tips like:
?> Legacy **Tip** callouts are deprecated.
**Markdown**
```markdown
?> _TODO_ unit test
!> Legacy **Important** callouts are deprecated.
?> Legacy **Tip** callouts are deprecated.
```
are rendered as:
?> _TODO_ unit test
## 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 `<a href="/#/demo/">link</a>` and will load `/demo/README
Now you can do that
```md
```markdown
[link](/demo/ ':ignore')
```
You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set the title for the link.
```md
```markdown
[link](/demo/ ':ignore title')
<a href="/demo/" title="title">link</a>
@ -64,14 +98,14 @@ You will get `<a href="/demo/">link</a>`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,7 +125,7 @@ You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set th
### Class names
```md
```markdown
![logo](https://docsify.js.org/_media/icon.svg ':class=someCssClass')
<!-- Multiple class names -->
@ -101,13 +135,13 @@ You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set th
### 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')
@ -123,7 +157,7 @@ You will get `<a href="/demo/">link</a>`html. Do not worry, you can still set th
## Heading IDs
```md
```markdown
### Hello, world! :id=hello-world
```

View File

@ -47,6 +47,12 @@
disabled
/>
<!-- Prism Theme -->
<!-- <link
rel="stylesheet"
href="//cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-twilight.min.css"
/> -->
<!-- Site styles -->
<style>
/* Plugin: Carbon Ads */

View File

@ -57,7 +57,7 @@ function add(a, b) {
Support for additional [languages](https://prismjs.com/#supported-languages) is available by loading the Prism [grammar files](https://cdn.jsdelivr.net/npm/prismjs@1/components/):
!> Prism grammar files must be loaded after Docsify.
> [!IMPORTANT] Prism grammar files must be loaded after Docsify.
```html
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
@ -79,7 +79,7 @@ Support for additional [languages](https://prismjs.com/#supported-languages) is
Docsify's official [themes](themes) are compatible with Prism syntax highlighting themes.
!> Prism themes must be loaded after Docsify themes.
> [!IMPORTANT] Prism themes must be loaded after Docsify themes.
```html
<!-- Light and dark mode -->

View File

@ -15,7 +15,7 @@ window.$docsify = {
};
```
?> Configuration Options Reference: [marked documentation](https://marked.js.org/#/USING_ADVANCED.md)
> [!TIP] Configuration Options Reference: [marked documentation](https://marked.js.org/#/USING_ADVANCED.md)
You can completely customize the parsing rules.
@ -31,7 +31,7 @@ window.$docsify = {
## Supports mermaid
!> Currently, docsify doesn't support the async mermaid render (the latest mermaid version supported is `v9.3.0`).
> [!IMPORTANT] Currently, docsify doesn't support the async mermaid render (the latest mermaid version supported is `v9.3.0`).
```js
// <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.css">

View File

@ -123,7 +123,7 @@ Install the plugin and configure the track id.
Renders a larger collection of emoji shorthand codes. Without this plugin, Docsify is able to render only a limited number of emoji shorthand codes.
!> Deprecated as of v4.13. Docsify no longer requires this plugin for full emoji support.
> [!IMPORTANT] Deprecated as of v4.13. Docsify no longer requires this plugin for full emoji support.
```html
<script src="//cdn.jsdelivr.net/npm/docsify@5/dist/plugins/emoji.min.js"></script>

View File

@ -32,7 +32,7 @@ Run the local server with `docsify serve`. You can preview your site in your bro
docsify serve docs
```
?> For more use cases of `docsify-cli`, head over to the [docsify-cli documentation](https://github.com/docsifyjs/docsify-cli).
> [!TIP] For more use cases of `docsify-cli`, head over to the [docsify-cli documentation](https://github.com/docsifyjs/docsify-cli).
## Manual initialization
@ -76,7 +76,7 @@ Download or create an `index.html` template using the following markup:
### Specifying docsify versions
?> Note that in both of the examples below, docsify URLs will need to be manually updated when a new major version of docsify is released (e.g. `v5.x.x` => `v6.x.x`). Check the docsify website periodically to see if a new major version has been released.
> [!TIP] Note that in both of the examples below, docsify URLs will need to be manually updated when a new major version of docsify is released (e.g. `v5.x.x` => `v6.x.x`). Check the docsify website periodically to see if a new major version has been released.
Specifying a major version in the URL (`@5`) will allow your site to receive non-breaking enhancements (i.e. "minor" updates) and bug fixes (i.e. "patch" updates) automatically. This is the recommended way to load docsify resources.

View File

@ -14,7 +14,7 @@ The Docsify "core" theme contains all of the styles and [theme properties](#them
Theme add-ons are used in combination with the [core theme](#core-theme). Add-ons contain CSS rules that modify [theme properties](#theme-properties) values and/or add custom style declarations. They can often (but not always) be used with other add-ons.
!> Theme add-ons must be loaded after the [core theme](#core-theme).
> [!IMPORTANT] Theme add-ons must be loaded after the [core theme](#core-theme).
<!-- prettier-ignore -->
```html
@ -288,7 +288,7 @@ Docsify provides [theme properties](#theme-properties) for simplified customizat
}
```
?> **Theme authors**: Consider providing instructions for loading your recommended web fonts manually instead of including them in your theme using `@import`. This allows users who prefer a different font to avoid loading your recommended web font(s) unnecessarily.
?> **Theme authors**: Consider providing instructions for loading your recommended web fonts manually instead of including them in your theme using `@import`. This allows users who prefer a different font to avoid loading your recommended web font(s) unnecessarily.
4. Advanced styling may require custom CSS declarations. This is expected, however custom CSS declarations may break when new versions of Docsify are released. When possible, leverage [theme properties](#theme-properties) instead of custom declarations or lock your [CDN](cdn) URLs to a [specific version](cdn#specific-version) to avoid potential issues when using custom CSS declarations.
@ -302,7 +302,7 @@ Docsify provides [theme properties](#theme-properties) for simplified customizat
The following properties are available in all official Docsify themes. Default values for the "Core" theme are shown.
?> **Theme and plugin authors**: We encourage you to leverage these custom theme properties and to offer similar customization options in your projects.
> [!TIP] **Theme and plugin authors**: We encourage you to leverage these custom theme properties and to offer similar customization options in your projects.
### Common

View File

@ -53,11 +53,54 @@
## Callouts
!> **Important** callout with `inline code` and additional placeholder text used
to force the content to wrap and span multiple lines.
<!-- prettier-ignore -->
> [!CAUTION]
> **Caution** callout with `inline code`.
?> **Tip** callout with `inline code` and additional placeholder text used to
force the content to wrap and span multiple lines.
<!-- prettier-ignore -->
> [!IMPORTANT]
> **Important** callout with `inline code`.
<!-- prettier-ignore -->
> [!NOTE]
> **Note** callout with `inline code`.
<!-- prettier-ignore -->
> [!TIP]
> **Tip** callout with `inline code`.
<!-- prettier-ignore -->
> [!WARNING]
> **Warning** callout with `inline code`.
**Multi Line**
<!-- prettier-ignore -->
> [!NOTE]
> - List item 1
> - List item 2
>
> Text
>
> ```html
> <p>Hello, World!</p>
> ```
**Nested**
<!-- prettier-ignore -->
> [!NOTE]
> Level 1
> > [!NOTE]
> > Level 2
> > > [!NOTE]
> > > Level 3
**Legacy Style**
!> Legacy **Important** callout with `inline code`.
?> Legacy **Tip** with `inline code`.
## Code

View File

@ -311,7 +311,7 @@ window.$docsify = {
Vue content can mounted using a `<script>` tag in your markdown pages.
!> Only the first `<script>` tag in a markdown file is executed. If you wish to mount multiple Vue instances using a script tag, all instances must be mounted within the first script tag in your markdown.
> [!IMPORTANT] Only the first `<script>` tag in a markdown file is executed. If you wish to mount multiple Vue instances using a script tag, all instances must be mounted within the first script tag in your markdown.
```html
<script>

View File

@ -10,6 +10,7 @@ import { imageCompiler } from './compiler/image.js';
import { headingCompiler } from './compiler/heading.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';
@ -156,12 +157,13 @@ export class Compiler {
// Supports mermaid
const origin = {};
// renderer customizers
// Renderer customizers
origin.heading = headingCompiler({
renderer,
router,
compiler: this,
});
origin.blockquoteCompiler = blockquoteCompiler({ renderer });
origin.code = highlightCodeCompiler({ renderer });
origin.link = linkCompiler({
renderer,

View File

@ -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 = '<blockquote>';
let closeTag = '</blockquote>';
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 = `<div class="callout ${calloutType}">`;
closeTag = `</div>`;
}
const body = this.parser.parse(tokens);
const html = `${openTag}${body}${closeTag}`;
return html;
});

View File

@ -1,5 +1,3 @@
/* eslint-disable */
// =============================================================================
// DO NOT EDIT: This file is auto-generated by an /build/emoji.js
// =============================================================================

View File

@ -112,6 +112,9 @@ export function tree(
return tpl.replace('{inner}', innerHTML);
}
/**
* @deprecated
*/
export function helper(className, content) {
return /* html */ `<p class="${className}">${content.slice(5).trim()}</p>`;
}

View File

@ -28,6 +28,8 @@
color-scheme: dark;
}
/* Cover */
/* ========================================================================== */
.cover-main {
a.button.secondary {
color: var(--color-text);
@ -35,6 +37,41 @@
}
}
/* 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);
}
}
}
/* Force light mode for iframes in dark theme */
iframe,
iframe *,

View File

@ -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;

View File

@ -81,21 +81,21 @@
--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);
--code-bg : var(--color-mono-2);
--callout-padding : 1em 1em 1em calc(25px + var(--callout-charm-size));
--code-bg : var(--color-mono-1);
--code-color : ;
--codeblock-bg : var(--code-bg);
--codeblock-color : var(--code-color);
@ -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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="13" height="13" fill="white"><path d="M10 14C10 15.1 9.1 16 8 16 6.9 16 6 15.1 6 14 6 12.9 6.9 12 8 12 9.1 12 10 12.9 10 14Z"/><path d="M10 1.6C10 1.2 9.8 0.9 9.6 0.7 9.2 0.3 8.6 0 8 0 7.4 0 6.8 0.2 6.5 0.6 6.2 0.9 6 1.2 6 1.6 6 1.7 6 1.8 6 1.9L6.8 9.6C6.9 9.9 7 10.1 7.2 10.2 7.4 10.4 7.7 10.5 8 10.5 8.3 10.5 8.6 10.4 8.8 10.3 9 10.1 9.1 9.9 9.2 9.6L10 1.9C10 1.8 10 1.7 10 1.6Z"/></svg>');
}
/* 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 : ;
&.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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="white"><path d="M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z"></path></svg>');
}
&.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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="14" height="14" fill="white"><path d="M9.1 0C10.2 0 10.7 0.7 10.7 1.6 10.7 2.6 9.8 3.6 8.6 3.6 7.6 3.6 7 3 7 2 7 1.1 7.7 0 9.1 0Z"/><path d="M5.8 16C5 16 4.4 15.5 5 13.2L5.9 9.1C6.1 8.5 6.1 8.2 5.9 8.2 5.7 8.2 4.6 8.6 3.9 9.1L3.5 8.4C5.6 6.6 7.9 5.6 8.9 5.6 9.8 5.6 9.9 6.6 9.5 8.2L8.4 12.5C8.2 13.2 8.3 13.5 8.5 13.5 8.7 13.5 9.6 13.2 10.4 12.5L10.9 13.2C8.9 15.2 6.7 16 5.8 16Z"/></svg>');
}
&.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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="14" height="14" fill="white"><path d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z"></path></svg>');
}
&.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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="13" height="13" fill="#a16207"><path d="M10 14C10 15.1 9.1 16 8 16 6.9 16 6 15.1 6 14 6 12.9 6.9 12 8 12 9.1 12 10 12.9 10 14Z"/><path d="M10 1.6C10 1.2 9.8 0.9 9.6 0.7 9.2 0.3 8.6 0 8 0 7.4 0 6.8 0.2 6.5 0.6 6.2 0.9 6 1.2 6 1.6 6 1.7 6 1.8 6 1.9L6.8 9.6C6.9 9.9 7 10.1 7.2 10.2 7.4 10.4 7.7 10.5 8 10.5 8.3 10.5 8.6 10.4 8.8 10.3 9 10.1 9.1 9.9 9.2 9.6L10 1.9C10 1.8 10 1.7 10 1.6Z"/></svg>');
}
}

View File

@ -5,9 +5,7 @@ exports[`Docs Site coverpage renders and is unchanged 1`] = `
<div class="mask"></div>
<div class="cover-main"><!-- markdownlint-disable first-line-h1 -->
<p><img src="http://127.0.0.1:4000/_media/icon.svg" data-origin="_media/icon.svg" alt="logo"></p><h1 id="docsify" tabindex="-1"><a href="#/?id=docsify" data-id="docsify" class="anchor"><span>docsify <small>5.0.0-rc.1</small></span></a></h1><blockquote>
<p>A magical documentation site generator</p></blockquote>
<ul><li>Simple and lightweight</li><li>No statically built HTML files</li><li>Multiple themes</li></ul><p><a href="#/?id=docsify" class="button primary">Get Started</a>
<p><img src="http://127.0.0.1:4000/_media/icon.svg" data-origin="_media/icon.svg" alt="logo"></p><h1 id="docsify" tabindex="-1"><a href="#/?id=docsify" data-id="docsify" class="anchor"><span>docsify <small>5.0.0-rc.1</small></span></a></h1><blockquote><p>A magical documentation site generator</p></blockquote><ul><li>Simple and lightweight</li><li>No statically built HTML files</li><li>Multiple themes</li></ul><p><a href="#/?id=docsify" class="button primary">Get Started</a>
<a href="https://github.com/docsifyjs/docsify/" target="_blank" rel="noopener" class="button secondary">GitHub</a></p><!-- ![color](#f0f0f0) -->
<!-- ![](/_media/icon.svg) -->
</div>

View File

@ -7,12 +7,52 @@ import { waitForText } from '../helpers/wait-for.js';
describe('render', function () {
// Helpers
// ---------------------------------------------------------------------------
describe('helpers', () => {
describe('callouts', () => {
beforeEach(async () => {
await docsifyInit();
});
test('important content', () => {
test('caution', () => {
const output = window.marked('> [!CAUTION]\n> Text');
expect(output).toMatchInlineSnapshot(
`"<div class="callout caution"><p>Text</p></div>"`,
);
});
test('important', () => {
const output = window.marked('> [!IMPORTANT]\n> Text');
expect(output).toMatchInlineSnapshot(
`"<div class="callout important"><p>Text</p></div>"`,
);
});
test('note', () => {
const output = window.marked('> [!NOTE]\n> Text');
expect(output).toMatchInlineSnapshot(
`"<div class="callout note"><p>Text</p></div>"`,
);
});
test('tip', () => {
const output = window.marked('> [!TIP]\n> Text');
expect(output).toMatchInlineSnapshot(
`"<div class="callout tip"><p>Text</p></div>"`,
);
});
test('warning', () => {
const output = window.marked('> [!WARNING]\n> Text');
expect(output).toMatchInlineSnapshot(
`"<div class="callout warning"><p>Text</p></div>"`,
);
});
test('important (legacy)', () => {
const output = window.marked('!> Important content');
expect(output).toMatchInlineSnapshot(
@ -20,7 +60,7 @@ describe('render', function () {
);
});
test('general tip', () => {
test('tip (legacy)', () => {
const output = window.marked('?> General tip');
expect(output).toMatchInlineSnapshot(