react-native-nitro-markdown 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +20 -2
  2. package/cpp/bindings/HybridMarkdownParser.cpp +2 -0
  3. package/cpp/core/MD4CParser.cpp +73 -39
  4. package/cpp/core/MarkdownTypes.hpp +6 -1
  5. package/cpp/md4c/md4c.c +79 -56
  6. package/cpp/md4c/md4c.h +7 -4
  7. package/lib/commonjs/headless.js +38 -1
  8. package/lib/commonjs/headless.js.map +1 -1
  9. package/lib/commonjs/markdown.js +19 -11
  10. package/lib/commonjs/markdown.js.map +1 -1
  11. package/lib/commonjs/renderers/image.js +26 -5
  12. package/lib/commonjs/renderers/image.js.map +1 -1
  13. package/lib/commonjs/renderers/list.js +1 -5
  14. package/lib/commonjs/renderers/list.js.map +1 -1
  15. package/lib/commonjs/renderers/math.js +14 -4
  16. package/lib/commonjs/renderers/math.js.map +1 -1
  17. package/lib/commonjs/renderers/paragraph.js +1 -3
  18. package/lib/commonjs/renderers/paragraph.js.map +1 -1
  19. package/lib/module/headless.js +36 -0
  20. package/lib/module/headless.js.map +1 -1
  21. package/lib/module/markdown.js +20 -12
  22. package/lib/module/markdown.js.map +1 -1
  23. package/lib/module/renderers/image.js +27 -6
  24. package/lib/module/renderers/image.js.map +1 -1
  25. package/lib/module/renderers/list.js +1 -5
  26. package/lib/module/renderers/list.js.map +1 -1
  27. package/lib/module/renderers/math.js +14 -4
  28. package/lib/module/renderers/math.js.map +1 -1
  29. package/lib/module/renderers/paragraph.js +1 -3
  30. package/lib/module/renderers/paragraph.js.map +1 -1
  31. package/lib/typescript/commonjs/headless.d.ts +4 -0
  32. package/lib/typescript/commonjs/headless.d.ts.map +1 -1
  33. package/lib/typescript/commonjs/markdown.d.ts +13 -0
  34. package/lib/typescript/commonjs/markdown.d.ts.map +1 -1
  35. package/lib/typescript/commonjs/renderers/image.d.ts.map +1 -1
  36. package/lib/typescript/commonjs/renderers/list.d.ts.map +1 -1
  37. package/lib/typescript/commonjs/renderers/math.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/renderers/paragraph.d.ts.map +1 -1
  39. package/lib/typescript/commonjs/specs/MarkdownSession.nitro.d.ts.map +1 -1
  40. package/lib/typescript/module/headless.d.ts +4 -0
  41. package/lib/typescript/module/headless.d.ts.map +1 -1
  42. package/lib/typescript/module/markdown.d.ts +13 -0
  43. package/lib/typescript/module/markdown.d.ts.map +1 -1
  44. package/lib/typescript/module/renderers/image.d.ts.map +1 -1
  45. package/lib/typescript/module/renderers/list.d.ts.map +1 -1
  46. package/lib/typescript/module/renderers/math.d.ts.map +1 -1
  47. package/lib/typescript/module/renderers/paragraph.d.ts.map +1 -1
  48. package/lib/typescript/module/specs/MarkdownSession.nitro.d.ts.map +1 -1
  49. package/nitrogen/generated/ios/NitroMarkdownAutolinking.swift +8 -7
  50. package/nitrogen/generated/ios/swift/HybridMarkdownSessionSpec.swift +2 -2
  51. package/package.json +1 -1
  52. package/src/headless.ts +56 -1
  53. package/src/markdown.tsx +40 -16
  54. package/src/renderers/image.tsx +35 -6
  55. package/src/renderers/list.tsx +5 -13
  56. package/src/renderers/math.tsx +8 -2
  57. package/src/renderers/paragraph.tsx +1 -3
  58. package/src/specs/MarkdownSession.nitro.ts +4 -6
package/cpp/md4c/md4c.c CHANGED
@@ -145,6 +145,9 @@
145
145
  #define OFF MD_OFFSET
146
146
 
147
147
  #define SZ_MAX (sizeof(SZ) == 8 ? UINT64_MAX : UINT32_MAX)
148
+ #ifdef OFF_MAX
149
+ #undef OFF_MAX
150
+ #endif
148
151
  #define OFF_MAX (sizeof(OFF) == 8 ? UINT64_MAX : UINT32_MAX)
149
152
 
150
153
  typedef struct MD_MARK_tag MD_MARK;
@@ -439,36 +442,36 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ
439
442
  } while(0)
440
443
 
441
444
 
442
- #define MD_ENTER_BLOCK(type, arg) \
445
+ #define MD_ENTER_BLOCK(type, arg, off) \
443
446
  do { \
444
- ret = ctx->parser.enter_block((type), (arg), ctx->userdata); \
447
+ ret = ctx->parser.enter_block((type), (arg), (off), ctx->userdata); \
445
448
  if(ret != 0) { \
446
449
  MD_LOG("Aborted from enter_block() callback."); \
447
450
  goto abort; \
448
451
  } \
449
452
  } while(0)
