📝 markdown
Markdown Parser & HTML Renderer - CommonMark Compatible
~400 lines
~35 function
CommonMark
📖 Overview
Markdown modülü, CommonMark standardına uyumlu Markdown parser and HTML renderer sağlar. AST manipulation, syntax highlighting and table of contents generation destekler.
🔑 Key Features
- CommonMark parser (standards-compliant)
- HTML rendering with customization
- AST (Abstract Syntax Tree) access
- Headings, paragraphs, lists, quotes
- Code blocks with syntax highlighting
- Tables, footnotes, task lists
- Inline: bold, italic, code, links, images
- Table of contents generation
- Word count & reading time
🚀 Quick Start
import markdown
// Basit rendering
let html = markdown.render("# Hello\nWorld!")
io.println(html)
// Output: <h1>Hello</h1>\n<p>World!</p>
// Dosyadan okuma
let md_text = fs.read_to_string("README.md")?
let html = markdown.render(md_text)
fs.write("README.html", html)?
💡 Example 1: Blog Generator
import markdown, fs, time, regex
struct BlogPost do
title: str,
date: time.Date,
author: str,
content_html: str,
excerpt: str,
reading_time: int
end
function parse_blog_post(md_file: str) -> Result[BlogPost, Error] do
// Markdown dosyasını oku
let content = fs.read_to_string(md_file)?
// Front matter parse et (YAML)
let (frontmatter, body) = split_frontmatter(content)?
let title = frontmatter.get("title")?
let date = time.parse(frontmatter.get("date")?, "%Y-%m-%d")?
let author = frontmatter.get("author")?
// Markdown to HTML
let doc = markdown.parse(body)
// Table of contents ekle
let toc = markdown.generate_toc(doc)
// Syntax highlighting
markdown.highlight_code_blocks(doc, do
theme: "github",
line_numbers: true
end)
let html = markdown.to_html(doc)
// Excerpt (first paragraph)
let excerpt = markdown.extract_text(doc, max_length: 150)
// Reading time (ortalama 200 kelime/dakika)
let word_count = markdown.word_count(doc)
let reading_time = (word_count / 200).max(1)
return Ok(BlogPost do
title: title,
date: date,
author: author,
content_html: html,
excerpt: excerpt,
reading_time: reading_time
end)
end
function generate_blog_html(post: BlogPost) -> str do
return "
<article>
<header>
<h1>{}</h1>
<div class='meta'>
<span>By {}</span>
<span>{}</span>
<span>{} min read</span>
</div>
</header>
<div class='excerpt'>{}</div>
<div class='content'>
{}
</div>
</article>
".formatla(
post.title,
post.author,
post.date.format("%B %d, %Y"),
post.reading_time,
post.excerpt,
post.content_html
)
end
function main() do
let posts = []
// Tüm blog postlarını parse et
each file in fs.read_dir("posts")? for do
if file.ends_with(".md") do
match parse_blog_post("posts/" + file) do
Ok(post) => posts.ekle(post),
Error(e) => io.eprintln("Error parsing {}: {}", file, e)
end
end
end
// Tarihe göre sırala
posts.sort_by(|a, b| b.date.cmp(&a.date))
// HTML create
each post in posts for do
let html = generate_blog_html(post)
let slug = post.title.to_lowercase().replace(" ", "-")
fs.write("output/{}.html".formatla(slug), html)?
end
io.println("Generated {} blog posts", posts.uzunluk())
end
💡 Example 2: Documentation Generator
import markdown, fs
function generate_docs(input_dir: str, output_dir: str) -> Result[None, Error] do
// Template
let template = fs.read_to_string("template.html")?
// Sidebar navigation
let nav_items = []
// Process all markdown files
each file in fs.glob("{}/**/*.md".formatla(input_dir))? for do
let md_text = fs.read_to_string(file)?
let doc = markdown.parse(md_text)
// Extract title (first h1)
let title = markdown.find_first_heading(doc, level: 1)
.unwrap_or("Untitled")
// Generate TOC
let toc_html = markdown.generate_toc_html(doc, do
min_level: 2,
max_level: 4,
id_prefix: "toc-"
end)
// Add IDs to headings
markdown.add_heading_ids(doc)
// Convert to HTML
let content_html = markdown.to_html(doc)
// Apply template
let html = template
.replace("{{title}}", title)
.replace("{{toc}}", toc_html)
.replace("{{content}}", content_html)
// Output path
let rel_path = file.strip_prefix(input_dir)?
let out_file = "{}/{}.html".formatla(output_dir,
rel_path.strip_suffix(".md")?)
fs.create_dir_all(fs.parent(out_file)?)?
fs.write(out_file, html)?
// Add to navigation
nav_items.ekle(do
title: title,
path: rel_path.replace(".md", ".html")
end)
io.println("✓ Generated {}", out_file)
end
// Generate index with navigation
generate_index(output_dir, nav_items)?
return Ok(None)
end
📦 AST Manipulation
// Parse to AST
let doc = markdown.parse("# Title\nContent")
// Traverse nodes
let root = doc.root()
each node in root.children() for do
match node.type() do
NodeType.Heading(level) => do
io.println("H{}: {}", level, node.text())
end,
NodeType.Paragraph => do
io.println("Paragraph: {}", node.text())
end,
_ => do end
end
end
// Modify AST
let heading = markdown.Node.new_heading(2)
heading.append_text("New Section")
root.append_child(heading)
// Convert back to HTML
let html = markdown.to_html(doc)
🔗 Related Modules
fs- File I/Oregex- Pattern matchingstring- Text processingtemplate- HTML templates