markd
Version, currently 0.6.011 versions
- 0.6.0latestJul 14, 2026
- 0.5.0not indexedJul 14, 2026
- 0.4.2not indexedJul 14, 2026
- 0.4.1not indexedJul 14, 2026
- 0.4.0not indexedJul 14, 2026
- 0.3.0not indexedJul 14, 2026
- 0.2.1not indexedJul 14, 2026
- 0.2.0not indexedJul 14, 2026
- 0.1.2not indexedJul 14, 2026
- 0.1.1not indexedJul 14, 2026
- 0.1.0not indexedJul 14, 2026
github.com/icyleaf/markd
Yet another markdown parser, Compliant to CommonMark specification, written in Crystal.
127 stars
9 dependents
License: MIT
Installation
# Add this to your shard.yml
dependencies:
markd:
github: icyleaf/markd
version: ~> 0.6.0Then run:
shards installshard.yml
- Crystal
>= 0.36.1, < 2.0.0- License
- MIT
- Authors
- icyleaf <icyleaf.cn@gmail.com>, nobodywasishere <margret@eowyn.net>
Dependencies
This version declares no dependencies.
README
# markd
[](https://github.com/crystal-lang/crystal)
[](https://github.com/icyleaf/markd/blob/master/CHANGELOG.md)
[](https://circleci.com/gh/icyleaf/markd)
<hr />
Yet another markdown parser built for speed, written in [Crystal](https://crystal-lang.org), Compliant to [CommonMark](http://spec.commonmark.org) specification (`v0.29`). Copy from [commonmark.js](https://github.com/jgm/commonmark.js).
## Installation
Add this to your application's `shard.yml`:
```yaml
dependencies:
markd:
github: icyleaf/markd
```
## Quick start
```crystal
require "markd"
markdown = <<-MD
# Hello Markd
> Yet another markdown parser built for speed, written in Crystal, Compliant to CommonMark specification.
MD
html = Markd.to_html(markdown)
```
Also here are options to configure the parse and render.
```crystal
options = Markd::Options.new(smart: true, safe: true)
Markd.to_html(markdown, options)
```
## Options
| Name | Type | Default value | Description |
| ----------- | ------ | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| time | `Bool` | false | render parse cost time during read source, parse blocks, parse inline. |
| smart | `Bool` | false | if **true**, straight quotes will be made curly,<br />`--` will be changed to an en dash,<br />`---` will be changed to an em dash, and<br />`...` will be changed to ellipses. |
| source_pos | `Bool` | false | if **true**, source position information for block-level elements<br />will be rendered in the data-sourcepos attribute (for HTML) |
| safe | `Bool` | false | if **true**, raw HTML will not be passed through to HTML output (it will be replaced by comments) |
| prettyprint | `Bool` | false | if **true**, code tags generated by code blocks will have a `prettyprint` class added to them, to be used by [Google code-prettify](https://github.com/google/code-prettify). |
| gfm | `Bool` | false | **Partial support** |
| autolink | `Bool` | false | if **true**, more autolinks are detected, like bare email addresses or http links |
| toc | `Bool` | false | **Not supported for now** |
| emoji | `Bool` | false | if **true**, convert Github style emoji chars. |
| tagfilter | `Bool` | false | if **true**, escape certain HTML tags. |
| base_url | `URI?` | nil | if not **nil**, relative URLs of links are resolved against this `URI`. It act's like HTML's `<base href="base_url">` in the context of a Markdown document. |
## Advanced
If you want to use a custom renderer, it can!
```crystal
class CustomRenderer < Markd::Renderer
def strong(node, entering)
end
# more methods following in render.
end
options = Markd::Options.new(time: true)
document = Markd::Parser.parse(markdown, options)
renderer = CustomRenderer.new(options)
html = renderer.render(document)
```
## Use tartrazine shards to render code block.
Added and require [tartrazine](https://github.com/ralsina/tartrazine) before markd will use it to render code block.
By default, it use formatter like following:
```crystal
formatter = Tartrazine::Html.new(
theme: Tartrazine.theme("catppuccin-macchiato"),
line_numbers: true,
standalone: true,
)
```
You can passing a formatter instead.
e.g.
```crystal
require "tartrazine" # require it before markd
require "markd"
formatter = Tartrazine::Html.new(
theme: Tartrazine.theme("emacs"),
# Disable print line number
line_numbers: false,
# Set standalone to false for better performace.
#
# You need generate css file use `bin/tartrazine -f html -t "emacs" --css`,
# then link it in you site.
standalone: false,
)
html = Markd.to_html(markdown,formatter: formatter)
```
If you don't care about the formatter config, you can just passing a string instead.
```crystal
require "tartrazine" # require it before markd
require "markd"
html = Markd.to_html(markdown, formatter: "emacs")
```
Currently Tartrazine supports 247 languages and [331 themes](https://github.com/ralsina/tartrazine/tree/main/styles), you can retrieve the supported languages use `Tartrazine::LEXERS_BY_NAME.values.uniq.sort`, for now the result is:
```crystal
[
"LiquidLexer", "VelocityLexer",
"abap", "abnf", "actionscript", "actionscript_3", "ada", "agda", "al", "alloy", "angular2",
"antlr", "apacheconf", "apl", "applescript", "arangodb_aql", "arduino", "armasm",
"autohotkey", "autoit", "awk",
"ballerina", "bash", "bash_session", "batchfile", "bbcode", "bibtex", "bicep", "blitzbasic",
"bnf", "bqn", "brainfuck",
"c", "c#", "c++", "cap_n_proto", "cassandra_cql", "ceylon", "cfengine3", "cfstatement",
"chaiscript", "chapel", "cheetah", "clojure", "cmake", "cobol", "coffeescript",
"common_lisp", "coq", "crystal", "css", "cue", "cython",
"d", "dart", "dax", "desktop_entry", "diff", "django_jinja", "dns", "docker", "dtd", "dylan",
"ebnf", "elixir", "elm", "emacslisp", "erlang",
"factor", "fennel", "fish", "forth", "fortran", "fortranfixed", "fsharp",
"gas", "gdscript", "gdscript3", "gherkin", "gleam", "glsl", "gnuplot", "go_template",
"graphql", "groff", "groovy",
"handlebars", "hare", "haskell", "hcl", "hexdump", "hlb", "hlsl", "holyc", "html", "hy",
"idris", "igor", "ini", "io", "iscdhcpd",
"j", "java", "javascript", "json", "jsonata", "julia", "jungle",
"kotlin",
"lighttpd_configuration_file", "llvm", "lua",
"makefile", "mako", "markdown", "mason", "materialize_sql_dialect", "mathematica", "matlab",
"mcfunction", "meson", "metal", "minizinc", "mlir", "modula-2", "moinwiki", "monkeyc",
"morrowindscript", "myghty", "mysql",
"nasm", "natural", "ndisasm", "newspeak", "nginx_configuration_file", "nim", "nix",
"objective-c", "objectpascal", "ocaml", "octave", "odin", "onesenterprise", "openedge_abl",
"openscad", "org_mode",
"pacmanconf", "perl", "php", "pig", "pkgconfig", "pl_pgsql", "plaintext", "plutus_core",
"pony", "postgresql_sql_dialect", "postscript", "povray", "powerquery", "powershell",
"prolog", "promela", "promql", "properties", "protocol_buffer", "prql", "psl", "puppet",
"python", "python_2",
"qbasic", "qml",
"r", "racket", "ragel", "react", "reasonml", "reg", "rego", "rexx", "rpm_spec", "rst",
"ruby", "rust",
"sas", "sass", "scala", "scheme", "scilab", "scss", "sed", "sieve", "smali", "smalltalk",
"smarty", "snobol", "solidity", "sourcepawn", "sparql", "sql", "squidconf", "standard_ml",
"stas", "stylus", "swift", "systemd", "systemverilog",
"tablegen", "tal", "tasm", "tcl", "tcsh", "termcap", "terminfo", "terraform", "tex",
"thrift", "toml", "tradingview", "transact-sql", "turing", "turtle", "twig", "typescript",
"typoscript", "typoscriptcssdata", "typoscripthtmldata",
"ucode",
"v", "v_shell", "vala", "vb_net", "verilog", "vhdl", "vhs", "viml", "vue", "wdte",
"webgpu_shading_language", "whiley",
"xml", "xorg",
"yaml", "yang", "z80_assembly",
"zed", "zig"
]
```
For details usage, check [tartrazine](https://github.com/ralsina/tartrazine) documents.
## Performance
Here is the result of [a sample markdown file](benchmarks/source.md) parse at MacBook Pro Retina 2015 (2.2 GHz):
```
Crystal Markdown (no longer present) 3.28k (305.29µs) (± 0.92%) fastest
Markd 305.36 ( 3.27ms) (± 5.52%) 10.73× slower
```
Recently, I'm working to compare the other popular commonmark parser, the code is stored in [benchmarks](/benchmarks).
## How to Contribute
Your contributions are always welcome! Please submit a pull request or create an issue to add a new question, bug or feature to the list.
All [Contributors](https://github.com/icyleaf/markd/graphs/contributors) are on the wall.
## You may also like
- [halite](https://github.com/icyleaf/halite) - HTTP Requests Client with a chainable REST API, built-in sessions and middlewares.
- [totem](https://github.com/icyleaf/totem) - Load and parse a configuration file or string in JSON, YAML, dotenv formats.
- [poncho](https://github.com/icyleaf/poncho) - A .env parser/loader improved for performance.
- [popcorn](https://github.com/icyleaf/popcorn) - Easy and Safe casting from one type to another.
- [fast-crystal](https://github.com/icyleaf/fast-crystal) - 💨 Writing Fast Crystal 😍 -- Collect Common Crystal idioms.
## License
[MIT License](https://github.com/icyleaf/markd/blob/master/LICENSE) © icyleaf
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.6.0- Tagged
- Jul 14, 2026
- Commit
9db69c0aba80- Crystal
>= 0.36.1, < 2.0.0- Indexed
- yes
Dependents
Repository
github.com/icyleaf/markd
Metadata
- Created
- Aug 12, 2026
- Updated
- Aug 12, 2026
- Synced
- Aug 12, 2026
- Versions
- 11