450
453
 
451
- #define MD_LEAVE_BLOCK(type, arg) \
454
+ #define MD_LEAVE_BLOCK(type, arg, off) \
452
455
  do { \
453
- ret = ctx->parser.leave_block((type), (arg), ctx->userdata); \
456
+ ret = ctx->parser.leave_block((type), (arg), (off), ctx->userdata); \
454
457
  if(ret != 0) { \
455
458
  MD_LOG("Aborted from leave_block() callback."); \
456
459
  goto abort; \
457
460
  } \
458
461
  } while(0)
459
462
 
460
- #define MD_ENTER_SPAN(type, arg) \
463
+ #define MD_ENTER_SPAN(type, arg, off) \
461
464
  do { \
462
- ret = ctx->parser.enter_span((type), (arg), ctx->userdata); \
465
+ ret = ctx->parser.enter_span((type), (arg), (off), ctx->userdata); \
463
466
  if(ret != 0) { \
464
467
  MD_LOG("Aborted from enter_span() callback."); \
465
468
  goto abort; \
466
469
  } \
467
470
  } while(0)
468
471
 
469
- #define MD_LEAVE_SPAN(type, arg) \
472
+ #define MD_LEAVE_SPAN(type, arg, off) \
470
473
  do { \
471
- ret = ctx->parser.leave_span((type), (arg), ctx->userdata); \
474
+ ret = ctx->parser.leave_span((type), (arg), (off), ctx->userdata); \
472
475
  if(ret != 0) { \
473
476
  MD_LOG("Aborted from leave_span() callback."); \
474
477
  goto abort; \
@@ -4157,7 +4160,7 @@ md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines,
4157
4160
  static int
4158
4161
  md_enter_leave_span_a(MD_CTX* ctx, int enter, MD_SPANTYPE type,
4159
4162
  const CHAR* dest, SZ dest_size, int is_autolink,
4160
- const CHAR* title, SZ title_size)
4163
+ const CHAR* title, SZ title_size, MD_OFFSET off)
4161
4164
  {
4162
4165
  MD_ATTRIBUTE_BUILD href_build = { 0 };
4163
4166
  MD_ATTRIBUTE_BUILD title_build = { 0 };
@@ -4173,9 +4176,9 @@ md_enter_leave_span_a(MD_CTX* ctx, int enter, MD_SPANTYPE type,
4173
4176
  MD_CHECK(md_build_attribute(ctx, title, title_size, 0, &det.title, &title_build));
4174
4177
  det.is_autolink = is_autolink;
4175
4178
  if(enter)
4176
- MD_ENTER_SPAN(type, &det);
4179
+ MD_ENTER_SPAN(type, &det, off);
4177
4180
  else
4178
- MD_LEAVE_SPAN(type, &det);
4181
+ MD_LEAVE_SPAN(type, &det, off);
4179
4182
 
4180
4183
  abort:
4181
4184
  md_free_attribute(ctx, &href_build);
@@ -4184,7 +4187,7 @@ abort:
4184
4187
  }
4185
4188
 
4186
4189
  static int
4187
- md_enter_leave_span_wikilink(MD_CTX* ctx, int enter, const CHAR* target, SZ target_size)
4190
+ md_enter_leave_span_wikilink(MD_CTX* ctx, int enter, const CHAR* target, SZ target_size, MD_OFFSET off)
4188
4191
  {
4189
4192
  MD_ATTRIBUTE_BUILD target_build = { 0 };
4190
4193
  MD_SPAN_WIKILINK_DETAIL det;
@@ -4194,9 +4197,9 @@ md_enter_leave_span_wikilink(MD_CTX* ctx, int enter, const CHAR* target, SZ targ
4194
4197
  MD_CHECK(md_build_attribute(ctx, target, target_size, 0, &det.target, &target_build));
4195
4198
 
4196
4199
  if (enter)
4197
- MD_ENTER_SPAN(MD_SPAN_WIKILINK, &det);
4200
+ MD_ENTER_SPAN(MD_SPAN_WIKILINK, &det, off);
4198
4201
  else
4199
- MD_LEAVE_SPAN(MD_SPAN_WIKILINK, &det);
4202
+ MD_LEAVE_SPAN(MD_SPAN_WIKILINK, &det, off);
4200
4203
 
4201
4204
  abort:
4202
4205
  md_free_attribute(ctx, &target_build);
@@ -4252,10 +4255,10 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines)
4252
4255
 
4253
4256
  case '`': /* Code span. */
4254
4257
  if(mark->flags & MD_MARK_OPENER) {
4255
- MD_ENTER_SPAN(MD_SPAN_CODE, NULL);
4258
+ MD_ENTER_SPAN(MD_SPAN_CODE, NULL, mark->beg);
4256
4259
  text_type = MD_TEXT_CODE;
4257
4260
  } else {
4258
- MD_LEAVE_SPAN(MD_SPAN_CODE, NULL);
4261
+ MD_LEAVE_SPAN(MD_SPAN_CODE, NULL, mark->end);
4259
4262
  text_type = MD_TEXT_NORMAL;
4260
4263
  }
4261
4264
  break;
@@ -4264,12 +4267,12 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines)
4264
4267
  if(ctx->parser.flags & MD_FLAG_UNDERLINE) {
4265
4268
  if(mark->flags & MD_MARK_OPENER) {
4266
4269
  while(off < mark->end) {
4267
- MD_ENTER_SPAN(MD_SPAN_U, NULL);
4270
+ MD_ENTER_SPAN(MD_SPAN_U, NULL, off);
4268
4271
  off++;
4269
4272
  }
4270
4273
  } else {
4271
4274
  while(off < mark->end) {
4272
- MD_LEAVE_SPAN(MD_SPAN_U, NULL);
4275
+ MD_LEAVE_SPAN(MD_SPAN_U, NULL, off + 1);
4273
4276
  off++;
4274
4277
  }
4275
4278
  }
@@ -4280,20 +4283,20 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines)
4280
4283
  case '*': /* Emphasis, strong emphasis. */
4281
4284
  if(mark->flags & MD_MARK_OPENER) {
4282
4285
  if((mark->end - off) % 2) {
4283
- MD_ENTER_SPAN(MD_SPAN_EM, NULL);
4286
+ MD_ENTER_SPAN(MD_SPAN_EM, NULL, off);
4284
4287
  off++;
4285
4288
  }
4286
4289
  while(off + 1 < mark->end) {
4287
- MD_ENTER_SPAN(MD_SPAN_STRONG, NULL);
4290
+ MD_ENTER_SPAN(MD_SPAN_STRONG, NULL, off);
4288
4291
  off += 2;
4289
4292
  }
4290
4293
  } else {
4291
4294
  while(off + 1 < mark->end) {
4292
- MD_LEAVE_SPAN(MD_SPAN_STRONG, NULL);
4295
+ MD_LEAVE_SPAN(MD_SPAN_STRONG, NULL, off + 2);
4293
4296
  off += 2;
4294
4297
  }
4295
4298
  if((mark->end - off) % 2) {
4296
- MD_LEAVE_SPAN(MD_SPAN_EM, NULL);
4299
+ MD_LEAVE_SPAN(MD_SPAN_EM, NULL, off + 1);
4297
4300
  off++;
4298
4301
  }
4299
4302
  }
@@ -4301,17 +4304,17 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines)
4301
4304
 
4302
4305
  case '~':
4303
4306
  if(mark->flags & MD_MARK_OPENER)
4304
- MD_ENTER_SPAN(MD_SPAN_DEL, NULL);
4307
+ MD_ENTER_SPAN(MD_SPAN_DEL, NULL, mark->beg);
4305
4308
  else
4306
- MD_LEAVE_SPAN(MD_SPAN_DEL, NULL);
4309
+ MD_LEAVE_SPAN(MD_SPAN_DEL, NULL, mark->end);
4307
4310
  break;
4308
4311
 
4309
4312
  case '$':
4310
4313
  if(mark->flags & MD_MARK_OPENER) {
4311
- MD_ENTER_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL);
4314
+ MD_ENTER_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL, off);
4312
4315
  text_type = MD_TEXT_LATEXMATH;
4313
4316
  } else {
4314
- MD_LEAVE_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL);
4317
+ MD_LEAVE_SPAN((mark->end - off) % 2 ? MD_SPAN_LATEXMATH : MD_SPAN_LATEXMATH_DISPLAY, NULL, off + ((mark->end - off) % 2 ? 1 : 2));
4315
4318
  text_type = MD_TEXT_NORMAL;
4316
4319
  }
4317
4320
  break;
@@ -4339,7 +4342,8 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines)
4339
4342
 
4340
4343
  MD_CHECK(md_enter_leave_span_wikilink(ctx, (mark->ch != ']'),
4341
4344
  has_label ? STR(opener->beg+2) : STR(opener->end),
4342
- target_sz));
4345
+ target_sz,
4346
+ (mark->ch != ']') ? opener->beg : closer->end));
4343
4347
 
4344
4348
  break;
4345
4349
  }
@@ -4353,7 +4357,8 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines)
4353
4357
  (opener->ch == '!' ? MD_SPAN_IMG : MD_SPAN_A),
4354
4358
  STR(dest_mark->beg), dest_mark->end - dest_mark->beg, FALSE,
4355
4359
  md_mark_get_ptr(ctx, (int)(title_mark - ctx->marks)),
4356
- title_mark->prev));
4360
+ title_mark->prev,
4361
+ (mark->ch != ']') ? opener->beg : closer->end));
4357
4362
 
4358
4363
  /* link/image closer may span multiple lines. */
4359
4364
  if(mark->ch == ']') {
@@ -4409,7 +4414,8 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines)
4409
4414
 
4410
4415
  if(closer->flags & MD_MARK_VALIDPERMISSIVEAUTOLINK)
4411
4416
  MD_CHECK(md_enter_leave_span_a(ctx, (mark->flags & MD_MARK_OPENER),
4412
- MD_SPAN_A, dest, dest_size, TRUE, NULL, 0));
4417
+ MD_SPAN_A, dest, dest_size, TRUE, NULL, 0,
4418
+ (mark->flags & MD_MARK_OPENER) ? mark->beg : mark->end));
4413
4419
  break;
4414
4420
  }
4415
4421
 
@@ -4544,9 +4550,9 @@ md_process_table_cell(MD_CTX* ctx, MD_BLOCKTYPE cell_type, MD_ALIGN align, OFF b
4544
4550
  line.beg = beg;
4545
4551
  line.end = end;
4546
4552
 
4547
- MD_ENTER_BLOCK(cell_type, &det);
4553
+ MD_ENTER_BLOCK(cell_type, &det, beg);
4548
4554
  MD_CHECK(md_process_normal_block_contents(ctx, &line, 1));
4549
- MD_LEAVE_BLOCK(cell_type, &det);
4555
+ MD_LEAVE_BLOCK(cell_type, &det, end);
4550
4556
 
4551
4557
  abort:
4552
4558
  return ret;
@@ -4586,7 +4592,7 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end,
4586
4592
  pipe_offs[j++] = end+1;
4587
4593
 
4588
4594
  /* Process cells. */
4589
- MD_ENTER_BLOCK(MD_BLOCK_TR, NULL);
4595
+ MD_ENTER_BLOCK(MD_BLOCK_TR, NULL, beg);
4590
4596
  k = 0;
4591
4597
  for(i = 0; i < j-1 && k < col_count; i++) {
4592
4598
  if(pipe_offs[i] < pipe_offs[i+1]-1)
@@ -4596,7 +4602,7 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end,
4596
4602
  * too few of them. */
4597
4603
  while(k < col_count)
4598
4604
  MD_CHECK(md_process_table_cell(ctx, cell_type, align[k++], 0, 0));
4599
- MD_LEAVE_BLOCK(MD_BLOCK_TR, NULL);
4605
+ MD_LEAVE_BLOCK(MD_BLOCK_TR, NULL, end);
4600
4606
 
4601
4607
  abort:
4602
4608
  free(pipe_offs);
@@ -4627,18 +4633,18 @@ md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines
4627
4633
 
4628
4634
  md_analyze_table_alignment(ctx, lines[1].beg, lines[1].end, align, col_count);
4629
4635
 
4630
- MD_ENTER_BLOCK(MD_BLOCK_THEAD, NULL);
4636
+ MD_ENTER_BLOCK(MD_BLOCK_THEAD, NULL, lines[0].beg);
4631
4637
  MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TH,
4632
4638
  lines[0].beg, lines[0].end, align, col_count));
4633
- MD_LEAVE_BLOCK(MD_BLOCK_THEAD, NULL);
4639
+ MD_LEAVE_BLOCK(MD_BLOCK_THEAD, NULL, lines[1].end);
4634
4640
 
4635
4641
  if(n_lines > 2) {
4636
- MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL);
4642
+ MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL, lines[2].beg);
4637
4643
  for(line_index = 2; line_index < n_lines; line_index++) {
4638
4644
  MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TD,
4639
4645
  lines[line_index].beg, lines[line_index].end, align, col_count));
4640
4646
  }
4641
- MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL);
4647
+ MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL, lines[n_lines-1].end);
4642
4648
  }
4643
4649
 
4644
4650
  abort:
@@ -4673,6 +4679,8 @@ struct MD_BLOCK_tag {
4673
4679
  * MD_BLOCK_OL: Start item number.
4674
4680
  */
4675
4681
  MD_SIZE n_lines;
4682
+ OFF beg;
4683
+ OFF end;
4676
4684
  };
4677
4685
 
4678
4686
  struct MD_CONTAINER_tag {
@@ -4684,6 +4692,7 @@ struct MD_CONTAINER_tag {
4684
4692
  unsigned contents_indent;
4685
4693
  OFF block_byte_off;
4686
4694
  OFF task_mark_off;
4695
+ OFF source_beg;
4687
4696
  };
4688
4697
 
4689
4698
 
@@ -4848,7 +4857,7 @@ md_process_leaf_block(MD_CTX* ctx, const MD_BLOCK* block)
4848
4857
  }
4849
4858
 
4850
4859
  if(!is_in_tight_list || block->type != MD_BLOCK_P)
4851
- MD_ENTER_BLOCK(block->type, (void*) &det);
4860
+ MD_ENTER_BLOCK(block->type, (void*) &det, block->beg);
4852
4861
 
4853
4862
  /* Process the block contents accordingly to is type. */
4854
4863
  switch(block->type) {
@@ -4878,7 +4887,7 @@ md_process_leaf_block(MD_CTX* ctx, const MD_BLOCK* block)
4878
4887
  }
4879
4888
 
4880
4889
  if(!is_in_tight_list || block->type != MD_BLOCK_P)
4881
- MD_LEAVE_BLOCK(block->type, (void*) &det);
4890
+ MD_LEAVE_BLOCK(block->type, (void*) &det, block->end);
4882
4891
 
4883
4892
  abort:
4884
4893
  if(clean_fence_code_detail) {
@@ -4933,14 +4942,14 @@ md_process_all_blocks(MD_CTX* ctx)
4933
4942
 
4934
4943
  if(block->flags & MD_BLOCK_CONTAINER) {
4935
4944
  if(block->flags & MD_BLOCK_CONTAINER_CLOSER) {
4936
- MD_LEAVE_BLOCK(block->type, &det);
4945
+ MD_LEAVE_BLOCK(block->type, &det, block->end);
4937
4946
 
4938
4947
  if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL || block->type == MD_BLOCK_QUOTE)
4939
4948
  ctx->n_containers--;
4940
4949
  }
4941
4950
 
4942
4951
  if(block->flags & MD_BLOCK_CONTAINER_OPENER) {
4943
- MD_ENTER_BLOCK(block->type, &det);
4952
+ MD_ENTER_BLOCK(block->type, &det, block->beg);
4944
4953
 
4945
4954
  if(block->type == MD_BLOCK_UL || block->type == MD_BLOCK_OL) {
4946
4955
  ctx->containers[ctx->n_containers].is_loose = (block->flags & MD_BLOCK_LOOSE_LIST);
@@ -5052,6 +5061,8 @@ md_start_new_block(MD_CTX* ctx, const MD_LINE_ANALYSIS* line)
5052
5061
  block->flags = 0;
5053
5062
  block->data = line->data;
5054
5063
  block->n_lines = 0;
5064
+ block->beg = line->beg;
5065
+ block->end = line->end;
5055
5066
 
5056
5067
  ctx->current_block = block;
5057
5068
  return 0;
@@ -5102,6 +5113,7 @@ md_consume_link_reference_definitions(MD_CTX* ctx)
5102
5113
  memmove(lines, lines + n, (n_lines - n) * sizeof(MD_LINE));
5103
5114
  ctx->current_block->n_lines -= n;
5104
5115
  ctx->n_block_bytes -= n * sizeof(MD_LINE);
5116
+ ctx->current_block->beg = lines[0].beg;
5105
5117
  }
5106
5118
  }
5107
5119
 
@@ -5137,6 +5149,7 @@ md_end_current_block(MD_CTX* ctx)
5137
5149
  /* Get rid of the underline. */
5138
5150
  ctx->current_block->n_lines--;
5139
5151
  ctx->n_block_bytes -= sizeof(MD_LINE);
5152
+ ctx->current_block->end = ((MD_LINE*) (ctx->current_block + 1))[ctx->current_block->n_lines - 1].end;
5140
5153
  } else {
5141
5154
  /* Only the underline has left after eating the ref. defs.
5142
5155
  * Keep the line as beginning of a new ordinary paragraph. */
@@ -5178,13 +5191,14 @@ md_add_line_into_current_block(MD_CTX* ctx, const MD_LINE_ANALYSIS* analysis)
5178
5191
  line->end = analysis->end;
5179
5192
  }
5180
5193
  ctx->current_block->n_lines++;
5194
+ ctx->current_block->end = analysis->end;
5181
5195
 
5182
5196
  return 0;
5183
5197
  }
5184
5198
 
5185
5199
  static int
5186
5200
  md_push_container_bytes(MD_CTX* ctx, MD_BLOCKTYPE type, unsigned start,
5187
- unsigned data, unsigned flags)
5201
+ unsigned data, unsigned flags, OFF off)
5188
5202
  {
5189
5203
  MD_BLOCK* block;
5190
5204
  int ret = 0;
@@ -5199,6 +5213,13 @@ md_push_container_bytes(MD_CTX* ctx, MD_BLOCKTYPE type, unsigned start,
5199
5213
  block->flags = flags;
5200
5214
  block->data = data;
5201
5215
  block->n_lines = start;
5216
+ if (flags & MD_BLOCK_CONTAINER_OPENER) {
5217
+ block->beg = off;
5218
+ block->end = 0;
5219
+ } else {
5220
+ block->beg = 0;
5221
+ block->end = off;
5222
+ }
5202
5223
 
5203
5224
  abort:
5204
5225
  return ret;
@@ -5674,15 +5695,15 @@ md_enter_child_containers(MD_CTX* ctx, int n_children)
5674
5695
 
5675
5696
  MD_CHECK(md_push_container_bytes(ctx,
5676
5697
  (is_ordered_list ? MD_BLOCK_OL : MD_BLOCK_UL),
5677
- c->start, c->ch, MD_BLOCK_CONTAINER_OPENER));
5698
+ c->start, c->ch, MD_BLOCK_CONTAINER_OPENER, c->source_beg));
5678
5699
  MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI,
5679
5700
  c->task_mark_off,
