Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Friendly doc Helpers #413

Open
QingWei-Li opened this issue Mar 6, 2018 · 7 comments
Open

Friendly doc Helpers #413

QingWei-Li opened this issue Mar 6, 2018 · 7 comments
Labels
enhancement pr welcome ready to implement ui/ux related to user interface and/or user experience of docsify
Milestone

Comments

@QingWei-Li
Copy link
Member

QingWei-Li commented Mar 6, 2018

status PR


docsify extends Markdown syntax to make your documents more readable.

> [!] **Time** is money, my friend!

In Markdown

[!] Time is money, my friend!

In docsify

image


> [?] _TODO_ unit test

In Markdown

[?] TODO unit test

In docsify

image


New helpers

> [v] Good
> [x] Bad
> [detail] summary
> detail detail deatail
> xxxx
@QingWei-Li QingWei-Li added this to the 4.7.0 milestone Mar 6, 2018
@jhildenbiddle
Copy link
Member

Friendly request for code support in <details> elements. 😄

> [details] Sample Code
> ```javascript
> console.log('foo');
> ```

@QingWei-Li QingWei-Li removed this from the 4.7.0 milestone Jun 29, 2018
@QingWei-Li QingWei-Li mentioned this issue Oct 28, 2018
5 tasks
@QingWei-Li QingWei-Li mentioned this issue Mar 31, 2019
3 tasks
@anikethsaha anikethsaha pinned this issue Jan 30, 2020
@anikethsaha anikethsaha unpinned this issue Feb 11, 2020
@jhildenbiddle
Copy link
Member

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:

> 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
!&gt;
!&gt; Paragraph 2</p>

The correct HTML output should be:

<div class="tip">
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</div>

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:

"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...

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:

> [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:

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:

<!-- details:start -->

#### Summary / Title

Some Text.

```javascript
console.log('foo');
```

<!-- details:end -->

Rendered as HTML:


Summary / TitleSome Text.

console.log('foo');

Rendered as markdown here on GitHub:


Summary / Title

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!

@jhildenbiddle
Copy link
Member

After reviewing #1166 I've come to realize that there are three types of comment-based helpers that should be accounted for:

  1. 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 -->
  2. Helpers with block content that should be processed by docsify and ignored in other environments (e.g. <script></script>)

    <!-- :script:
      console.log('foo')
    -->
  3. 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"-->

@anikethsaha
Copy link
Member

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 👍

@jhildenbiddle
Copy link
Member

The details helper is covered here (near the end of the comment): #413 (comment)

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.

@anikethsaha
Copy link
Member

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>

@jhildenbiddle jhildenbiddle added the ui/ux related to user interface and/or user experience of docsify label Jun 11, 2020
@jhildenbiddle
Copy link
Member

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:

  1. Helpers with block content that should render in all environments (e.g. <details></details>):

    <!-- details:start class="myclass" -->
    #### Heading
    Text
    <!-- details:end -->
  2. 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"-->
  3. 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>
    `;
  }
});

@jhildenbiddle jhildenbiddle modified the milestones: 5.x, 6.x Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement pr welcome ready to implement ui/ux related to user interface and/or user experience of docsify
Projects
None yet
Development

No branches or pull requests

4 participants