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

feat: GitHub style callouts #2487

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from
Open

feat: GitHub style callouts #2487

wants to merge 15 commits into from

Conversation

jhildenbiddle
Copy link
Member

@jhildenbiddle jhildenbiddle commented Aug 8, 2024

Summary

  • Add support for new GitHub style callouts
  • Update documentation with new syntax details and examples
  • Migrate legacy callouts to new syntax in documentation
  • Mark legacy syntax as deprecated

Markdown

> [!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.

Screenshots

CleanShot 2024-08-08 at 00 07 10@2x

CleanShot 2024-08-08 at 00 06 50@2x

Related issue, if any:

#2486
#1588
#483

What kind of change does this PR introduce?

Feature
Docs

For any code change,

  • Related documentation has been updated, if needed
  • Related tests have been added or updated, if needed

Does this PR introduce a breaking change?

No

Tested in the following browsers:

  • Chrome
  • Firefox
  • Safari
  • Edge

Copy link

vercel bot commented Aug 8, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
docsify-preview ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 12, 2024 5:02am

sy-records
sy-records previously approved these changes Aug 8, 2024
Copy link
Member

@Koooooo-7 Koooooo-7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little changes I proposed.
BTW, the important icon is cute.

// 0: Match "[!TIP] My Title"
// 1: Mark "[!TIP]"
// 2: Type "TIP"
tokens[0].raw.match(/^(\[!(\w+)\])/);
Copy link
Member

@Koooooo-7 Koooooo-7 Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tokens[0].raw.match(/^(\[!(\w+)\])/);
tokens[0].raw.match(/^(\[!(CAUTION|IMPORTANT|NOTE|TIP|WARNING)\])/);

I think we need strict match the callout tags in case of users use something like ![DUCK] in some reason.
And we have no callout class to handle it either.

Copy link
Member Author

@jhildenbiddle jhildenbiddle Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was intentional. :)

Callouts (or "admonitions" or "alerts") are found in many other apps and the list of callouts supported is often much larger than what GitHub supports. By capturing the string contained with the brackets ([!STRING]) and using it as a separate styling-only class (<div class="callout string">) it simplified adding new callouts for third parties.

For example:

> [!BUG]
> This is a bug callout
.callout.bug {
  --callout-bg: orange;
}

Copy link
Member

@Koooooo-7 Koooooo-7 Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. so it means the ![words] is a callout syntax hook (I think I can call it as an reserved word/block) in docsify and users could do the extension.Meanwhile, it will disable to allow user uses a ![not-callout] as a plain start of blockquote.

> [!question] Should we mention it in `UI-KIT`?
> > [!advantage] users can understand there is a way to do extension for callout block (so am I xD ).
> > > [!example]  or we could also add an example.

Copy link
Member Author

@jhildenbiddle jhildenbiddle Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct.

The .callout class handles all of the base styling. The additional class on the callout element (.caution, .important, .note, etc.) is used to adjust styles like colors and icons. To extend the system to support the example you provided above they would simply need to create CSS declarations for each:

callout.question {
  --callout-bg: red;
  --callout-color: white;
}

I can add a note about custom classes to the docs along with a note explaining that in most cases custom classes will not work outside of Docsify.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add a note about custom classes to the docs along with a note explaining that in most cases custom classes will not work outside of Docsify.

Hi, @jhildenbiddle Do you still need to modify the document? If not, then you can merge this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sy-records Yep. Haven't had a chance to complete the updated docs, but I'll have that in the next or two.

Copy link
Member Author

@jhildenbiddle jhildenbiddle Aug 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Koooooo-7 @sy-records --

One other enhancements I'd like to make is the ability to define localized labels. I make a conscious decision to not implement this initially for a few reasons, but after thinking it over for a bit I've decided it makes sense to offer this feature.

The implementation will follow the same pattern we've used elsewhere in our configuration. The default behavior will be to not render text labels (as shown in screenshots above):

window.$docsify = {
  // Default: do not render text labels
  callouts: {},
};

If users want to render text labels automatically as is done in markdown environments like GitHub and Obsidian, they can define them as part of their configuration:

window.$docsify = {
  // Render same label for all route paths
  callouts: {
    caution: 'Caution',
    important: 'Important',
    note: 'Note',
    tip: 'Tip',
    warning: 'Warning',
  },
};
window.$docsify = {
  // Render localized labels based on route paths
  callouts: {
    caution: {
      '/es/': 'Precaución',
      '/de-de/': 'Vorsicht',
      '/ru-ru/': 'Осторожность',
      '/zh-cn/': '警告',
      '/': 'Caution',
    },
    // ...
  },
};

Copy link
Member

@Koooooo-7 Koooooo-7 Aug 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

----- @jhildenbiddle , Currently, we simply add a icon per callout config. That looks good to me.
TIP


