docsify extends Markdown syntax to make your documents more readable.
> [!] **Time** is money, my friend!
In Markdown
[!] Time is money, my friend!
In docsify

> [?] _TODO_ unit test
In Markdown
[?] _TODO_ unit test
In docsify

> [v] Good
> [x] Bad
> [detail] summary
> detail detail deatail
> xxxx
Friendly request for code support in <details> elements. :smile:
> [details] Sample Code
> ```javascript
> console.log('foo');
> ```
Three helper-related items worth mentioning:
Consider how generic markdown supports multiple paragraphs in a single blockquote:
> Paragraph 1
>
> Paragraph 2
HTML output:
<blockquote>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</blockquote>
Unfortunately, the existing "important content" and "general tips" do not support nested block-level elements properly:
?> Paragraph 1
?>
?> Paragraph 2
HTML output:
<p class="tip">Paragraph 1
!>
!> Paragraph 2</p>
The correct HTML output should be:
<div class="tip">
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</div>
Markdown is an environment-agnostic format. Markdown used with docsify will likely be viewed, edited, and previewed outside of docsify by site devs and content authors. Consideration should be given to the experience of working with docsify-specific markdown in these environments, not just how it will render in the final docsify site.
From the original markdown project page:
"Markdown is a text-to-HTML conversion tool for web writers. Markdown allows you to write using an easy-to-read, easy-to-write plain text format, then convert it to structurally valid XHTML (or HTML).”
"The overriding design goal for Markdown’s formatting syntax is to make it as readable as possible. The idea is that a Markdown-formatted document should be publishable as-is, as plain text, without looking like it’s been marked up with tags or formatting instructions."
Docsify helper syntax should be simple, consistent, and as unobtrusive as possible when authoring content and reading rendered content on a docsify site or any other environment (GitHub, code editor, markdown preview, etc).
For example, consider how the current v4 syntax for the "important content" and "general tip" helpers compares to the new v5 syntax proposed by @QingWei-Li:
Current v4 syntax rendered here on GitHub:
?> General Tip
!> Important Content
Proposed v5 syntax rendered here on GitHub:
[?] General Tip
[!] Important Content
The new format allows the "General Tip" and "Important Content" blocks to be visually distinct from the surrounding text content when rendered outside of docsify (like here on GitHub), and the text-as-icon indicators don't significantly impact readability. This is (IMHO) much better than the previous syntax, which to my eyes looked like broken or unprocessed markdown.
I mention this as good advise for helper-related v5 discussions in general, and because it relates directly to the next item...
Markdown's blockquote syntax is a convenient way to render container elements, but this syntax may not be the best mechanism for all helpers that require a container element. Specifically, some content (like the "Important content" and "General tip" blocks) look fine when rendered as blockquotes outside of docsify, but others do not.
For example, consider how a <details> helper that leverages markdown's blockquote syntax will render outside of a docsify site:
> [details ':open'] Summary / Title
>
> Some Text.
>
> ```javascript
> console.log('foo');
> ```
Rendered here on GitHub:
[details ':open'] Summary / Title
Some Text.
console.log('foo');
Yeesh. Not good.
I wrestled with this same issue while developing docsify-tabs: how can I indicate tab titles and their associated content in markdown without adding a non-standard, docsify-specific syntax that will look terrible when rendered outside of docsify?
The solution I came up with was to use HTML comments (which are valid markdown and properly hidden when markdown is rendered) to serve as the start and end of a container, then use standard markdown elements (like headings) to serve special purposes when placed between those comments.
Here is the example provided in the Usage section of the docs:
<!-- tabs:start -->
#### **English**
Hello!
#### **French**
Bonjour!
#### **Italian**
Ciao!
<!-- tabs:end -->
Rendered as HTML by docsify-tabs:

Rendered as markdown here on GitHub:
Hello!
Bonjour!
Ciao!
Perfect. No docsify-specific markdown for formatting visible when rendered outside of docsify. This same approach could be used for a <details> helper as well:
````markdown
Some Text.
console.log('foo');
````
Rendered as HTML:
Some Text.
Summary / Title
console.log('foo');
Rendered as markdown here on GitHub:
Some Text.
console.log('foo');
With this format, the opening comment can be used to set options using HTML-like attributes that docsify can detect but other markdown parsers (like GitHub) will ignore. For example, this could allow setting the open attribute on a <details> element:
<!-- details:start open -->
For other helper elements, it could allow specifying both standard HTML attributes (id, class, style, etc.) or helper-specific attributes:
<!-- helper:start id="my-id" class="my-class" style="background: red;" helper-specific="abc123" -->
Hope this was helpful, and apologies for the lengthy post. Just wanted to get these three topic covered in one place.
Thanks!
After reviewing #1166 I've come to realize that there are three types of comment-based helpers that should be accounted for:
Helpers with block content that should render in all environments (e.g. <details></details>). These helpers need a start/end indicator for efficient parsing. The content between the start/end comments will be uniquely rendered by docsify while rendered as standard markdown by other processors.
<!-- details:start -->
#### Heading
Text
<!-- details:end -->
<!-- tabs:start -->
#### **English**
Hello!
#### **French**
Bonjour!
#### **Italian**
Ciao!
<!-- tabs:end -->
Helpers with block content that should be processed by docsify and ignored in other environments (e.g. <script></script>)
<!-- :script:
console.log('foo')
-->
Helpers with attributes that should be processed by docsify and ignored in other environments (e.g. <script src="...">)
<!-- :embed: src="path/to/file.md"-->
<!-- :script: src="path/to/file.js"-->
<!-- :video: src="path/to/file.mp4"-->
The examples above use colons to indicate the helper name, but brackets (as suggested in #830) could be used as well:
<!-- [details:start] -->
#### Heading
Text
<!-- [details:end] -->
<!-- [tabs:start] -->
#### **English**
Hello!
#### **French**
Bonjour!
#### **Italian**
Ciao!
<!-- [tabs:end] -->
<!-- [script]
console.log('foo')
-->
<!-- [embed] src="path/to/file.md"-->
<!-- [script] src="path/to/file.js"-->
<!-- [video] src="path/to/file.mp4"-->
thanks for the input.
I liked the tab and the script thing. can you explain about the detail. is it similar to collapsable in markdowns ? perhaps how it would render will help to understand 👍
The details helper is covered here (near the end of the comment): https://github.com/docsifyjs/docsify/issues/413#issuecomment-609085729
I don’t believe there is a native “collapsible” element in markdown. Currently if you want to add a collapsable element in markdown, you do it with HTML.
The details helper is covered here (near the end of the comment): #413 (comment)
cool i will check
I don’t believe there is a native “collapsible” element in markdown. Currently if you want to add a collapsable element in markdown, you do it with HTML.
yes, I meant using the details and summary tag
like this
<details>
<summary>Click to expand!</summary>
## Heading
</details>
More thoughts...
A major advantage to standardizing "helper" syntax is that docsify can handle parsing the markdown and provide access to the helper data via the plugin system. This would greatly simplify plugin creation, improve plugin reliability, and improve site performance by reducing the amount of code downloaded and executed.
For example, consider the code necessary to process the three different kinds of helpers described in my comment above:
Helpers with block content that should render in all environments (e.g. <details></details>):
<!-- details:start class="myclass" -->
#### Heading
Text
<!-- details:end -->
Helpers with block content that should be processed by docsify and ignored in other environments (e.g. a <video> helper):
<!-- :video: src="https://www.youtube.com/watch?v=abc123"-->
Helpers with attributes that should be processed by docsify and ignored in other environments (e.g. <script src="...">):
<!-- :script:
console.log('foo')
-->
Today, all three of these helpers would be handled separately. If these were third-party plugins, each plugin would include similar logic for parsing markdown, processing output, and injecting final content back into the markdown content. This would be done either by modifying the markdown renderer object or using the beforeEach() method of the plugin system:
// Modify markdown renderer
hook.init(function() {
// Do stuff with $docsify.markdown.renderer...
});
// Modify markdown content
hook.beforeEach(function(markdown) {
// Do stuff...
return markdown;
});
With the helper syntax standardized, docsify can generate an object containing all relevant data...
{
details: [
{
at: [100, 140],
attrs: {
class: 'myclass'
},
content: '#### Heading\n Text',
raw: '<!-- details:start class="myclass" -->\n#### Heading\nText\n<!-- details:end -->'
}
],
video: [
{
at: [250, 275],
attrs: {
src: 'https://www.youtube.com/watch?v=abc123'
},
raw: '<!-- :video: src="https://www.youtube.com/watch?v=abc123" -->'
}
],
script: [
{
at: [310, 328],
content: '#### Heading\n Text',
raw: '<!-- :script:\n console.log('foo')\n-->'
}
]
}
... and pass it to either the beforeEach() method:
hook.beforeEach(function(markdown, helperData) {
// ...
return markdown;
});
... or even better, offer a new method that is called once for each block of helper content. Here's how a <details> plugin author might use this new method:
hook.handleHelpers(function(helperType, helperData) {
if (helperType === 'details') {
return `
<details class="${helperData.attrs.class}">
${helperData.content}
</details>
`;
}
});
Most helpful comment
Three helper-related items worth mentioning:
1. Blockquote helpers should support nested block-level elements
Consider how generic markdown supports multiple paragraphs in a single blockquote:
HTML output:
Unfortunately, the existing "important content" and "general tips" do not support nested block-level elements properly:
HTML output:
The correct HTML output should be:
2. Docsify-specific markdown
Markdown is an environment-agnostic format. Markdown used with docsify will likely be viewed, edited, and previewed outside of docsify by site devs and content authors. Consideration should be given to the experience of working with docsify-specific markdown in these environments, not just how it will render in the final docsify site.
From the original markdown project page:
Docsify helper syntax should be simple, consistent, and as unobtrusive as possible when authoring content and reading rendered content on a docsify site or any other environment (GitHub, code editor, markdown preview, etc).
For example, consider how the current v4 syntax for the "important content" and "general tip" helpers compares to the new v5 syntax proposed by @QingWei-Li:
Current v4 syntax rendered here on GitHub:
?> General Tip
!> Important Content
Proposed v5 syntax rendered here on GitHub:
The new format allows the "General Tip" and "Important Content" blocks to be visually distinct from the surrounding text content when rendered outside of docsify (like here on GitHub), and the text-as-icon indicators don't significantly impact readability. This is (IMHO) much better than the previous syntax, which to my eyes looked like broken or unprocessed markdown.
I mention this as good advise for helper-related v5 discussions in general, and because it relates directly to the next item...
3. Blockquotes-as-containers vs. alternate approaches
Markdown's blockquote syntax is a convenient way to render container elements, but this syntax may not be the best mechanism for all helpers that require a container element. Specifically, some content (like the "Important content" and "General tip" blocks) look fine when rendered as blockquotes outside of docsify, but others do not.
For example, consider how a
<details>helper that leverages markdown's blockquote syntax will render outside of a docsify site:Rendered here on GitHub:
Yeesh. Not good.
I wrestled with this same issue while developing docsify-tabs: how can I indicate tab titles and their associated content in markdown without adding a non-standard, docsify-specific syntax that will look terrible when rendered outside of docsify?
The solution I came up with was to use HTML comments (which are valid markdown and properly hidden when markdown is rendered) to serve as the start and end of a container, then use standard markdown elements (like headings) to serve special purposes when placed between those comments.
Here is the example provided in the Usage section of the docs:
Rendered as HTML by docsify-tabs:
Rendered as markdown here on GitHub:
English
Hello!
French
Bonjour!
Italian
Ciao!
Perfect. No docsify-specific markdown for formatting visible when rendered outside of docsify. This same approach could be used for a
<details>helper as well:````markdown
Summary / Title
Some Text.
````
Rendered as HTML:
Summary / Title
Some Text.
Rendered as markdown here on GitHub:
Summary / Title
Some Text.
With this format, the opening comment can be used to set options using HTML-like attributes that docsify can detect but other markdown parsers (like GitHub) will ignore. For example, this could allow setting the
openattribute on a<details>element:For other helper elements, it could allow specifying both standard HTML attributes (id, class, style, etc.) or helper-specific attributes:
Hope this was helpful, and apologies for the lengthy post. Just wanted to get these three topic covered in one place.
Thanks!