yzhang-gh / vscode-markdown

Markdown All in One
https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one
MIT License
2.93k stars 325 forks source link

Printing document to HTML yields broken ToC #1478

Open Bugg4 opened 3 weeks ago

Bugg4 commented 3 weeks ago

What's the problem

If a document with headings containing special characters is printed to HTML, generated ToC links point to slugified ids, while <h1> , <h2>, etc. tags are given a non-slugified id, breaking the link.

What's the expected result

header tags in the generated HTML are given slugified ids.

How to reproduce

  1. Take the following sample document:
    
    # BROKEN TOC DEMO

test1, comma

lorem ipsum

test2 — em dash

dolor sit

2. Generate a ToC with `Levels`=`2..6` and `Slugify Mode`=`github` (although the issue should be reproducible with any other `Levels` and `Slugify Mode` setting too). The following should be obtained:
```html
<!DOCTYPE html>
        <html>
        <head>
            <meta charset="UTF-8">
            <title>BROKEN TOC DEMO</title>
            <style>
/* From extension vscode.github */
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

.vscode-dark img[src$=\#gh-light-mode-only],
.vscode-light img[src$=\#gh-dark-mode-only],
.vscode-high-contrast:not(.vscode-high-contrast-light) img[src$=\#gh-light-mode-only],
.vscode-high-contrast-light img[src$=\#gh-dark-mode-only] {
    display: none;
}

/* From extension searKing.preview-vscode */
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

.preview-vscode-error {
    color: var(--vscode-editorError-foreground);
}

</style>

        <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/markdown.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Microsoft/vscode/extensions/markdown-language-features/media/highlight.css">
<style>
            body {
                font-family: -apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif;
                font-size: 14px;
                line-height: 1.6;
            }
        </style>
        <style>
.task-list-item {
    list-style-type: none;
}

.task-list-item-checkbox {
    margin-left: -20px;
    vertical-align: middle;
    pointer-events: none;
}
</style>
<style>
:root {
  --color-note: #0969da;
  --color-tip: #1a7f37;
  --color-warning: #9a6700;
  --color-severe: #bc4c00;
  --color-caution: #d1242f;
  --color-important: #8250df;
}

</style>
<style>
@media (prefers-color-scheme: dark) {
  :root {
    --color-note: #2f81f7;
    --color-tip: #3fb950;
    --color-warning: #d29922;
    --color-severe: #db6d28;
    --color-caution: #f85149;
    --color-important: #a371f7;
  }
}

</style>
<style>
.markdown-alert {
  padding: 0.5rem 1rem;
  margin-bottom: 16px;
  color: inherit;
  border-left: .25em solid #888;
}

.markdown-alert>:first-child {
  margin-top: 0
}

.markdown-alert>:last-child {
  margin-bottom: 0
}

.markdown-alert .markdown-alert-title {
  display: flex;
  font-weight: 500;
  align-items: center;
  line-height: 1
}

.markdown-alert .markdown-alert-title .octicon {
  margin-right: 0.5rem;
  display: inline-block;
  overflow: visible !important;
  vertical-align: text-bottom;
  fill: currentColor;
}

.markdown-alert.markdown-alert-note {
  border-left-color: var(--color-note);
}

.markdown-alert.markdown-alert-note .markdown-alert-title {
  color: var(--color-note);
}

.markdown-alert.markdown-alert-important {
  border-left-color: var(--color-important);
}

.markdown-alert.markdown-alert-important .markdown-alert-title {
  color: var(--color-important);
}

.markdown-alert.markdown-alert-warning {
  border-left-color: var(--color-warning);
}

.markdown-alert.markdown-alert-warning .markdown-alert-title {
  color: var(--color-warning);
}

.markdown-alert.markdown-alert-tip {
  border-left-color: var(--color-tip);
}

.markdown-alert.markdown-alert-tip .markdown-alert-title {
  color: var(--color-tip);
}

.markdown-alert.markdown-alert-caution {
  border-left-color: var(--color-caution);
}

.markdown-alert.markdown-alert-caution .markdown-alert-title {
  color: var(--color-caution);
}

</style>

        </head>
        <body class="vscode-body vscode-light">
            <h1 id="broken-toc-demo" tabindex="-1" id="broken-toc-demo">BROKEN TOC DEMO</h1>
<ul>
<li><a href="#test1-comma">test1, comma</a></li>
<li><a href="#test2--em-dash">test2 — em dash</a></li>
</ul>
<h2 id="test1%2C-comma" tabindex="-1" id="test1-comma">test1, comma</h2>
<p>lorem ipsum</p>
<h2 id="test2-%E2%80%94-em-dash" tabindex="-1" id="test2--em-dash">test2 — em dash</h2>
<p>dolor sit</p>

        </body>
        </html>
  1. Try following a ToC link.

Other information

I also noticed that the generated HTML header tags always have two ids.