返回 Skill 列表
extension
分类: 开发与工程无需 API Key

markdown-to-html

将Markdown文件转换为HTML,类似于`marked.js`、`pandoc`、`gomarkdown/markdown`或类似的工具;或者编写自定义脚本来将markdown转换为html,并/或在如`jekyll/jekyll`、`gohugoio/hugo`或类似的使用markdown文档的web模板系统上工作,将它们转换为html。当被要求“将markdown转换为html”、“将md转换为html”、“渲染markdown”、“从markdown生成html”,或在处理.md文件和/或将markdown转换为HTML输出的web模板系统时使用。支持带有GFM、CommonMark和标准Markdown风格的CLI和Node.js工作流。

person作者: jakexiaohubgithub

Markdown to HTML Conversion

Expert skill for converting Markdown documents to HTML using the marked.js library, or writing data conversion scripts; in this case scripts similar to markedJS/marked repository. For custom scripts knowledge is not confined to marked.js, but data conversion methods are utilized from tools like pandoc and gomarkdown/markdown for data conversion; jekyll/jekyll and gohugoio/hugo for templating systems.

The conversion script or tool should handle single files, batch conversions, and advanced configurations.

When to Use This Skill

  • User asks to "convert markdown to html" or "transform md files"
  • User wants to "render markdown" as HTML output
  • User needs to generate HTML documentation from .md files
  • User is building static sites from Markdown content
  • User is building template system that converts markdown to html
  • User is working on a tool, widget, or custom template for an existing templating system
  • User wants to preview Markdown as rendered HTML

Converting Markdown to HTML

Essential Basic Conversions

For more see basic-markdown-to-html.md

    ```markdown
    # Level 1
    ## Level 2

    One sentence with a [link](https://example.com), and a HTML snippet like `<p>paragraph tag</p>`.

    - `ul` list item 1
    - `ul` list item 2

    1. `ol` list item 1
    2. `ol` list item 1

    | Table Item | Description |
    | One | One is the spelling of the number `1`. |
    | Two | Two is the spelling of the number `2`. |

    ```js
    var one = 1;
    var two = 2;

    function simpleMath(x, y) {
     return x + y;
    }
    console.log(simpleMath(one, two));
    ```
    ```

    ```html
    <h1>Level 1</h1>
    <h2>Level 2</h2>

    <p>One sentence with a <a href="https://example.com">link</a>, and a HTML snippet like <code>&lt;p&gt;paragraph tag&lt;/p&gt;</code>.</p>

    <ul>
     <li>`ul` list item 1</li>
     <li>`ul` list item 2</li>
    </ul>

    <ol>
     <li>`ol` list item 1</li>
     <li>`ol` list item 2</li>
    </ol>

    <table>
     <thead>
      <tr>
       <th>Table Item</th>
       <th>Description</th>
      </tr>
     </thead>
     <tbody>
      <tr>
       <td>One</td>
       <td>One is the spelling of the number `1`.</td>
      </tr>
      <tr>
       <td>Two</td>
       <td>Two is the spelling of the number `2`.</td>
      </tr>
     </tbody>
    </table>

    <pre>
     <code>var one = 1;
     var two = 2;

     function simpleMath(x, y) {
      return x + y;
     }
     console.log(simpleMath(one, two));</code>
    </pre>
    ```

Code Block Conversions

For more see code-blocks-to-html.md


    ```markdown
    your code here
    ```

    ```html
    <pre><code class="language-md">
    your code here
    </code></pre>
    ```

    ```js
    console.log("Hello world");
    ```

    ```html
    <pre><code class="language-js">
    console.log("Hello world");
    </code></pre>
    ```

    ```markdown
      ```

      ```
      visible backticks
      ```

      ```
    ```

    ```html
      <pre><code>
      ```

      visible backticks

      ```
      </code></pre>
    ```

Collapsed Section Conversions

For more see collapsed-sections-to-html.md

    ```markdown
    <details>
    <summary>More info</summary>

    ### Header inside

    - Lists
    - **Formatting**
    - Code blocks

        ```js
        console.log("Hello");
        ```

    </details>
    ```

    ```html
    <details>
    <summary>More info</summary>

    <h3>Header inside</h3>

    <ul>
     <li>Lists</li>
     <li><strong>Formatting</strong></li>
     <li>Code blocks</li>
    </ul>

    <pre>
     <code class="language-js">console.log("Hello");</code>
    </pre>

    </details>
    ```

Mathematical Expression Conversions

For more see writing-mathematical-expressions-to-html.md

    ```markdown
    This sentence uses `$` delimiters to show math inline: $\sqrt{3x-1}+(1+x)^2$
    ```

    ```html
    <p>This sentence uses <code>$</code> delimiters to show math inline:
     <math-renderer><math xmlns="http://www.w3.org/1998/Math/MathML">
      <msqrt><mn>3</mn><mi>x</mi><mo>−</mo><mn>1</mn></msqrt>
      <mo>+</mo><mo>(</mo><mn>1</mn><mo>+</mo><mi>x</mi>
      <msup><mo>)</mo><mn>2</mn></msup>
     </math>
    </math-renderer>
    </p>
    ```

    ```markdown
    **The Cauchy-Schwarz Inequality**\
    $$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)$$
    ```

    ```html
    <p><strong>The Cauchy-Schwarz Inequality</strong><br>
     <math-renderer>
      <math xmlns="http://www.w3.org/1998/Math/MathML">
       <msup>
        <mrow><mo>(</mo>
         <munderover><mo data-mjx-texclass="OP">∑</mo>
          <mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow><mi>n</mi>
         </munderover>
         <msub><mi>a</mi><mi>k</mi></msub>
         <msub><mi>b</mi><mi>k</mi></msub>
         <mo>)</mo>
        </mrow>
        <mn>2</mn>
       </msup>
       <mo>≤</mo>
       <mrow><mo>(</mo>
        <munderover><mo>∑</mo>
         <mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow>
         <mi>n</mi>
        </munderover>
        <msubsup><mi>a</mi><mi>k</mi><mn>2</mn></msubsup>
        <mo>)</mo>
       </mrow>
       <mrow><mo>(</mo>
         <munderover><mo>∑</mo>
          <mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow>
          <mi>n</mi>
         </munderover>
         <msubsup><mi>b</mi><mi>k</mi><mn>2</mn></msubsup>
         <mo>)</mo>
       </mrow>
      </math>
     </math-renderer></p>
    ```

Table Conversions

For more see tables-to-html.md

    ```markdown
    | First Header  | Second Header |
    | ------------- | ------------- |
    | Content Cell  | Content Cell  |
    | Content Cell  | Content Cell  |
    ```

    ```html
    <table>
     <thead><tr><th>First Header</th><th>Second Header</th></tr></thead>
     <tbody>
      <tr><td>Content Cell</td><td>Content Cell</td></tr>
      <tr><td>Content Cell</td><td>Content Cell</td></tr>
     </tbody>
    </table>
    ```

    ```markdown
    | Left-aligned | Center-aligned | Right-aligned |
    | :---         |     :---:      |          ---: |
    | git status   | git status     | git status    |
    | git diff     | git diff       | git diff      |
    ```

    ```html
    <table>
      <thead>
       <tr>
        <th align="left">Left-aligned</th>
        <th align="center">Center-aligned</th>
        <th align="right">Right-aligned</th>
       </tr>
      </thead>
      <tbody>
       <tr>
        <td align="left">git status</td>
        <td align="center">git status</td>
        <td align="right">git status</td>
       </tr>
       <tr>
        <td align="left">git diff</td>
        <td align="center">git diff</td>
        <td align="right">git diff</td>
       </tr>
      </tbody>
    </table>
    ```

Working with markedJS/marked

Prerequisites

  • Node.js installed (for CLI or programmatic usage)
  • Install marked globally for CLI: npm install -g marked
  • Or install locally: npm install marked

Quick Conversion Methods

See marked.md Quick Conversion Methods

Step-by-Step Workflows

See marked.md Step-by-Step Workflows

CLI Configuration

Using Config Files

Create ~/.marked.json for persistent options:

{
  "gfm": true,
  "breaks": true
}

Or use a custom config:

marked -i input.md -o output.html -c config.json

CLI Options Reference

| Option | Description | |--------|-------------| | -i, --input <file> | Input Markdown file | | -o, --output <file> | Output HTML file | | -s, --string <string> | Parse string instead of file | | -c, --config <file> | Use custom config file | | --gfm | Enable GitHub Flavored Markdown | | --breaks | Convert newlines to <br> | | --help | Show all options |

Security Warning

⚠️ Marked does NOT sanitize output HTML. For untrusted input, use a sanitizer:

import { marked } from 'marked';
import DOMPurify from 'dompurify';

const unsafeHtml = marked.parse(untrustedMarkdown);
const safeHtml = DOMPurify.sanitize(unsafeHtml);

Recommended sanitizers:

Supported Markdown Flavors

| Flavor | Support | |--------|---------| | Original Markdown | 100% | | CommonMark 0.31 | 98% | | GitHub Flavored Markdown | 97% |

Troubleshooting

| Issue | Solution | |-------|----------| | Special characters at file start | Strip zero-width chars: content.replace(/^[\u200B\u200C\u200D\uFEFF]/,"") | | Code blocks not highlighting | Add a syntax highlighter like highlight.js | | Tables not rendering | Ensure gfm: true option is set | | Line breaks ignored | Set breaks: true in options | | XSS vulnerability concerns | Use DOMPurify to sanitize output |

Working with pandoc

