markdown
Parse Markdown into a block list, render it to HTML, and pull out the headings, code blocks and tables a docs pipeline or RAG ingest actually wants. Pure - no capabilities.
ecko get github.com/ecko-lang/markdown
import markdown
Pure computation: it declares no capabilities, so it cannot touch the network, the filesystem or the environment.
Version 0.36.0 - source - MIT.
parse(src)
Parse Markdown into a list of block maps.
Every block has a kind, and the fields that go with it:
heading->level(1-6),textparagraph->textcode->lang(may be ""),codelist->ordered(bool),items(list of strings)table->headers(list),rows(list of lists)quote->textrule-> no extra fields
Blocks come back in document order, so parse then a for loop is the whole walking story - there is no separate visitor to learn.
to_html(src)
Render Markdown to HTML.
Text is HTML-escaped before any tag is added, so a document cannot inject markup - <script> in the source comes out as <script>, including inside code blocks and link text.
headings(src)
Every heading, as { level, text }, in document order.
The shape a table of contents or a doc-structure check wants.
code_blocks(src)
Every fenced code block, as { lang, code }.
lang is whatever followed the fence, or "" when the fence was bare - so filtering by language is filter(fn(c) c.lang == "ecko").
tables(src)
Every table, as { headers, rows }.
A table needs the |---| separator row under its header to be recognised, which is what keeps a paragraph that happens to contain a pipe from being read as one.
text(src)
The document as plain text, with the markup removed.
For embedding and search: headings, paragraphs, list items, quotes and table cells come through as text, and code blocks are dropped - a vector of a code sample rarely answers the question someone asked in prose. Use code_blocks when you want those.
sections(src)
Split a document into { heading, level, body } sections, one per heading.
This is the chunking a RAG ingest wants: each section carries the heading it sits under, so a retrieved chunk knows what it is about. Text before the first heading comes back with an empty heading and level 0 rather than being dropped.