diff --git a/source/md.c b/source/md.c index 6228686..d58a30d 100644 --- a/source/md.c +++ b/source/md.c @@ -2624,7 +2624,16 @@ MD_FUNCTION MD_CodeLoc MD_CodeLocFromNode(MD_Node *node) { MD_Node *root = MD_RootFromNode(node); - MD_CodeLoc loc = MD_CodeLocFromFileOffset(root->string, root->raw_string.str, node->offset); + MD_Node *first_tag = root->first_tag; + MD_CodeLoc loc = {0}; + if(MD_NodeIsNil(first_tag)) + { + loc = MD_CodeLocFromFileOffset(root->string, root->raw_string.str, node->offset); + } + else + { + loc = MD_CodeLocFromFileOffset(root->string, first_tag->raw_string.str, node->offset); + } return loc; } @@ -2907,7 +2916,11 @@ MD_NodeMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags) if(a->kind == b->kind && MD_S8Match(a->string, b->string, flags)) { result = 1; - if(a->kind != MD_NodeKind_Tag && (flags & MD_NodeMatchFlag_Tags)) + if(result && flags & MD_NodeMatchFlag_NodeFlags) + { + result = result && a->flags == b->flags; + } + if(result && a->kind != MD_NodeKind_Tag && (flags & MD_NodeMatchFlag_Tags)) { for(MD_Node *a_tag = a->first_tag, *b_tag = b->first_tag; !MD_NodeIsNil(a_tag) || !MD_NodeIsNil(b_tag); @@ -3461,12 +3474,6 @@ MD_FUNCTION void MD_ReconstructionFromNode(MD_Arena *arena, MD_String8List *out, MD_Node *node, int indent, MD_String8 indent_string) { - // TODO(rjf): // TODO(rjf): // TODO(rjf): - // TODO(rjf): // TODO(rjf): // TODO(rjf): - // TODO(rjf): cleanup pass - // TODO(rjf): // TODO(rjf): // TODO(rjf): - // TODO(rjf): // TODO(rjf): // TODO(rjf): - MD_CodeLoc code_loc = MD_CodeLocFromNode(node); #define MD_PrintIndent(_indent_level) do\ @@ -3503,9 +3510,22 @@ MD_S8ListPush(arena, out, indent_string);\ } //- rjf: tags of node + MD_u32 tag_first_line = MD_CodeLocFromNode(node->first_tag).line; + MD_u32 tag_last_line = tag_first_line; { for(MD_EachNode(tag, node->first_tag)) { + MD_u32 tag_line = MD_CodeLocFromNode(tag).line; + if(tag_line != tag_last_line) + { + MD_S8ListPush(arena, out, MD_S8Lit("\n")); + tag_last_line = tag_line; + } + else if(!MD_NodeIsNil(tag->prev)) + { + MD_S8ListPush(arena, out, MD_S8Lit(" ")); + } + MD_PrintIndent(indent); MD_S8ListPush(arena, out, MD_S8Lit("@")); MD_S8ListPush(arena, out, tag->string); @@ -3535,11 +3555,7 @@ MD_S8ListPush(arena, out, indent_string);\ MD_S8ListPush(arena, out, MD_S8Lit(",\n")); } } - MD_S8ListPush(arena, out, MD_S8Lit(")\n")); - } - else - { - MD_S8ListPush(arena, out, MD_S8Lit("\n")); + MD_S8ListPush(arena, out, MD_S8Lit(")")); } } } @@ -3547,7 +3563,15 @@ MD_S8ListPush(arena, out, indent_string);\ //- rjf: name of node if(node->string.size != 0) { - MD_PrintIndent(indent); + if(tag_first_line != tag_last_line) + { + MD_S8ListPush(arena, out, MD_S8Lit("\n")); + MD_PrintIndent(indent); + } + else if(!MD_NodeIsNil(node->first_tag) || !MD_NodeIsNil(node->prev)) + { + MD_S8ListPush(arena, out, MD_S8Lit(" ")); + } if(node->kind == MD_NodeKind_File) { MD_S8ListPush(arena, out, MD_S8Lit("`")); @@ -3567,7 +3591,6 @@ MD_S8ListPush(arena, out, indent_string);\ { MD_S8ListPush(arena, out, MD_S8Lit(":")); } - MD_PrintIndent(indent); // rjf: figure out opener/closer symbols MD_u8 opener_char = 0; @@ -3597,9 +3620,18 @@ MD_S8ListPush(arena, out, indent_string);\ MD_S8ListPush(arena, out, MD_S8Lit("\n")); MD_PrintIndent(indent); } + else + { + MD_S8ListPush(arena, out, MD_S8Lit(" ")); + } MD_S8ListPush(arena, out, MD_S8(&opener_char, 1)); + if(multiline) + { + MD_S8ListPush(arena, out, MD_S8Lit("\n")); + MD_PrintIndent(indent+1); + } } - MD_u32 last_line = code_loc.line; + MD_u32 last_line = MD_CodeLocFromNode(node->first_child).line; for(MD_EachNode(child, node->first_child)) { int child_indent = 0; @@ -3621,6 +3653,10 @@ MD_S8ListPush(arena, out, indent_string);\ MD_S8ListPush(arena, out, MD_S8Lit("\n")); MD_PrintIndent(indent); } + else + { + MD_S8ListPush(arena, out, MD_S8Lit(" ")); + } MD_S8ListPush(arena, out, MD_S8(&closer_char, 1)); } } diff --git a/source/md.h b/source/md.h index 182504a..eb1eda7 100644 --- a/source/md.h +++ b/source/md.h @@ -506,6 +506,7 @@ enum { MD_NodeMatchFlag_Tags = (1<<16), MD_NodeMatchFlag_TagArguments = (1<<17), + MD_NodeMatchFlag_NodeFlags = (1<<18), }; typedef struct MD_DecodedCodepoint MD_DecodedCodepoint; diff --git a/tests/sanity_tests.c b/tests/sanity_tests.c index a487415..c154118 100644 --- a/tests/sanity_tests.c +++ b/tests/sanity_tests.c @@ -810,6 +810,43 @@ int main(void) MD_String8 actual = MD_S8ListJoin(arena, actual_strings, 0); TestResult(MD_S8Match(expected, actual, 0)); } + { + MD_String8 code = MD_S8Lit("@foo @bar @baz a: { b c d e f }"); + MD_ParseResult parse1 = MD_ParseOneNode(arena, code, 0); + MD_String8List reconstruction_strs = {0}; + MD_ReconstructionFromNode(arena, &reconstruction_strs, parse1.node, 0, MD_S8Lit(" ")); + MD_String8 reconstruction = MD_S8ListJoin(arena, reconstruction_strs, 0); + MD_ParseResult parse2 = MD_ParseOneNode(arena, reconstruction, 0); + TestResult(MD_NodeDeepMatch(parse1.node, parse2.node, MD_NodeMatchFlag_TagArguments|MD_NodeMatchFlag_NodeFlags)); + } + { + MD_String8 code = MD_S8Lit("@foo(x: y: z) @bar(a: b: c) @baz(1: 2: 3) abcdefg: { b: 4, c d: 5; e; f, }"); + MD_ParseResult parse1 = MD_ParseOneNode(arena, code, 0); + MD_String8List reconstruction_strs = {0}; + MD_ReconstructionFromNode(arena, &reconstruction_strs, parse1.node, 0, MD_S8Lit(" ")); + MD_String8 reconstruction = MD_S8ListJoin(arena, reconstruction_strs, 0); + MD_ParseResult parse2 = MD_ParseOneNode(arena, reconstruction, 0); + TestResult(MD_NodeDeepMatch(parse1.node, parse2.node, MD_NodeMatchFlag_TagArguments|MD_NodeMatchFlag_NodeFlags)); + } + { + MD_String8 code = MD_S8Lit("@foo(x: y: z)\n" + "@bar(a: b: c)\n" + "@baz(1: 2: 3)\n" + "abcdefg:\n" + "{\n" + " b: 4,\n" + " c\n" + " d: 5;\n" + " e;\n" + " f,\n" + "}\n"); + MD_ParseResult parse1 = MD_ParseOneNode(arena, code, 0); + MD_String8List reconstruction_strs = {0}; + MD_ReconstructionFromNode(arena, &reconstruction_strs, parse1.node, 0, MD_S8Lit(" ")); + MD_String8 reconstruction = MD_S8ListJoin(arena, reconstruction_strs, 0); + MD_ParseResult parse2 = MD_ParseOneNode(arena, reconstruction, 0); + TestResult(MD_NodeDeepMatch(parse1.node, parse2.node, MD_NodeMatchFlag_TagArguments|MD_NodeMatchFlag_NodeFlags)); + } } return 0;