5680
5701
  (c->is_task ? CH(c->task_mark_off) : 0),
5681
- MD_BLOCK_CONTAINER_OPENER));
5702
+ MD_BLOCK_CONTAINER_OPENER, c->source_beg));
5682
5703
  break;
5683
5704
 
5684
5705
  case _T('>'):
5685
- MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, 0, 0, MD_BLOCK_CONTAINER_OPENER));
5706
+ MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, 0, 0, MD_BLOCK_CONTAINER_OPENER, c->source_beg));
5686
5707
  break;
5687
5708
 
5688
5709
  default:
@@ -5696,7 +5717,7 @@ abort:
5696
5717
  }
5697
5718
 
5698
5719
  static int
5699
- md_leave_child_containers(MD_CTX* ctx, int n_keep)
5720
+ md_leave_child_containers(MD_CTX* ctx, int n_keep, OFF off)
5700
5721
  {
5701
5722
  int ret = 0;
5702
5723
 
@@ -5715,15 +5736,15 @@ md_leave_child_containers(MD_CTX* ctx, int n_keep)
5715
5736
  case _T('*'):
5716
5737
  MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI,
5717
5738
  c->task_mark_off, (c->is_task ? CH(c->task_mark_off) : 0),
5718
- MD_BLOCK_CONTAINER_CLOSER));
5739
+ MD_BLOCK_CONTAINER_CLOSER, off));
5719
5740
  MD_CHECK(md_push_container_bytes(ctx,
5720
5741
  (is_ordered_list ? MD_BLOCK_OL : MD_BLOCK_UL), 0,
5721
- c->ch, MD_BLOCK_CONTAINER_CLOSER));
5742
+ c->ch, MD_BLOCK_CONTAINER_CLOSER, off));
5722
5743
  break;
5723
5744
 
5724
5745
  case _T('>'):
5725
5746
  MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_QUOTE, 0,
5726
- 0, MD_BLOCK_CONTAINER_CLOSER));
5747
+ 0, MD_BLOCK_CONTAINER_CLOSER, off));
5727
5748
  break;
5728
5749
 
5729
5750
  default:
@@ -6032,6 +6053,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
6032
6053
  if(md_is_container_mark(ctx, line->indent, off, &tmp, &container) &&
6033
6054
  md_is_container_compatible(&ctx->containers[n_parents], &container))
6034
6055
  {
6056
+ container.source_beg = tmp;
6035
6057
  pivot_line = &md_dummy_blank_line;
6036
6058
 
6037
6059
  off = tmp;
@@ -6073,6 +6095,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
6073
6095
  if(line->indent < ctx->code_indent_offset &&
6074
6096
  md_is_container_mark(ctx, line->indent, off, &off, &container))
6075
6097
  {
6098
+ container.source_beg = off;
6076
6099
  if(pivot_line->type == MD_LINE_TEXT && n_parents == ctx->n_containers &&
6077
6100
  (off >= ctx->size || ISNEWLINE(off)) && container.ch != _T('>'))
6078
6101
  {
@@ -6104,7 +6127,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
6104
6127
  pivot_line = &md_dummy_blank_line;
6105
6128
 
6106
6129
  if(n_children == 0)
6107
- MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers));
6130
+ MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers, pivot_line->end));
6108
6131
 
6109
6132
  n_children++;
6110
6133
  MD_CHECK(md_push_container(ctx, &container));
@@ -6283,7 +6306,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
6283
6306
 
6284
6307
  /* Leave any containers we are not part of anymore. */
6285
6308
  if(n_children == 0 && n_parents + n_brothers < ctx->n_containers)
6286
- MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers));
6309
+ MD_CHECK(md_leave_child_containers(ctx, n_parents + n_brothers, pivot_line->end));
6287
6310
 
6288
6311
  /* Enter any container we found a mark for. */
6289
6312
  if(n_brothers > 0) {
@@ -6291,11 +6314,11 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end,
6291
6314
  MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI,
6292
6315
  ctx->containers[n_parents].task_mark_off,
6293
6316
  (ctx->containers[n_parents].is_task ? CH(ctx->containers[n_parents].task_mark_off) : 0),
6294
- MD_BLOCK_CONTAINER_CLOSER));
6317
+ MD_BLOCK_CONTAINER_CLOSER, container.source_beg));
6295
6318
  MD_CHECK(md_push_container_bytes(ctx, MD_BLOCK_LI,
6296
6319
  container.task_mark_off,
6297
6320
  (container.is_task ? CH(container.task_mark_off) : 0),
6298
- MD_BLOCK_CONTAINER_OPENER));
6321
+ MD_BLOCK_CONTAINER_OPENER, container.source_beg));
6299
6322
  ctx->containers[n_parents].is_task = container.is_task;
6300
6323
  ctx->containers[n_parents].task_mark_off = container.task_mark_off;
6301
6324
  }
@@ -6392,7 +6415,7 @@ md_process_doc(MD_CTX *ctx)
6392
6415
  OFF off = 0;