Prerequisites

  • Pandoc installed (download from https://pandoc.org/installing.html)
  • For PDF output: LaTeX installation (MacTeX on macOS, MiKTeX on Windows, texlive on Linux)
  • Terminal/command prompt access

Quick Conversion Methods

Method 1: CLI Basic Conversion

# Convert markdown to HTML
pandoc input.md -o output.html

# Convert with standalone document (includes header/footer)
pandoc input.md -s -o output.html

# Explicit format specification
pandoc input.md -f markdown -t html -s -o output.html

Method 2: Filter Mode (Interactive)

# Start pandoc as a filter
pandoc

# Type markdown, then Ctrl-D (Linux/macOS) or Ctrl-Z+Enter (Windows)
Hello *pandoc*!
# Output: <p>Hello <em>pandoc</em>!</p>

Method 3: Format Conversion

# HTML to Markdown
pandoc -f html -t markdown input.html -o output.md

# Markdown to LaTeX
pandoc input.md -s -o output.tex

# Markdown to PDF (requires LaTeX)
pandoc input.md -s -o output.pdf

# Markdown to Word
pandoc input.md -s -o output.docx

CLI Configuration

| Option | Description | |--------|-------------| | -f, --from <format> | Input format (markdown, html, latex, etc.) | | -t, --to <format> | Output format (html, latex, pdf, docx, etc.) | | -s, --standalone | Produce standalone document with header/footer | | -o, --output <file> | Output file (inferred from extension) | | --mathml | Convert TeX math to MathML | | --metadata title="Title" | Set document metadata | | --toc | Include table of contents | | --template <file> | Use custom template | | --help | Show all options |

Security Warning

⚠️ Pandoc processes input faithfully. When converting untrusted markdown:

  • Use --sandbox mode to disable external file access
  • Validate input before processing
  • Sanitize HTML output if displayed in browsers
# Run in sandbox mode for untrusted input
pandoc --sandbox input.md -o output.html

Supported Markdown Flavors

| Flavor | Support | |--------|---------| | Pandoc Markdown | 100% (native) | | CommonMark | Full (use -f commonmark) | | GitHub Flavored Markdown | Full (use -f gfm) | | MultiMarkdown | Partial |

Troubleshooting

| Issue | Solution | |-------|----------| | PDF generation fails | Install LaTeX (MacTeX, MiKTeX, or texlive) | | Encoding issues on Windows | Run chcp 65001 before using pandoc | | Missing standalone headers | Add -s flag for complete documents | | Math not rendering | Use --mathml or --mathjax option | | Tables not rendering | Ensure proper table syntax with pipes and dashes |

Working with gomarkdown/markdown

Prerequisites

  • Go 1.18 or higher installed
  • Install the library: go get github.com/gomarkdown/markdown
  • For CLI tool: go install github.com/gomarkdown/mdtohtml@latest

Quick Conversion Methods

Method 1: Simple Conversion (Go)

package main

import (
    "fmt"
    "github.com/gomarkdown/markdown"
)

func main() {
    md := []byte("# Hello World\n\nThis is **bold** text.")
    html := markdown.ToHTML(md, nil, nil)
    fmt.Println(string(html))
}

Method 2: CLI Tool

# Install mdtohtml
go install github.com/gomarkdown/mdtohtml@latest

# Convert file
mdtohtml input.md output.html

# Convert file (output to stdout)
mdtohtml input.md

Method 3: Custom Parser and Renderer

package main

import (
    "github.com/gomarkdown/markdown"
    "github.com/gomarkdown/markdown/html"
    "github.com/gomarkdown/markdown/parser"
)

func mdToHTML(md []byte) []byte {
    // Create parser with extensions
    extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
    p := parser.NewWithExtensions(extensions)
    doc := p.Parse(md)

    // Create HTML renderer with extensions
    htmlFlags := html.CommonFlags | html.HrefTargetBlank
    opts := html.RendererOptions{Flags: htmlFlags}
    renderer := html.NewRenderer(opts)

    return markdown.Render(doc, renderer)
}

CLI Configuration

The mdtohtml CLI tool has minimal options:

mdtohtml input-file [output-file]

For advanced configuration, use the Go library programmatically with parser and renderer options:

| Parser Extension | Description | |------------------|-------------| | parser.CommonExtensions | Tables, fenced code, autolinks, strikethrough, etc. | | parser.AutoHeadingIDs | Generate IDs for headings | | parser.NoEmptyLineBeforeBlock | No blank line needed before blocks | | parser.MathJax | MathJax support for LaTeX math |

| HTML Flag | Description | |-----------|-------------| | html.CommonFlags | Common HTML output flags | | html.HrefTargetBlank | Add target="_blank" to links | | html.CompletePage | Generate complete HTML page | | html.UseXHTML | Generate XHTML output |

Security Warning

⚠️ gomarkdown does NOT sanitize output HTML. For untrusted input, use Bluemonday:

import (
    "github.com/microcosm-cc/bluemonday"
    "github.com/gomarkdown/markdown"
)

maybeUnsafeHTML := markdown.ToHTML(md, nil, nil)
html := bluemonday.UGCPolicy().SanitizeBytes(maybeUnsafeHTML)

Recommended sanitizer: Bluemonday

Supported Markdown Flavors

| Flavor | Support | |--------|---------| | Original Markdown | 100% | | CommonMark | High (with extensions) | | GitHub Flavored Markdown | High (tables, fenced code, strikethrough) | | MathJax/LaTeX Math | Supported via extension | | Mmark | Supported |

Troubleshooting

| Issue | Solution | |-------|----------| | Windows/Mac newlines not parsed | Use parser.NormalizeNewlines(input) | | Tables not rendering | Enable parser.Tables extension | | Code blocks without highlighting | Integrate with syntax highlighter like Chroma | | Math not rendering | Enable parser.MathJax extension | | XSS vulnerabilities | Use Bluemonday to sanitize output |

Working with jekyll

Prerequisites

  • Ruby version 2.7.0 or higher
  • RubyGems
  • GCC and Make (for native extensions)
  • Install Jekyll and Bundler: gem install jekyll bundler

Quick Conversion Methods

Method 1: Create New Site

# Create a new Jekyll site
jekyll new myblog

# Change to site directory
cd myblog

# Build and serve locally
bundle exec jekyll serve

# Access at http://localhost:4000

Method 2: Build Static Site

# Build site to _site directory
bundle exec jekyll build

# Build with production environment
JEKYLL_ENV=production bundle exec jekyll build

Method 3: Live Reload Development

# Serve with live reload
bundle exec jekyll serve --livereload

# Serve with drafts
bundle exec jekyll serve --drafts

CLI Configuration

| Command | Description | |---------|-------------| | jekyll new <path> | Create new Jekyll site | | jekyll build | Build site to _site directory | | jekyll serve | Build and serve locally | | jekyll clean | Remove generated files | | jekyll doctor | Check for configuration issues |

| Serve Options | Description | |---------------|-------------| | --livereload | Reload browser on changes | | --drafts | Include draft posts | | --port <port> | Set server port (default: 4000) | | --host <host> | Set server host (default: localhost) | | --baseurl <url> | Set base URL |

Security Warning

⚠️ Jekyll security considerations:

  • Avoid using safe: false in production
  • Use exclude in _config.yml to prevent sensitive files from being published
  • Sanitize user-generated content if accepting external input
  • Keep Jekyll and plugins updated
# _config.yml security settings
exclude:
  - Gemfile
  - Gemfile.lock
  - node_modules
  - vendor

Supported Markdown Flavors

| Flavor | Support | |--------|---------| | Kramdown (default) | 100% | | CommonMark | Via plugin (jekyll-commonmark) | | GitHub Flavored Markdown | Via plugin (jekyll-commonmark-ghpages) | | RedCarpet | Via plugin (deprecated) |

Configure markdown processor in _config.yml:

markdown: kramdown
kramdown:
  input: GFM
  syntax_highlighter: rouge

Troubleshooting

| Issue | Solution | |-------|----------| | Ruby 3.0+ fails to serve | Run bundle add webrick | | Gem dependency errors | Run bundle install | | Slow builds | Use --incremental flag | | Liquid syntax errors | Check for unescaped { in content | | Plugin not loading | Add to _config.yml plugins list |

Working with hugo

Prerequisites

Quick Conversion Methods

Method 1: Create New Site

# Create a new Hugo site
hugo new site mysite

# Change to site directory
cd mysite

# Add a theme
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke
echo "theme = 'ananke'" >> hugo.toml

# Create content
hugo new content posts/my-first-post.md

# Start development server
hugo server -D

Method 2: Build Static Site

# Build site to public directory
hugo

# Build with minification
hugo --minify

# Build for specific environment
hugo --environment production

Method 3: Development Server

# Start server with drafts
hugo server -D

# Start with live reload and bind to all interfaces
hugo server --bind 0.0.0.0 --baseURL http://localhost:1313/

# Start with specific port
hugo server --port 8080

CLI Configuration

| Command | Description | |---------|-------------| | hugo new site <name> | Create new Hugo site | | hugo new content <path> | Create new content file | | hugo | Build site to public directory | | hugo server | Start development server | | hugo mod init | Initialize Hugo Modules |

| Build Options | Description | |---------------|-------------| | -D, --buildDrafts | Include draft content | | -E, --buildExpired | Include expired content | | -F, --buildFuture | Include future-dated content | | --minify | Minify output | | --gc | Run garbage collection after build | | -d, --destination <path> | Output directory |

| Server Options | Description | |----------------|-------------| | --bind <ip> | Interface to bind to | | -p, --port <port> | Port number (default: 1313) | | --liveReloadPort <port> | Live reload port | | --disableLiveReload | Disable live reload | | --navigateToChanged | Navigate to changed content |

Security Warning

⚠️ Hugo security considerations:

  • Configure security policy in hugo.toml for external commands
  • Use --enableGitInfo carefully with public repositories
  • Validate shortcode parameters for user-generated content
# hugo.toml security settings
[security]
  enableInlineShortcodes = false
  [security.exec]
    allow = ['^go$', '^npx$', '^postcss$']
  [security.funcs]
    getenv = ['^HUGO_', '^CI$']
  [security.http]
    methods = ['(?i)GET|POST']
    urls = ['.*']

Supported Markdown Flavors

| Flavor | Support | |--------|---------| | Goldmark (default) | 100% (CommonMark compliant) | | GitHub Flavored Markdown | Full (tables, strikethrough, autolinks) | | CommonMark | 100% | | Blackfriday (legacy) | Deprecated, not recommended |

Configure markdown in hugo.toml:

[markup]
  [markup.goldmark]
    [markup.goldmark.extensions]
      definitionList = true
      footnote = true
      linkify = true
      strikethrough = true
      table = true
      taskList = true
    [markup.goldmark.renderer]
      unsafe = false  # Set true to allow raw HTML

Troubleshooting

| Issue | Solution | |-------|----------| | "Page not found" on paths | Check baseURL in config | | Theme not loading | Verify theme in themes/ or Hugo Modules | | Slow builds | Use --templateMetrics to identify bottlenecks | | Raw HTML not rendering | Set unsafe = true in goldmark config | | Images not loading | Check static/ folder structure | | Module errors | Run hugo mod tidy |

References

Writing and Styling Markdown

markedJS/marked

pandoc

gomarkdown/markdown

jekyll

hugo