Open mortenpi opened 1 year ago
The next step I can take is to replace most of the container/element types, which should also be trivial, since I don't think I changed their fields (
Text
is an exception).
Okay, that was a little optimistic, but I did manage to hack it until I got it to work without any changes to the rest of CommonMark (except for removing type definitions). However, that was more an academic exercise, and not the final product.
Here are the current differences between CommonMark and MarkdownAST that required workarounds. @MichaelHatherly, would you have a bit of time to make some executive decisions on how you think it would be best to proceed with these? I tried to list some potential options for each of them, but I am unsure which ones would be the most appropriate for CM.
.literal
fieldA bunch of elements use the .literal
field of Node
to store their content (Text
, CodeBlock
,Code
, DisplayMath
, InlineMath
, HTMLBlock
, HTMLInline
). In MarkdownAST I would like have all the element-level information to be stored in the element object (e.g. .text
field of the Text
element). Options:
.literal
field, so that updating it keeps the corresponding element field updated too. This is the approach here right now, and doesn't require any changes to CM..literal
values where appropriate..literal
field for some elements. But I am not a big fan of this, as I strongly feel that you shouldn't have to refer back to the container Node
object to figure out e.g. what code is in a code block.Some elements contain additional fields that I did not transfer to MarkdownAST:
CodeBlock
: .is_fenced
, .fence_char
, .fence_length
, .fence_offset
HTMLBlock
: .html_block_type
List
, Item
: .list_data
(in MarkdownAST, I've only moved .type
and .tight
into List
)Mostly, I am not quite sure what information these fields contain, and they look more like some internal parser information. I would like to keep the fields of the elements in MarkdownAST strictly to those that contain some semantic information about the AST.
In the current hack, I have, effectively, added a new field to Node
(via the meta object) that can store another element-specific struct that contains the extra fields (it also has a dynamic type, like .t
), and added some wrapping and overloads to make sure that everything keeps working. Options:
node.meta.extra.node_block_type
instead of node.t.html_block_type
).JuliaExpression
-> JuliaValue
thing), discarding all the extra fields.The CommonMark elements generally have zero-argument constructors, and the fields of the elements are populated afterwards. In MarkdownAST, I generally want to construct a valid element right away, so I don't usually have the zero-argument constructors, and I also try to enforce some invariants in the constructors, to make sure you can't construct nonsensical elements. Options:
CodeBlock() = MarkdownAST.CodeBlock("", "")
). This would require updating all the places where the elements are used as types though (e.g. function signatures, isa
checks).element(::Type{CodeBlock}) = MarkdownAST.CodeBlock("", "")
and call it as node.t = element(CodeBlock)
).In the current hack, I am just committing type piracy, and adding the necessary constructors to the MarkdownAST types.
This is just a proof of concept, but shows how we can use the
Node
type from MarkdownAST, by just overloading the properties of the fully qualified type.I am actually a little surprised that this required literally no code changes. The next step I can take is to replace most of the container/element types, which should also be trivial, since I don't think I changed their fields (
Text
is an exception).