I don't propose that we need introduce a label into docsify with the i18n support either:

  • We need extract the content from the [!HERE] and match it to the $.callouts config by path and by content.
    i.e. if user has the ![example], they absolutely want to config it like this:
window.$docsify = {
  // Render same label for all route paths
  callouts: {
    example: {
      '/zh-cn/': '例子',
      '/': 'Example',
    },
  },

It makes the config more complex and messy, they need config options size is: i18n-paths * callouts.


IMO, the icon already has the info, we don't need mention it specially with a label.
In a common sense, a light lamp is tips, a i is info/note, a red thing is forbidden/attention, a yellow triangle is warning. user can simply use it as it default meanings.

The only different thing is we introduce some icon more docsify style (such as important is a cute star.). thats fine since we don't fu*k any things up.

If user do wanna enrich the label in their multi lang sites for each icon, they can simply add something like this:

  • > [!IMPORTANT] **Important** in EN site.
  • > [!IMPORTANT] **重要** in ZH site.

Besides.
We don't need stuck in the [!IMPORTANT] is an IMPORTANT icon.
User can treat the [!SOMEKEY] just a tag or a snytax that docsify would provide some callout icons.

Which means, user could just know something like:

If you config the [!TIP], docsify will give a lamp.

Then, they can append all the extra info for the icon they want or fully "rename" them.
No matter user is an EN speaker or not and how they categorize the icons in their site with their customized icon and docsify builtin icons.

> [!IMPORTANT] **Bonus Time** When you see the Star icon, it means we brings you bonus surprise now!

bunus

@jhildenbiddle jhildenbiddle requested a review from Koooooo-7 August 8, 2024 06:32
Koooooo-7
Koooooo-7 previously approved these changes Aug 8, 2024
Copy link
Member

@Koooooo-7 Koooooo-7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some doc details for the reserved callout syntax and the extension. others LGTM.

paulhibbitts
paulhibbitts previously approved these changes Aug 8, 2024
Copy link
Collaborator

@paulhibbitts paulhibbitts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much @jhildenbiddle, this is a valuable addition to the Docsify Markdown ecosystem!

Copy link
Member

@trusktr trusktr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jhildenbiddle, this is an awesome feature! I've been missing this, and thus I have been using a docsify-plugin-flexible-alerts to enable a similar feature although not exactly the same as GitHub's syntax.

A couple questions:

  1. Does this need to be in core? Or can it be an official plugin?

  2. Can we please follow the GitHub behavior?
    More on question 2:

For example in GitHub we can input this markdown:

> [!Note]
> This is a Note

> [!CAUTION]
> This is a cautionary thing (case of the header doesn't matter)

and this is the result:

Note

This is a Note

Caution

This is a cautionary thing (case of the header doesn't matter)


Note that I did not have to input a redundant additional **Note** or **Caution**, as GitHub will automatically input the text for the callout.

On the otherhand, based on what I see in the OP screenshots, the callout names will not be automatically added, and the Docsify user has to redundantly input them like this:

> [!CAUTION]
> **Caution** callouts communicate negative potential consequences of an action.

The result on GitHub is this:

Caution

Caution callouts communicate negative potential consequences of an action.

which as we can see results in "caution" being there twice, which means rendering will differ between Docsify and GitHub.

@Koooooo-7
Copy link
Member

Hiiii @trusktr Joe.

which as we can see results in "caution" being there twice, which means rendering will differ between Docsify and GitHub.

I think the behavior is totally acceptable.

  • We host docsify in server/githubpage with our own md parser instead github's. (Although it may looks odd when read raw markdown in github)

  • You put all the things under EN and github does not support i18n tho.

i.e.

All is EN, and github's callout icon supports only EN. it seems duplicated.

Caution

Caution callouts communicate negative potential consequences of an action.

  • How about this? The content is ZH, but github still gives me EN callout icon with EN content tho.

Caution

非常重要 这里是一条你不能错过的信息。

IMHO, It is worse than only simply support a icon.

@jhildenbiddle
Copy link
Member Author

jhildenbiddle commented Aug 12, 2024

@trusktr @Koooooo-7 --

You both have valid points. I believe the current design and proposed custom label feature (described here) addresses both of them.

For context, understand that a large number of people are unhappy with GitHub's English-centric callout design (see https://github.com/orgs/community/discussions/16925#discussioncomment-9861713). GitHub callouts always display a label and that label is always in English. There is no way to override this, which can be problematic when authoring markdown non-English languages.

The Docsify callout design addresses GitHub's English-centric design by rendering only an icon without a label by default. This allows users to easy customize callout labels as they prefer directly in their markdown:

Markdown:

<!-- No label, single line -->
> [!caution]
> This is the callout text.

<!-- EN label, single line -->
> [!caution] **Caution:** This is the callout text.

<!-- EN label, new line -->
> [!caution]
>
> **Caution**
>
> This is the callout text.

<!-- ZH label, new line -->
> [!caution]
>
> **非常重要 这里是**
>
> This is the callout text.

However, I believe @trusktr is correct that there will be users who expect Docsify to render callout labels as GitHub does. Users who manually add callout labels in their markdown to "fix" the problem in Docsify may also be unhappy when duplicate titles are rendered on GitHub. This is why I would like to optionally render titles and provide the ability to define localized labels as part of the Docsify config here.

Per @Koooooo-7's preference, the default configuration will render icons only:

window.$docsify = {
  // Default: do not render callout titles
  callouts: {},
};

Per @trusktr's preference, specifying callout labels in English will render callout labels as seen on GitHub and avoid duplicate titles when markdown is rendered on GitHub:

window.$docsify = {
  // Render EN callout titles for all route paths
  callouts: {
    caution: 'Caution',
    important: 'Important',
    note: 'Note',
    tip: 'Tip',
    warning: 'Warning',
  },
};

For sites offering localized documentation, callout labels can be defined based on the route path:

window.$docsify = {
  // Render localized labels based on route paths
  callouts: {
    caution: {
      '/es/': 'Precaución',
      '/de-de/': 'Vorsicht',
      '/ru-ru/': 'Осторожность',
      '/zh-cn/': '警告',
      '/': 'Caution',
    },
    important: {
      // ...
    },
    note: {
      // ...
    },
    tip: {
      // ...
    },
    warning: {
      // ...
    },
  },
};

NOTE: After this PR is merged, it is my intention to recommend GitHub consider a similar "icons only be default" design to address the concerns with their current EN-centric design. I would like to link to our own documentation (once completed) as a reference.

@Koooooo-7
Copy link
Member

Koooooo-7 commented Aug 12, 2024

However, I believe @trusktr is correct that there will be users who expect Docsify to render callout labels as GitHub does. Users who manually add callout labels in their markdown to "fix" the problem in Docsify may also be unhappy when duplicate titles are rendered on GitHub.

@jhildenbiddle --- I keep my point that we could just provide a callout icon and keep the consistency in docsify.
The user unhappy things don't make sense to me:

  • Normally, user don't need add a label to "explain" what the icon means, icon already explains itself by default. and if they do want do so, they can.

  • docsify is not a github based project, we don't need strict follow the github UX stuff for now and in future, it is unpredictable how would github to be in further. All the things are just an refer.
    If we cares about docsify render the callout not same to github.
    When users view and manage their repo in gitlab,bitbucket...etc, which may have different UX stylings. y and would you refuse to follow them? What docsify should do is maintain its own callout styling in consistency. No matter it would be deployed in github pages or other places/services. It is the docsify's renderer job, none of anything code/markdown management services' business.

  • User wants the docs render good in their site, not means it should be same result to view github raw markdown or in other git service providers. otherwise, such as the :id=Heading config should be removed from docsify, github can not parser it, either the js scripts within a markdown. docsify isn't a markdown viewer plugin for github using the github markdown parser. Even the callout syntax is not supported in github enterprise also.
    docsify aims to build a docs site with its own unique styling.

I understand the $.callouts config can both compatible with this, I just think it is unnecessary to strict follow github's to do those changes tho.

@jhildenbiddle
Copy link
Member Author

@jhildenbiddle --- I keep my point that we could just provide a callout icon and keep the consistency in docsify.

Agreed. This is why I opted for the "icon-only" presentation initially and propose it remain the default presentation for Docsify. I believe it is better than GitHub's implementation because it addresses internationalization issues inherent in GitHub's implementation and gives users control over if/how callout titles are rendered.

However, it is also true the icon-only presentation is unique to Docsify and not how other popular markdown environments render the same callout syntax. One way to "fix" the inconsistency in Docsify is to add text labels in markdown, however this will produce duplicate labels when rendered on GitHub and other environments that support the [!LABEL] syntax:

Caution

CAUTION

This is some text

Missing or duplicate labels may not matter to some but they definitely will matter to others. Hence the label option.

Normally, user don't need add a label to "explain" what the icon means, icon already explains itself by default. and if they do want do so, they can.

Agreed on the "if they want to do so, they can" part. The label configuration option provides a way of rendering callout labels that also prevents duplicate labels from being rendered outside of Docsify (see example above). This issue is created by our decision to have a different default presentation (icon-only) than other markdown environments that support the same syntax. If we instead chose to render callous labels by default as other markdown environments do, we wouldn't have to worry about duplicate callout labels when rendering callout markdown outside of Docsify.

When users view and manage their repo in gitlab,bitbucket...etc, which may have different UX stylings. y and would you refuse to follow them? What docsify should do is maintain its own callout styling in consistency. No matter it would be deployed in github pages or other places/services. It is the docsify's renderer job, none of anything code/markdown management services' business.

This is about content consistency, not style consistency.

The issue people have with GitHub's callout implementation is that it introduces potentially unwanted content in the form of English-only labels without the ability to modify them. I think this is a mistake, as do many others who have shared their opinions in the GitHub callout discussion. Regardless and for better or worse, other markdown environments that offer native support for the same syntax (e.g., Obsidian, Typora, VitePress) also render callout labels by default. In order for Docsify to render callouts consistently across environments, we need to provide an option to render callout labels as other environments do. This matters because markdown is a portable documentation format and it is therefore not uncommon for people/teams to edit markdown content in different environments. For example, I frequently edit Docsify markdown in Typora and I know first-hand of teams that have non-technical team members edit Docsify markdown content directly on GitHub.

As far as styles go, Docsify has its own callout style (icons, colors, border, backgrounds, etc.) just as other markdown environments do. This is not unexpected as it is very much a benefit/feature of markdown's portability.

...otherwise, such as the :id=Heading config should be removed from docsify, github can not parser it, either the js scripts within a markdown.

I would love to remove non-standard, Docsify-only syntax from Docsify because the more of it we offer the less portable Docsify markdown becomes. Unfortunately, there are some features that markdown does not offer and extended syntaxes to support them have not been standardized so we're left to invent our own sometimes. IMHO, these non-standard, Docsify-only markdown extensions are a necessary evil, not a pattern to continue if we can help it.

In the case of callouts, a standardized syntax did not exist back in 2017 when Docsify v4 was released so the custom "important" (!>) and "tip" (?>) syntax were fine (although they had issues like not supporting multi-line and nested content). Now that GitHub has released support for the [!LABEL] syntax, markdown environments are adopting it because of GitHub's reach and influence. The syntax is far from perfect, but it's far closer to a standard than Docsify's previous helper syntax is likely to ever be.

@Koooooo-7
Copy link
Member

Koooooo-7 commented Aug 13, 2024

--- @trusktr

Another thing is that "Markdown" was meant to be a standard, and the more variations we have of it, the more fragmented the community. GitHub's is one of the most popular variants of Markdown (if not the most popular), so I think it is worth having consistency in the language, similar to how browsers standardize for HTML, CSS, and JavaScript.

Because of this, I believe we should have a way to follow GitHub's format, but we can allow it to be more flexible customizeable too, best of both worlds. Basically it would be a complete superset of the "standard" markdown, rather than a fork with new parts and parts of standard missing.

Agreed. and I have more deep realization of the github influence now.

Perhaps GitHub behavior should be the default unless a config is provided to override it. The reason is because the "standard" is in english GFM, with default the default behavior on GitHub, so maybe good if it just works the same out of the box with no config. Then someone who needs it in another language can add the config, which is better than both types of users having to add the config. Wdyt?

Jump in. :)
I think we should keep the showing icon without label as the default:

  • The callout of GFM doesn't work very well (no i18n) as I posted here, agree with @jhildenbiddle 's comments .

    NOTE: After this PR is merged, it is my intention to recommend GitHub consider a similar "icons only be default" design to address the concerns with their current EN-centric design. I would like to link to our own documentation (once completed) as a reference.

  • We can not preset the user is EN user, nor the site content, we could keep the behavior same to search placeholder.

docsify-plugin-flexible-alerts also allows customizing the icon, but it requires the font awesome class (f.e. fa-caution) to be specified. I think it would be nice to be able to provide the URL for each icon image instead of a class (or alternative to a class). Useful for "troubleshooting", "bug", and other types of callouts. Or f.e. a warcraft site has warcraft-style shield-like icons, or a stock trading website has bull and bear icons, etc. 😄

Good idea to more customized the callout.
@jhildenbiddle already provide an callout extension hook for custom callout, I suppose it could make it. 👀

@trusktr
Copy link
Member

trusktr commented Feb 28, 2025

I would love to get this merged, but there's one question we haven't chatted about yet:

  1. Does this need to be in core? Or can it be an official plugin?

I personally wish that if there's something we can do as a plugin, that we do it as a plugin, so we can keep core less complicated and smaller, and people can expand the features they need.

Is there anything missing that we need to add to the plugin API before this can be a plugin? If so, we can add that here in the same PR too (or separate if you prefer).


As for the default options, I can live with no call-out text being the default, and I can easily add the options to my config to make it follow GitHub's style. We can also make this prominent in the docs.

@trusktr trusktr self-requested a review February 28, 2025 01:37
Copy link
Member

@trusktr trusktr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to address of this can be in a plugin (previous comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants