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

Support GitHub's Alert Markdown extension #12590

Closed
chlorine3545 opened this issue Jun 11, 2024 · 7 comments
Closed

Support GitHub's Alert Markdown extension #12590

chlorine3545 opened this issue Jun 11, 2024 · 7 comments

Comments

@chlorine3545
Copy link

chlorine3545 commented Jun 11, 2024

I am currently immersed in the development of a new Hugo theme, which aims to provide users with a seamless experience when writing Hugo blogs using Obsidian. However, when it comes to Callout blocks like this:

Important

This is a Callout.

Things get stuck. While utilizing shortcodes and regex can be a workaround, it tends to be error-prone and lacks elegance.

Thus, I am curious whether the esteemed Hugo development team would consider enhancing the Markdown parsing engine to natively support GitHub-style Callouts.

Yours sincerely.

@bep
Copy link
Member

bep commented Jun 11, 2024

When this was proposed/implemented at GitHub, I suggested they used markdown attributes instead (which is certainly more standard and something Hugo could easily support).

They chose not to listen to me. But you could, e.g:

```callout {level="warning" }
This is a warning.
```

And add a code render hook for it.

@bep bep changed the title 能否支持 GitHub 风格的 Callout?Any possibility to support GitHub-style Callout without shortcode? GitHub-style callout in markdown Jun 11, 2024
@chlorine3545
Copy link
Author

When this was proposed/implemented at GitHub, I suggested they used markdown attributes instead (which is certainly more standard and something Hugo could easily support).

They chose not to listen to me. But you could, e.g:

```callout {level="warning" }
This is a warning.

And add a code render hook for it.

Thank you for your kind reply, @bep. Using markdown attributes is indeed a more Markdown-standard solution, and I will try it in my development. I might also come up with another solution for our Obsidian users to write with ease.

I won't close this issue, and if there are any breakthroughs, I will update it.

Have a day as amazing as you are :)

@jmooring
Copy link
Member

jmooring commented Jun 12, 2024

GitHub's documentation for their Alert Markdown extension:
https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts

GitHub's implementation is OK if you speak English. But for the rest of the planet, not so much.

Using English words in the alert designator (e.g., [!NOTE]) is fine, but the rendered alert type is always English. For example:

> [!NOTE]  
> Das ist meine Notiz.

Note

Das ist meine Notiz.

The above is just... rude.

We could support this monolignual syntax with a Goldmark extension, or (preferably) provide multilingual support via a blockquote render hook.

The blockquote render hook would parse the first line, looking for an alert designator (e.g., [!something]), and provide this context to the render hook template:

  • .Attributes -- The Markdown attributes, if any.
  • .Text -- The blockquote text.
  • .PlainText -- The blockquote text as plain text.
  • .Page -- A reference to the current page.
  • .Ordinal -- The zero-based ordinal of the blockquote on the page.
  • .Position -- The position of the blockquote within the page content.
  • .IsAlert -- Returns true if the blockquote has an alert designator.
  • .AlertType -- The alert type converted to lowercase.
  • .AlertText -- The blockquote text, excluding the alert designator.
  • .AlertPlainText -- The blockquote text as plain text, excluding the alert designator.

Ordinal and position are desired but not required. The ordinal is handy for assigning element ids, and the position is handy for error reporting. Example render hook:

{{ $emojis := dict
  "caution" ":exclamation:"
  "important" ":information_source:"
  "note" ":information_source:"
  "tip" ":bulb:"
  "warning" ":information_source:"
}}

{{ if .IsAlert }}
  <blockquote class="alert alert-{{ .AlertType }}">
    <p class="alert-heading">
      {{ transform.Emojify (index $emojis .AlertType) }}
      {{ or (i18n .AlertType) (title .AlertType) }}
    </p>
    {{ .AlertText | safeHTML }}
  </blockquote>
{{ else }}
  <blockquote>
    {{ .Text | safeHTML }}
  </blockquote>
{{ end }}

This render hook implementation would also allow you to do things like:

[markup.goldmark.parser.attribute]
block = true
> Some text
{cite="https://gohugo.io" caption="Some caption"}
<figure>
  <blockquote {{ with .Attributes.cite }}cite="{{ . }}"{{ end }}>
    {{ .Text | safeHTML }}
  </blockquote>
  {{ with .Attributes.caption }}
    <figcaption class="blockquote-caption">
      {{ . | safeHTML }}
    </figcaption>
  {{ end }}
</figure>

@jmooring jmooring changed the title GitHub-style callout in markdown Support GitHub's Alert Markdown extension Jun 14, 2024
@bep bep added this to the v0.131.0 milestone Jul 22, 2024
@chlorine3545
Copy link
Author

chlorine3545 commented Aug 2, 2024

Have there been any breakthroughs here? I wrote a Python script for an All-in-One regex and S3 image upload, and it works well for me for now. However, I'm still hoping for native support for GitHub alerts. This Markdown syntax does have its quirks, but it's currently the most widely used format. :)

PS: My hastily-written Python regex

alert_pattern = re.compile(r'^>\s*\[!(.*?)\]\s*\n((?:>.*\n)*)', re.MULTILINE | re.DOTALL)
def replace_alert(match):
    alert_type = match.group(1).strip()
    content = match.group(2).replace('>', '').strip()
    return f'{{{{< alert "{alert_type}" >}}}}\n{content}\n{{{{< /alert >}}}}'
    
content = alert_pattern.sub(replace_alert, content)

@bep bep added Enhancement and removed Proposal labels Aug 2, 2024
@bep bep self-assigned this Aug 5, 2024
bep added a commit to bep/hugo that referenced this issue Aug 5, 2024
bep added a commit to bep/hugo that referenced this issue Aug 6, 2024
bep added a commit to bep/hugo that referenced this issue Aug 6, 2024
bep added a commit to bep/hugo that referenced this issue Aug 6, 2024
bep added a commit to bep/hugo that referenced this issue Aug 6, 2024
bep added a commit to bep/hugo that referenced this issue Aug 6, 2024
bep added a commit to bep/hugo that referenced this issue Aug 6, 2024
bep added a commit to bep/hugo that referenced this issue Aug 6, 2024
@bep bep closed this as completed in 665ac94 Aug 7, 2024
@jakeprice-me
Copy link

I've been trying this out following the new documentation and it works great, thanks to @bep and @jmooring.

I have however noticed that the alert type's seem to be hardcoded to only accept a few preset types (the five mentioned in GitHub's alerts documentation) - which makes sense because this ticket was for exactly that!

However, it would be quite helpful if we could define additional alert types. I use Obsidian and this change is great because Obsidian does alerts the same way as GitHub, but supports a few more alert types, see here for the list (stuff like info, danger etc).

Would @bep consider adding functionality to allow the user to manually define their own alert types in config.yml?.

@jmooring
Copy link
Member

@jakeprice-me Please open a new issue.

Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants