Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -0,0 +1,151 @@
|
||||
// Copyright 2026 The V Language. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
//
|
||||
// Module markdown provides CommonMark-compliant markdown parsing and HTML
|
||||
// rendering with support for GitHub Flavored Markdown and additional
|
||||
// extensions. It is designed for feature parity with github.com/yuin/goldmark.
|
||||
//
|
||||
// Basic usage:
|
||||
//
|
||||
// import x.markdown
|
||||
//
|
||||
// html := markdown.to_html('# Hello\n\nWorld')
|
||||
//
|
||||
// With GFM extensions:
|
||||
//
|
||||
// md := markdown.new(extensions: markdown.gfm())
|
||||
// html := md.convert('| a | b |\n|---|---|\n| 1 | 2 |')
|
||||
//
|
||||
// With fine-grained options:
|
||||
//
|
||||
// md := markdown.new(
|
||||
// extensions: [markdown.Extension(markdown.footnote()), markdown.typographer()],
|
||||
// parser_opts: markdown.ParserOptions{ auto_heading_id: true },
|
||||
// renderer_opts: markdown.RendererOptions{ unsafe_: true, xhtml: true },
|
||||
// )
|
||||
// html := md.convert(source)
|
||||
//
|
||||
// Parse to AST and walk:
|
||||
//
|
||||
// doc := md.parse(source)
|
||||
// doc.walk(fn (node &markdown.Node) bool {
|
||||
// println(node.kind)
|
||||
// return true
|
||||
// })
|
||||
module markdown
|
||||
|
||||
// ParserOptions configures parser behaviour.
|
||||
@[params]
|
||||
pub struct ParserOptions {
|
||||
pub mut:
|
||||
// auto_heading_id generates an id attribute for every heading node
|
||||
// derived from the heading text content (goldmark WithAutoHeadingID).
|
||||
auto_heading_id bool
|
||||
}
|
||||
|
||||
// RendererOptions configures HTML renderer behaviour.
|
||||
@[params]
|
||||
pub struct RendererOptions {
|
||||
pub mut:
|
||||
// unsafe_ allows raw HTML from the source to be included in the output.
|
||||
// When false (the default) raw HTML is replaced with an HTML comment.
|
||||
unsafe_ bool
|
||||
// hard_wraps converts every newline inside a paragraph to a <br> tag.
|
||||
hard_wraps bool
|
||||
// xhtml outputs XHTML-style self-closing tags (e.g. <br />).
|
||||
xhtml bool
|
||||
}
|
||||
|
||||
// Options configures a Markdown processor.
|
||||
// Extension flags in the mut section are normally set by calling new() with
|
||||
// an extensions slice; they can also be set directly.
|
||||
@[params]
|
||||
pub struct Options {
|
||||
pub mut:
|
||||
// extensions is the list of extensions applied when new() is called.
|
||||
extensions []Extension
|
||||
// parser_opts configures the parser.
|
||||
parser_opts ParserOptions
|
||||
// renderer_opts configures the renderer.
|
||||
renderer_opts RendererOptions
|
||||
// --- feature flags set by extensions ---
|
||||
tables bool
|
||||
strikethrough bool
|
||||
linkify bool
|
||||
task_list bool
|
||||
footnotes bool
|
||||
typographer bool
|
||||
definition_list bool
|
||||
}
|
||||
|
||||
// LinkRef holds a collected link reference definition (url + optional title).
|
||||
struct LinkRef {
|
||||
dest string
|
||||
title string
|
||||
}
|
||||
|
||||
// Markdown is the main markdown processor. Create one with new() and reuse it
|
||||
// across multiple convert/parse calls; link reference definitions are cached.
|
||||
pub struct Markdown {
|
||||
pub mut:
|
||||
opts Options
|
||||
ref_map map[string]LinkRef
|
||||
}
|
||||
|
||||
// Markdown.new creates a Markdown processor with the given options.
|
||||
// All extensions in opts.extensions are applied immediately.
|
||||
pub fn Markdown.new(opts Options) Markdown {
|
||||
mut m := Markdown{
|
||||
opts: opts
|
||||
ref_map: map[string]LinkRef{}
|
||||
}
|
||||
for ext in opts.extensions {
|
||||
ext.extend(mut m)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// to_html converts the markdown source to HTML with the given options.
|
||||
pub fn to_html(src string, opts Options) string {
|
||||
mut md := Markdown.new(opts)
|
||||
return md.convert(src)
|
||||
}
|
||||
|
||||
// to_plaintext converts the markdown source to UTF-8 plain text with the given options.
|
||||
pub fn to_plaintext(src string, opts Options) string {
|
||||
mut md := Markdown.new(opts)
|
||||
return md.convert_plaintext(src)
|
||||
}
|
||||
|
||||
// convert parses the markdown source and renders it to an HTML string.
|
||||
pub fn (mut m Markdown) convert(src string) string {
|
||||
doc := m.parse(src)
|
||||
mut r := HTMLRenderer{
|
||||
opts: m.opts
|
||||
ref_map: m.ref_map // Use the updated ref_map after parse()
|
||||
}
|
||||
return r.render(doc)
|
||||
}
|
||||
|
||||
// convert_plaintext parses the markdown source and renders it to UTF-8 plain text.
|
||||
pub fn (mut m Markdown) convert_plaintext(src string) string {
|
||||
doc := m.parse(src)
|
||||
mut r := PlainTextRenderer{
|
||||
opts: m.opts
|
||||
ref_map: m.ref_map
|
||||
}
|
||||
return r.render(doc)
|
||||
}
|
||||
|
||||
// parse parses the markdown source into an AST and returns the document root.
|
||||
// Link reference definitions collected during parsing are cached so that
|
||||
// subsequent parse/convert calls on the same Markdown instance share them.
|
||||
pub fn (mut m Markdown) parse(src string) &Node {
|
||||
mut p := BlockParser.new(src, m.opts, m.ref_map)
|
||||
doc := p.parse()
|
||||
for k, v in p.ref_map {
|
||||
m.ref_map[k] = v
|
||||
}
|
||||
return doc
|
||||
}
|
||||
Reference in new issue
Block a user