mirror of
https://github.com/github/awesome-copilot.git
synced 2026-02-20 10:25:13 +00:00
6.1 KiB
6.1 KiB
gomarkdown/markdown Reference
Go library for parsing Markdown and rendering HTML. Fast, extensible, and thread-safe.
Installation
# Add to your Go project
go get github.com/gomarkdown/markdown
# Install CLI tool
go install github.com/gomarkdown/mdtohtml@latest
Basic Usage
Simple Conversion
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))
}
Using CLI Tool
# Convert file to HTML
mdtohtml input.md output.html
# Output to stdout
mdtohtml input.md
Parser Configuration
Common Extensions
import (
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/parser"
)
// Create parser with extensions
extensions := parser.CommonExtensions | parser.AutoHeadingIDs
p := parser.NewWithExtensions(extensions)
// Parse markdown
doc := p.Parse(md)
Available Parser Extensions
| Extension | Description |
|---|---|
parser.CommonExtensions |
Tables, fenced code, autolinks, strikethrough |
parser.Tables |
Pipe tables support |
parser.FencedCode |
Fenced code blocks with language |
parser.Autolink |
Auto-detect URLs |
parser.Strikethrough |
|
parser.SpaceHeadings |
Require space after # in headings |
parser.HeadingIDs |
Custom heading IDs {#id} |
parser.AutoHeadingIDs |
Auto-generate heading IDs |
parser.Footnotes |
Footnote support |
parser.NoEmptyLineBeforeBlock |
No blank line required before blocks |
parser.HardLineBreak |
Newlines become <br> |
parser.MathJax |
MathJax support |
parser.SuperSubscript |
Super^script^ and sub |
parser.Mmark |
Mmark syntax support |
HTML Renderer Configuration
Common Flags
import (
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"
)
// Parser
p := parser.NewWithExtensions(parser.CommonExtensions)
// Renderer
htmlFlags := html.CommonFlags | html.HrefTargetBlank
opts := html.RendererOptions{
Flags: htmlFlags,
Title: "My Document",
CSS: "style.css",
}
renderer := html.NewRenderer(opts)
// Convert
html := markdown.ToHTML(md, p, renderer)
Available HTML Flags
| Flag | Description |
|---|---|
html.CommonFlags |
Common sensible defaults |
html.HrefTargetBlank |
Add target="_blank" to links |
html.CompletePage |
Generate complete HTML document |
html.UseXHTML |
Use XHTML output |
html.FootnoteReturnLinks |
Add return links in footnotes |
html.FootnoteNoHRTag |
No <hr> before footnotes |
html.Smartypants |
Smart punctuation |
html.SmartypantsFractions |
Smart fractions (1/2 → ½) |
html.SmartypantsDashes |
Smart dashes (-- → –) |
html.SmartypantsLatexDashes |
LaTeX-style dashes |
Renderer Options
opts := html.RendererOptions{
Flags: htmlFlags,
Title: "Document Title",
CSS: "path/to/style.css",
Icon: "favicon.ico",
Head: []byte("<meta name='author' content='...'>"),
RenderNodeHook: customRenderHook,
}
Complete Example
package main
import (
"os"
"github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"
)
func mdToHTML(md []byte) []byte {
// Parser with extensions
extensions := parser.CommonExtensions |
parser.AutoHeadingIDs |
parser.NoEmptyLineBeforeBlock
p := parser.NewWithExtensions(extensions)
doc := p.Parse(md)
// HTML renderer with options
htmlFlags := html.CommonFlags | html.HrefTargetBlank
opts := html.RendererOptions{Flags: htmlFlags}
renderer := html.NewRenderer(opts)
return markdown.Render(doc, renderer)
}
func main() {
md, _ := os.ReadFile("input.md")
html := mdToHTML(md)
os.WriteFile("output.html", html, 0644)
}
Security: Sanitizing Output
Important: gomarkdown does not sanitize HTML output. Use Bluemonday for untrusted input:
import (
"github.com/microcosm-cc/bluemonday"
"github.com/gomarkdown/markdown"
)
// Convert markdown to potentially unsafe HTML
unsafeHTML := markdown.ToHTML(md, nil, nil)
// Sanitize using Bluemonday
p := bluemonday.UGCPolicy()
safeHTML := p.SanitizeBytes(unsafeHTML)
Bluemonday Policies
| Policy | Description |
|---|---|
UGCPolicy() |
User-generated content (most common) |
StrictPolicy() |
Strip all HTML |
StripTagsPolicy() |
Strip tags, keep text |
NewPolicy() |
Build custom policy |
Working with AST
Accessing the AST
import (
"github.com/gomarkdown/markdown/ast"
"github.com/gomarkdown/markdown/parser"
)
p := parser.NewWithExtensions(parser.CommonExtensions)
doc := p.Parse(md)
// Walk the AST
ast.WalkFunc(doc, func(node ast.Node, entering bool) ast.WalkStatus {
if heading, ok := node.(*ast.Heading); ok && entering {
fmt.Printf("Found heading level %d\n", heading.Level)
}
return ast.GoToNext
})
Custom Renderer
type MyRenderer struct {
*html.Renderer
}
func (r *MyRenderer) RenderNode(w io.Writer, node ast.Node, entering bool) ast.WalkStatus {
// Custom rendering logic
if heading, ok := node.(*ast.Heading); ok && entering {
fmt.Fprintf(w, "<h%d class='custom'>", heading.Level)
return ast.GoToNext
}
return r.Renderer.RenderNode(w, node, entering)
}
Handling Newlines
Windows and Mac newlines need normalization:
// Normalize newlines before parsing
normalized := parser.NormalizeNewlines(input)
html := markdown.ToHTML(normalized, nil, nil)