6393
6416
  int ret = 0;
6394
6417
 
6395
- MD_ENTER_BLOCK(MD_BLOCK_DOC, NULL);
6418
+ MD_ENTER_BLOCK(MD_BLOCK_DOC, NULL, 0);
6396
6419
 
6397
6420
  while(off < ctx->size) {
6398
6421
  if(line == pivot_line)
@@ -6407,10 +6430,10 @@ md_process_doc(MD_CTX *ctx)
6407
6430
  MD_CHECK(md_build_ref_def_hashtable(ctx));
6408
6431
 
6409
6432
  /* Process all blocks. */
6410
- MD_CHECK(md_leave_child_containers(ctx, 0));
6433
+ MD_CHECK(md_leave_child_containers(ctx, 0, ctx->size));
6411
6434
  MD_CHECK(md_process_all_blocks(ctx));
6412
6435
 
6413
- MD_LEAVE_BLOCK(MD_BLOCK_DOC, NULL);
6436
+ MD_LEAVE_BLOCK(MD_BLOCK_DOC, NULL, ctx->size);
6414
6437
 
6415
6438
  abort:
6416
6439
 
package/cpp/md4c/md4c.h CHANGED
@@ -360,11 +360,11 @@ typedef struct MD_PARSER {
360
360
  * Any rendering callback may abort further parsing of the document by
361
361
  * returning non-zero.
362
362
  */
363
- int (*enter_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
364
- int (*leave_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
363
+ int (*enter_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, MD_OFFSET /*off*/, void* /*userdata*/);
364
+ int (*leave_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, MD_OFFSET /*off*/, void* /*userdata*/);
365
365
 
366
- int (*enter_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
367
- int (*leave_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
366
+ int (*enter_span)(MD_SPANTYPE /*type*/, void* /*detail*/, MD_OFFSET /*off*/, void* /*userdata*/);
367
+ int (*leave_span)(MD_SPANTYPE /*type*/, void* /*detail*/, MD_OFFSET /*off*/, void* /*userdata*/);
368
368
 
369
369
  int (*text)(MD_TEXTTYPE /*type*/, const MD_CHAR* /*text*/, MD_SIZE /*size*/, void* /*userdata*/);
370
370
 
@@ -378,6 +378,9 @@ typedef struct MD_PARSER {
378
378
  void (*debug_log)(const char* /*msg*/, void* /*userdata*/);
379
379
 
380
380
  /* Reserved. Set to NULL.
381
+ *
382
+ * Note: used to be syntax callback, now reused for something else or just kept for ABI?
383
+ * We don't care about ABI much here since it's static linking for RN.
381
384
  */
382
385
  void (*syntax)(void);
383
386
  } MD_PARSER;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getTextContent = exports.MarkdownParserModule = void 0;
6
+ exports.getTextContent = exports.getFlattenedText = exports.MarkdownParserModule = void 0;
7
7
  exports.parseMarkdown = parseMarkdown;
8
8
  exports.parseMarkdownWithOptions = parseMarkdownWithOptions;
9
9
  var _reactNativeNitroModules = require("react-native-nitro-modules");
@@ -57,5 +57,42 @@ const getTextContent = node => {
57
57
  if (node.content) return node.content;
58
58
  return node.children?.map(getTextContent).join("") ?? "";
59
59
  };
60
+
61
+ /**
62
+ * recursively extracts plain text from the AST, normalizing spacing.
63
+ */
60
64
  exports.getTextContent = getTextContent;
65
+ const getFlattenedText = node => {
66
+ if (node.type === "text" || node.type === "code_inline" || node.type === "math_inline" || node.type === "html_inline") {
67
+ return node.content ?? "";
68
+ }
69
+ if (node.type === "code_block" || node.type === "math_block" || node.type === "html_block") {
70
+ return (node.content ?? "").trim() + "\n\n";
71
+ }
72
+ if (node.type === "line_break") return "\n";
73
+ if (node.type === "soft_break") return " ";
74
+ if (node.type === "horizontal_rule") return "---\n\n";
75
+ if (node.type === "image") {
76
+ return node.alt || node.title || "";
77
+ }
78
+ const childrenText = node.children?.map(getFlattenedText).join("") ?? "";
79
+ switch (node.type) {
80
+ case "paragraph":
81
+ case "heading":
82
+ case "blockquote":
83
+ return childrenText.trim() + "\n\n";
84
+ case "list_item":
85
+ case "task_list_item":
86
+ return childrenText.trim() + "\n";
87
+ case "list":
88
+ return childrenText + "\n";
89
+ case "table_row":
90
+ return childrenText + "\n";
91
+ case "table_cell":
92
+ return childrenText + " | ";
93
+ default:
94
+ return childrenText;
95
+ }
96
+ };
97
+ exports.getFlattenedText = getFlattenedText;
61
98
  //# sourceMappingURL=headless.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNativeNitroModules","require","MarkdownParserModule","exports","NitroModules","createHybridObject","parseMarkdown","text","jsonStr","parse","JSON","parseMarkdownWithOptions","options","parseWithOptions","getTextContent","node","content","children","map","join"],"sourceRoot":"../../src","sources":["headless.ts"],"mappings":";;;;;;;;AAYA,IAAAA,wBAAA,GAAAC,OAAA;AAZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;;AAyDO,MAAMC,oBAAoB,GAAAC,OAAA,CAAAD,oBAAA,GAC/BE,qCAAY,CAACC,kBAAkB,CAAiB,gBAAgB,CAAC;;AAEnE;AACA;AACA;AACA;AACA;AACO,SAASC,aAAaA,CAACC,IAAY,EAAgB;EACxD,MAAMC,OAAO,GAAGN,oBAAoB,CAACO,KAAK,CAACF,IAAI,CAAC;EAChD,OAAOG,IAAI,CAACD,KAAK,CAACD,OAAO,CAAC;AAC5B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,wBAAwBA,CACtCJ,IAAY,EACZK,OAAsB,EACR;EACd,MAAMJ,OAAO,GAAGN,oBAAoB,CAACW,gBAAgB,CAACN,IAAI,EAAEK,OAAO,CAAC;EACpE,OAAOF,IAAI,CAACD,KAAK,CAACD,OAAO,CAAC;AAC5B;AAIA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMM,cAAc,GAAIC,IAAkB,IAAa;EAC5D,IAAIA,IAAI,CAACC,OAAO,EAAE,OAAOD,IAAI,CAACC,OAAO;EACrC,OAAOD,IAAI,CAACE,QAAQ,EAAEC,GAAG,CAACJ,cAAc,CAAC,CAACK,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE;AAC1D,CAAC;AAAChB,OAAA,CAAAW,cAAA,GAAAA,cAAA","ignoreList":[]}
1
+ {"version":3,"names":["_reactNativeNitroModules","require","MarkdownParserModule","exports","NitroModules","createHybridObject","parseMarkdown","text","jsonStr","parse","JSON","parseMarkdownWithOptions","options","parseWithOptions","getTextContent","node","content","children","map","join","getFlattenedText","type","trim","alt","title","childrenText"],"sourceRoot":"../../src","sources":["headless.ts"],"mappings":"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","ignoreList":[]}
@@ -27,19 +27,34 @@ const Markdown = ({
27
27
  theme: userTheme,
28
28
  styles: nodeStyles,
29
29
  stylingStrategy = "opinionated",
30
- style
30
+ style,
31
+ onParsingInProgress,
32
+ onParseComplete
31
33
  }) => {
32
34
  const ast = (0, _react.useMemo)(() => {
33
35
  try {
36
+ if (onParsingInProgress) {
37
+ onParsingInProgress();
38
+ }
39
+ let result;
34
40
  if (options) {
35
- return (0, _headless.parseMarkdownWithOptions)(children, options);
41
+ result = (0, _headless.parseMarkdownWithOptions)(children, options);
42
+ } else {
43
+ result = (0, _headless.parseMarkdown)(children);
44
+ }
45
+ if (onParseComplete) {
46
+ onParseComplete({
47
+ raw: children,
48
+ ast: result,
49
+ text: (0, _headless.getFlattenedText)(result)
50
+ });
36
51
  }
37
- return (0, _headless.parseMarkdown)(children);
52
+ return result;
38
53
  } catch (error) {
39
54
  console.error("Failed to parse markdown:", error);
40
55
  return null;
41
56
  }
42
- }, [children, options]);
57
+ }, [children, options, onParsingInProgress, onParseComplete]);
43
58
  const theme = (0, _react.useMemo)(() => {
44
59
  const base = stylingStrategy === "minimal" ? _theme.minimalMarkdownTheme : _theme.defaultMarkdownTheme;
45
60
  return (0, _theme.mergeThemes)(base, userTheme);
@@ -153,36 +168,29 @@ const NodeRenderer = ({
153
168
  };
154
169
  const enhancedProps = {
155
170
  ...baseProps,
156
- // Heading
157
171
  ...(node.type === "heading" && {
158
172
  level: node.level ?? 1
159
173
  }),
160
- // Link
161
174
  ...(node.type === "link" && {
162
175
  href: node.href ?? "",
163
176
  title: node.title
164
177
  }),
165
- // Image
166
178
  ...(node.type === "image" && {
167
179
  url: node.href ?? "",
168
180
  alt: node.alt,
169
181
  title: node.title
170
182
  }),
171
- // Code block
172
183
  ...(node.type === "code_block" && {
173
184
  content: (0, _headless.getTextContent)(node),
174
185
  language: node.language
175
186
  }),
176
- // Inline code
177
187
  ...(node.type === "code_inline" && {
178
188
  content: node.content ?? ""
179
189
  }),
180
- // List
181
190
  ...(node.type === "list" && {
182
191
  ordered: node.ordered ?? false,
183
192
  start: node.start
184
193
  }),
185
- // Task list item
186
194
  ...(node.type === "task_list_item" && {
187
195
  checked: node.checked ?? false
188
196
  })