///|
// Cmark sequences and definition maps are mutable. Copy every container at the
// interoperability boundary. Scalars, strings and parser-created metadata are
// immutable and can be shared. These helpers only receive our private parsed AST.
fn copy_doc(doc : @cmark.Doc) -> @cmark.Doc {
let defs = Map([])
for key, definition in doc.defs {
defs[key] = match definition {
LinkDef(node) => @cmark.LabelDef::LinkDef(node.map(copy_link_definition))
FootnoteDef(node) => @cmark.LabelDef::FootnoteDef(node.map(copy_footnote))
}
}
{ ..doc, block: copy_block(doc.block), defs, }
}
///|
fn copy_label(label : @cmark.Label) -> @cmark.Label {
{ ..label, text: label.text.map(x => x), }
}
///|
fn copy_link_definition(value : @cmark.LinkDefinition) -> @cmark.LinkDefinition {
{
..value,
layout: {
..value.layout,
before_dest: value.layout.before_dest.map(x => x),
after_dest: value.layout.after_dest.map(x => x),
},
label: value.label.map(copy_label),
defined_label: value.defined_label.map(copy_label),
title: value.title.map(title => title.map(x => x)),
}
}
///|
fn copy_link(value : @cmark.InlineLink) -> @cmark.InlineLink {
{
text: copy_inline(value.text),
reference: match value.reference {
Inline(node) =>
@cmark.ReferenceKind::Inline(node.map(copy_link_definition))
Ref(layout, label, defined_label) =>
@cmark.ReferenceKind::Ref(
layout,
copy_label(label),
copy_label(defined_label),
)
},
}
}
///|
fn copy_inline(inline : @cmark.Inline) -> @cmark.Inline {
match inline {
Autolink(_) | Break(_) | Text(_) => inline
CodeSpan(node) =>
@cmark.Inline::CodeSpan(
node.map(value => {
..value,
code_layout: value.code_layout.map(x => x),
}),
)
Emphasis(node) =>
@cmark.Inline::Emphasis(
node.map(value => { ..value, inline: copy_inline(value.inline), }),
)
StrongEmphasis(node) =>
@cmark.Inline::StrongEmphasis(
node.map(value => { ..value, inline: copy_inline(value.inline), }),
)
Link(node) => @cmark.Inline::Link(node.map(copy_link))
Image(node) => @cmark.Inline::Image(node.map(copy_link))
Inlines(node) =>
@cmark.Inline::Inlines(node.map(values => values.map(copy_inline)))
RawHtml(node) =>
@cmark.Inline::RawHtml(
node.map(value => @cmark.InlineRawHtml(value.0.map(x => x))),
)
ExtStrikethrough(node) =>
@cmark.Inline::ExtStrikethrough(
node.map(value => @cmark.InlineStrikethrough(copy_inline(value.0))),
)
ExtMathSpan(node) =>
@cmark.Inline::ExtMathSpan(
node.map(value => { ..value, tex_layout: value.tex_layout.map(x => x), }),
)
}
}
///|
fn copy_code(value : @cmark.CodeBlock) -> @cmark.CodeBlock {
{ ..value, code: value.code.map(x => x), }
}
///|
fn copy_footnote(value : @cmark.Footnote) -> @cmark.Footnote {
{
..value,
label: copy_label(value.label),
defined_label: value.defined_label.map(copy_label),
block: copy_block(value.block),
}
}
///|
fn copy_row(value : @cmark.TableRow) -> @cmark.TableRow {
match value {
Header(cells) =>
@cmark.TableRow::Header(cells.map(cell => (copy_inline(cell.0), cell.1)))
Data(cells) =>
@cmark.TableRow::Data(cells.map(cell => (copy_inline(cell.0), cell.1)))
Sep(cells) => @cmark.TableRow::Sep(cells.map(x => x))
}
}
///|
fn copy_block(block : @cmark.Block) -> @cmark.Block {
match block {
BlankLine(_) | ThematicBreak(_) => block
Blocks(node) =>
@cmark.Block::Blocks(node.map(values => values.map(copy_block)))
BlockQuote(node) =>
@cmark.Block::BlockQuote(
node.map(value => { ..value, block: copy_block(value.block), }),
)
CodeBlock(node) => @cmark.Block::CodeBlock(node.map(copy_code))
ExtMathBlock(node) => @cmark.Block::ExtMathBlock(node.map(copy_code))
Heading(node) =>
@cmark.Block::Heading(
node.map(value => { ..value, inline: copy_inline(value.inline), }),
)
Paragraph(node) =>
@cmark.Block::Paragraph(
node.map(value => { ..value, inline: copy_inline(value.inline), }),
)
HtmlBlock(node) =>
@cmark.Block::HtmlBlock(
node.map(value => @cmark.HtmlBlock(value.0.map(x => x))),
)
LinkRefDefinition(node) =>
@cmark.Block::LinkRefDefinition(node.map(copy_link_definition))
List(node) =>
@cmark.Block::List(
node.map(value => {
..value,
items: value.items.map(item => {
item.map(value => { ..value, block: copy_block(value.block), })
}),
}),
)
ExtFootnoteDefinition(node) =>
@cmark.Block::ExtFootnoteDefinition(node.map(copy_footnote))
ExtTable(node) =>
@cmark.Block::ExtTable(
node.map(value => {
..value,
rows: value.rows.map(row => (row.0.map(copy_row), row.1)),
}),
)
}
}