uniorg-parse 0.4.3 → 0.5.0

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.
package/lib/parser.js CHANGED
@@ -1,15 +1,9 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.parse = void 0;
7
- const vfile_1 = __importDefault(require("vfile"));
8
- const unist_builder_1 = __importDefault(require("unist-builder"));
9
- const entities_1 = require("./entities");
10
- const utils_1 = require("./utils");
11
- const parse_options_1 = require("./parse-options");
12
- const reader_1 = require("./reader");
1
+ import { VFile } from 'vfile';
2
+ import { u } from 'unist-builder';
3
+ import { getOrgEntity } from './entities.js';
4
+ import { restrictionFor, greaterElements, unescapeCodeInString, escapeRegExp, OrgRegexUtils, } from './utils.js';
5
+ import { defaultOptions } from './parse-options.js';
6
+ import { Reader } from './reader.js';
13
7
  /*
14
8
  (defun rasen/org-debug ()
15
9
  "Show org AST for the current buffer."
@@ -50,20 +44,19 @@ var ParseMode;
50
44
  /** Default parsing mode. */
51
45
  ParseMode[ParseMode["Default"] = 7] = "Default";
52
46
  })(ParseMode || (ParseMode = {}));
53
- function parse(file, options) {
54
- return new Parser(vfile_1.default(file), options).parse();
47
+ export function parse(file, options) {
48
+ return new Parser(new VFile(file), options).parse();
55
49
  }
56
- exports.parse = parse;
57
50
  class Parser {
58
51
  constructor(file, options = {}) {
59
- this.r = new reader_1.Reader(file);
60
- this.options = Object.assign(Object.assign({}, parse_options_1.defaultOptions), options);
61
- this.re = new utils_1.OrgRegexUtils(this.options);
52
+ this.r = new Reader(file);
53
+ this.options = { ...defaultOptions, ...options };
54
+ this.re = new OrgRegexUtils(this.options);
62
55
  }
63
56
  parse() {
64
57
  this.parseEmptyLines();
65
58
  const children = this.parseElements(ParseMode.TopComment);
66
- return unist_builder_1.default('org-data', { contentsBegin: 0, contentsEnd: this.r.endOffset() }, children);
59
+ return u('org-data', { contentsBegin: 0, contentsEnd: this.r.endOffset() }, children);
67
60
  }
68
61
  // General parsing structure
69
62
  parseElements(mode, structure) {
@@ -78,25 +71,31 @@ class Parser {
78
71
  prevOffset = offset;
79
72
  const element = this.parseElement(mode, structure);
80
73
  const type = element.type;
74
+ // @ts-expect-error contentsBegin is not defined for "literals"
81
75
  const cbeg = element.contentsBegin;
76
+ // @ts-expect-error contentsBegin is not defined for "literals"
82
77
  const cend = element.contentsEnd;
83
78
  if (cbeg === undefined || cend === undefined) {
84
79
  // do nothing
85
80
  }
86
- else if (utils_1.greaterElements.has(type)) {
87
- const elementStructure = element.structure;
81
+ else if (greaterElements.has(type)) {
88
82
  this.r.narrow(cbeg, cend);
89
- appendChildren(element, this.parseElements(Parser.nextMode(mode, type, true), structure !== null && structure !== void 0 ? structure : elementStructure));
83
+ appendChildren(element, this.parseElements(Parser.nextMode(mode, type, true), element.type === 'plain-list' || element.type === 'list-item'
84
+ ? // @ts-expect-error Property 'structure' does not exist on type 'OrgData'
85
+ element.structure
86
+ : undefined));
90
87
  this.r.widen();
91
88
  // Delete structure from lists. It’s only here to facilitate
92
89
  // parsing and should not be exposed to the user.
93
- if (elementStructure) {
90
+ // @ts-expect-error Property 'structure' does not exist on type 'OrgData'
91
+ if (element.structure) {
92
+ // @ts-expect-error Property 'structure' does not exist on type 'OrgData'
94
93
  delete element.structure;
95
94
  }
96
95
  }
97
96
  else {
98
97
  this.r.narrow(cbeg, cend);
99
- appendChildren(element, this.parseObjects(utils_1.restrictionFor(element.type)));
98
+ appendChildren(element, this.parseObjects(restrictionFor(element.type)));
100
99
  this.r.widen();
101
100
  }
102
101
  elements.push(element);
@@ -134,7 +133,6 @@ class Parser {
134
133
  return ParseMode.Default;
135
134
  }
136
135
  parseElement(mode, structure) {
137
- var _a, _b;
138
136
  // List Item.
139
137
  if (mode === ParseMode.ListItem)
140
138
  return this.parseListItem(structure);
@@ -166,7 +164,7 @@ class Parser {
166
164
  // && TODO: check previous line is headline
167
165
  ((mode === ParseMode.PropertyDrawer || mode === ParseMode.TopComment) &&
168
166
  !this.r.lookingAt(/\s*$/m))) &&
169
- this.r.lookingAt(/^[ \t]*:PROPERTIES:[ \t]*\n(?:[ \t]*:\S+:(?: .*)?[ \t]*\n)*?[ \t]*:END:[ \t]*$/m)) {
167
+ this.r.lookingAt(/^[ \t]*:PROPERTIES:[ \t]*\n(?:[ \t]*:\S+:(?: .*)?[ \t]*\n)*?[ \t]*:END:[ \t]*$/im)) {
170
168
  return this.parsePropertyDrawer();
171
169
  }
172
170
  // When not at beginning of line, point is at the beginning of an
@@ -255,7 +253,7 @@ class Parser {
255
253
  const offset = this.r.offset();
256
254
  this.r.advance(this.r.line());
257
255
  const nextLineOffset = this.r.offset();
258
- const firstNonTable = (_b = (_a = this.r.match(/^[ \t]*($|[^|])/m)) === null || _a === void 0 ? void 0 : _a.index) !== null && _b !== void 0 ? _b : null;
256
+ const firstNonTable = this.r.match(/^[ \t]*($|[^|])/m)?.index ?? null;
259
257
  this.r.advance(firstNonTable);
260
258
  const isTable = this.r.offset() > nextLineOffset && this.r.lookingAt(ruleRe);
261
259
  this.r.resetOffset(offset);
@@ -295,13 +293,15 @@ class Parser {
295
293
  if (objectBegin !== prevEnd) {
296
294
  // parse text before object
297
295
  const value = this.r.substring(prevEnd, objectBegin);
298
- objects.push(unist_builder_1.default('text', { value }));
296
+ objects.push(u('text', { value }));
299
297
  }
298
+ // @ts-expect-error contentsBegin is not defined for "literals"
300
299
  const cbeg = o.contentsBegin;
300
+ // @ts-expect-error contentsBegin is not defined for "literals"
301
301
  const cend = o.contentsEnd;
302
302
  if (cbeg !== undefined && cend !== undefined) {
303
303
  this.r.narrow(cbeg, cend);
304
- appendChildren(o, this.parseObjects(utils_1.restrictionFor(o.type)));
304
+ appendChildren(o, this.parseObjects(restrictionFor(o.type)));
305
305
  this.r.widen();
306
306
  }
307
307
  objects.push(o);
@@ -312,7 +312,7 @@ class Parser {
312
312
  const text = this.r.rest();
313
313
  this.r.advance(text.length);
314
314
  if (text.trim().length) {
315
- objects.push(unist_builder_1.default('text', { value: text }));
315
+ objects.push(u('text', { value: text }));
316
316
  }
317
317
  return objects;
318
318
  }
@@ -467,26 +467,25 @@ class Parser {
467
467
  ? this.r.offset() + endOfSubtree.index
468
468
  : this.r.endOffset();
469
469
  this.r.resetOffset(contentsEnd);
470
- return unist_builder_1.default('section', { contentsBegin, contentsEnd }, []);
470
+ return u('section', { contentsBegin, contentsEnd }, []);
471
471
  }
472
472
  parseHeadline() {
473
- var _a, _b, _c;
474
473
  const begin = this.r.offset();
475
474
  this.r.advance(this.r.line());
476
475
  this.r.narrow(begin, this.r.offset());
477
476
  const stars = this.r.advance(this.r.forceLookingAt(/^(\*+)[ \t]+/));
478
477
  const level = stars[1].length;
479
478
  const todoM = this.r.advance(this.r.lookingAt(new RegExp('^' + this.options.todoKeywords.join('|'))));
480
- const todoKeyword = (_a = todoM === null || todoM === void 0 ? void 0 : todoM[0]) !== null && _a !== void 0 ? _a : null;
479
+ const todoKeyword = todoM?.[0] ?? null;
481
480
  this.r.advance(this.r.lookingAt(/^[ \t]*/));
482
481
  const priorityM = this.r.advance(this.r.lookingAt(/^\[#.\]/));
483
- const priority = (_b = priorityM === null || priorityM === void 0 ? void 0 : priorityM[0][2]) !== null && _b !== void 0 ? _b : null;
482
+ const priority = priorityM?.[0][2] ?? null;
484
483
  this.r.advance(this.r.lookingAt(/^[ \t]*/));
485
484
  const commented = !!this.r.advance(this.r.lookingAt(/^COMMENT/));
486
485
  this.r.advance(this.r.lookingAt(/^[ \t]*/));
487
486
  const titleStart = this.r.offset();
488
487
  const tagsM = this.r.lookingAt(/^(.*?)[ \t]+:([\w@#%:]+):[ \t]*$/m);
489
- const tags = (_c = tagsM === null || tagsM === void 0 ? void 0 : tagsM[2].split(':')) !== null && _c !== void 0 ? _c : [];
488
+ const tags = tagsM?.[2].split(':') ?? [];
490
489
  const titleEnd = tagsM
491
490
  ? titleStart + tagsM.index + tagsM[1].length
492
491
  : titleStart + this.r.forceLookingAt(/.*/)[0].length;
@@ -496,7 +495,7 @@ class Parser {
496
495
  // Reset line restriction.
497
496
  this.r.widen();
498
497
  this.parseEmptyLines();
499
- return unist_builder_1.default('headline', {
498
+ return u('headline', {
500
499
  level,
501
500
  todoKeyword,
502
501
  priority,
@@ -530,17 +529,17 @@ class Parser {
530
529
  this.r.widen();
531
530
  this.r.advance(this.r.line());
532
531
  this.parseEmptyLines();
533
- return unist_builder_1.default('planning', { scheduled, deadline, closed });
532
+ return u('planning', { scheduled, deadline, closed });
534
533
  }
535
534
  parsePropertyDrawer() {
536
535
  this.r.advance(this.r.line());
537
536
  const contentsBegin = this.r.offset();
538
- const endM = this.r.forceMatch(/^[ \t]*:END:[ \t]*$/m);
537
+ const endM = this.r.forceMatch(/^[ \t]*:END:[ \t]*$/im);
539
538
  this.r.advance(endM.index);
540
539
  const contentsEnd = this.r.offset();
541
540
  this.r.advance(this.r.line());
542
541
  this.parseEmptyLines();
543
- return unist_builder_1.default('property-drawer', { contentsBegin, contentsEnd }, []);
542
+ return u('property-drawer', { contentsBegin, contentsEnd }, []);
544
543
  }
545
544
  parseBlock(type, pattern, affiliated) {
546
545
  const endM = this.r.match(new RegExp(`^[ \\t]*#\\+end_${pattern}[ \\t]*$`, 'im'));
@@ -555,7 +554,7 @@ class Parser {
555
554
  this.r.advance(this.r.line());
556
555
  this.parseEmptyLines();
557
556
  const _end = this.r.offset();
558
- return unist_builder_1.default(type, { affiliated, contentsBegin, contentsEnd }, []);
557
+ return u(type, { affiliated, contentsBegin, contentsEnd }, []);
559
558
  }
560
559
  parseComment() {
561
560
  let valueLines = [];
@@ -571,7 +570,7 @@ class Parser {
571
570
  if (value[value.length - 1] === '\n') {
572
571
  value = value.substring(0, value.length - 1);
573
572
  }
574
- return unist_builder_1.default('comment', { value: value });
573
+ return u('comment', { value: value });
575
574
  }
576
575
  parseFixedWidth(affiliated) {
577
576
  let valueLines = [];
@@ -583,7 +582,7 @@ class Parser {
583
582
  valueLines.push(m[1]);
584
583
  }
585
584
  const value = valueLines.join('\n');
586
- return unist_builder_1.default('fixed-width', { affiliated, value });
585
+ return u('fixed-width', { affiliated, value });
587
586
  }
588
587
  parseCommentBlock(affiliated) {
589
588
  const comment = this.parseBlock('comment-block', 'comment', affiliated);
@@ -592,7 +591,7 @@ class Parser {
592
591
  return comment;
593
592
  }
594
593
  const value = this.r.substring(comment.contentsBegin, comment.contentsEnd);
595
- return unist_builder_1.default('comment-block', { affiliated, value });
594
+ return u('comment-block', { affiliated, value });
596
595
  }
597
596
  parseSrcBlock(affiliated) {
598
597
  const endM = this.r.match(/^[ \t]*#\+end_src[ \t]*$/im);
@@ -605,12 +604,12 @@ class Parser {
605
604
  const begin = this.r.offset();
606
605
  const contentsBegin = begin + this.r.line().length;
607
606
  const contentsEnd = begin + endM.index;
608
- const value = utils_1.unescapeCodeInString(this.r.substring(contentsBegin, contentsEnd));
607
+ const value = unescapeCodeInString(this.r.substring(contentsBegin, contentsEnd));
609
608
  this.r.resetOffset(contentsEnd);
610
609
  this.r.advance(this.r.line());
611
610
  this.parseEmptyLines();
612
611
  const _end = this.r.offset();
613
- return unist_builder_1.default('src-block', { affiliated, language, value });
612
+ return u('src-block', { affiliated, language, value });
614
613
  }
615
614
  parseExampleBlock(affiliated) {
616
615
  // TODO: parse switches
@@ -620,30 +619,29 @@ class Parser {
620
619
  return block;
621
620
  }
622
621
  const value = this.r.substring(block.contentsBegin, block.contentsEnd);
623
- return unist_builder_1.default('example-block', { affiliated, value });
622
+ return u('example-block', { affiliated, value });
624
623
  }
625
624
  parseExportBlock(affiliated) {
626
- var _a;
627
625
  const endM = this.r.match(/^[ \t]*#\+end_export[ \t]*$/im);
628
626
  if (!endM) {
629
627
  // Incomplete block: parse it as a paragraph.
630
628
  return this.parseParagraph(affiliated);
631
629
  }
632
630
  const headerM = this.r.forceMatch(/^[ \t]*#\+begin_export(?:[ \t]+(\S+))?[ \t]*$/im);
633
- const backend = (_a = headerM[1]) !== null && _a !== void 0 ? _a : null;
631
+ const backend = headerM[1] ?? null;
634
632
  const begin = this.r.offset();
635
633
  const contentsBegin = begin + this.r.line().length;
636
634
  const contentsEnd = begin + endM.index;
637
- const value = utils_1.unescapeCodeInString(this.r.substring(contentsBegin, contentsEnd));
635
+ const value = unescapeCodeInString(this.r.substring(contentsBegin, contentsEnd));
638
636
  this.r.resetOffset(contentsEnd);
639
637
  this.r.advance(this.r.line());
640
638
  this.parseEmptyLines();
641
639
  const _end = this.r.offset();
642
- return unist_builder_1.default('export-block', { affiliated, backend, value });
640
+ return u('export-block', { affiliated, backend, value });
643
641
  }
644
642
  parseSpecialBlock(affiliated) {
645
643
  const blockType = this.r.forceLookingAt(/[ \t]*#\+begin_(\S+)/i)[1];
646
- const endM = this.r.match(new RegExp(`^[ \\t]*#\\+end_${utils_1.escapeRegExp(blockType)}[ \\t]*$`, 'im'));
644
+ const endM = this.r.match(new RegExp(`^[ \\t]*#\\+end_${escapeRegExp(blockType)}[ \\t]*$`, 'im'));
647
645
  if (!endM) {
648
646
  this.r.message('incomplete block', this.r.offset(), 'uniorg');
649
647
  // Incomplete block: parse it as a paragraph.
@@ -656,29 +654,30 @@ class Parser {
656
654
  this.r.advance(this.r.line());
657
655
  this.parseEmptyLines();
658
656
  const _end = this.r.offset();
659
- return unist_builder_1.default('special-block', { affiliated, blockType, contentsBegin, contentsEnd }, []);
657
+ return u('special-block', { affiliated, blockType, contentsBegin, contentsEnd }, []);
660
658
  }
661
659
  parseAffiliatedKeywords() {
662
- var _a, _b, _c, _d;
663
660
  const offset = this.r.offset();
664
661
  const result = {};
665
662
  while (!this.r.eof()) {
666
663
  const keywordM = this.r.lookingAt(affiliatedRe);
667
664
  if (!keywordM)
668
665
  break;
669
- const rawKeyword = ((_b = (_a = keywordM.groups.dualKeyword) !== null && _a !== void 0 ? _a : keywordM.groups.regularKeyword) !== null && _b !== void 0 ? _b : keywordM.groups.attributeKeyword).toUpperCase();
670
- const keyword = (_c = keywordTranslationTable[rawKeyword]) !== null && _c !== void 0 ? _c : rawKeyword;
666
+ const rawKeyword = (keywordM.groups.dualKeyword ??
667
+ keywordM.groups.regularKeyword ??
668
+ keywordM.groups.attributeKeyword).toUpperCase();
669
+ const keyword = keywordTranslationTable[rawKeyword] ?? rawKeyword;
671
670
  // true if keyword should have its value parsed
672
671
  const isParsed = parsedKeywords.has(keyword);
673
672
  this.r.advance(keywordM);
674
673
  this.r.narrow(this.r.offset(), this.r.offset() + this.r.line().length);
675
674
  const mainValue = isParsed
676
- ? this.parseObjects(utils_1.restrictionFor('keyword'))
675
+ ? this.parseObjects(restrictionFor('keyword'))
677
676
  : this.r.rest().trim();
678
677
  this.r.widen();
679
678
  this.r.advance(this.r.line());
680
679
  const isDual = dualKeywords.has(keyword);
681
- const dualValue = isDual ? (_d = keywordM.groups.dualValue) !== null && _d !== void 0 ? _d : null : null;
680
+ const dualValue = isDual ? keywordM.groups.dualValue ?? null : null;
682
681
  const value = dualValue === null ? mainValue : [mainValue, dualValue];
683
682
  if (multipleKeywords.has(keyword) ||
684
683
  // Attributes can always appear on multiple lines.
@@ -704,7 +703,7 @@ class Parser {
704
703
  const value = m[2].trim();
705
704
  this.r.advance(this.r.line());
706
705
  this.parseEmptyLines();
707
- return unist_builder_1.default('keyword', { affiliated, key, value });
706
+ return u('keyword', { affiliated, key, value });
708
707
  }
709
708
  parseLatexEnvironment(affiliated) {
710
709
  const beginOffset = this.r.offset();
@@ -720,10 +719,10 @@ class Parser {
720
719
  const endOffset = this.r.offset();
721
720
  this.parseEmptyLines();
722
721
  const value = this.r.substring(beginOffset, endOffset);
723
- return unist_builder_1.default('latex-environment', { affiliated, value });
722
+ return u('latex-environment', { affiliated, value });
724
723
  }
725
724
  parseDrawer(affiliated) {
726
- const endM = this.r.match(/^[ \t]*:END:[ \t]*$/m);
725
+ const endM = this.r.match(/^[ \t]*:END:[ \t]*$/im);
727
726
  if (!endM) {
728
727
  this.r.message('incomplete drawer', this.r.offset(), 'uniorg');
729
728
  // Incomplete drawer: parse it as a paragraph.
@@ -736,7 +735,7 @@ class Parser {
736
735
  this.r.resetOffset(contentsEnd);
737
736
  this.r.advance(this.r.line());
738
737
  this.parseEmptyLines();
739
- return unist_builder_1.default('drawer', { affiliated, name, contentsBegin, contentsEnd }, []);
738
+ return u('drawer', { affiliated, name, contentsBegin, contentsEnd }, []);
740
739
  }
741
740
  parseClock() {
742
741
  this.r.advance(this.r.forceMatch(/^[ \t]*CLOCK:[ \t]*/));
@@ -746,16 +745,15 @@ class Parser {
746
745
  const duration = durationM ? durationM[1] : null;
747
746
  const status = duration ? 'closed' : 'running';
748
747
  this.parseEmptyLines();
749
- return unist_builder_1.default('clock', { value, duration, status });
748
+ return u('clock', { value, duration, status });
750
749
  }
751
750
  parseNodeProperty() {
752
- var _a;
753
751
  const propertyRe = /^[ \t]*:(?<key>\S+):(?:(?<value1>$)|[ \t]+(?<value2>.*?))[ \t]*$/m;
754
752
  const m = this.r.forceLookingAt(propertyRe);
755
753
  const key = m.groups['key'];
756
- const value = (_a = m.groups['value1']) !== null && _a !== void 0 ? _a : m.groups['value2'];
754
+ const value = m.groups['value1'] ?? m.groups['value2'];
757
755
  this.r.advance(this.r.line());
758
- return unist_builder_1.default('node-property', { key, value });
756
+ return u('node-property', { key, value });
759
757
  }
760
758
  parseParagraph(affiliated) {
761
759
  const contentsBegin = this.r.offset();
@@ -778,7 +776,7 @@ class Parser {
778
776
  }
779
777
  const drawerM = this.r.lookingAt(drawerRe);
780
778
  if (drawerM) {
781
- const endM = this.r.match(/^[ \t]*:END:[ \t]*$/m);
779
+ const endM = this.r.match(/^[ \t]*:END:[ \t]*$/im);
782
780
  if (!endM) {
783
781
  this.r.advance(this.r.line());
784
782
  continue;
@@ -809,16 +807,15 @@ class Parser {
809
807
  const contentsEnd = next ? this.r.offset() : this.r.endOffset();
810
808
  this.r.resetOffset(contentsEnd);
811
809
  this.parseEmptyLines();
812
- return unist_builder_1.default('paragraph', { affiliated, contentsBegin, contentsEnd }, []);
810
+ return u('paragraph', { affiliated, contentsBegin, contentsEnd }, []);
813
811
  }
814
812
  parseFootnoteDefinition(affiliated) {
815
- var _a;
816
813
  const m = this.r.forceLookingAt(footnoteDefinitionRe);
817
814
  const label = m[1];
818
815
  const begin = this.r.offset();
819
816
  this.r.advance(this.r.line());
820
817
  const endM = this.r.match(footnoteDefinitionSeparatorRe);
821
- this.r.advance(endM === null || endM === void 0 ? void 0 : endM.index);
818
+ this.r.advance(endM?.index);
822
819
  let contentsEnd = endM ? this.r.offset() : this.r.endOffset();
823
820
  if (endM && endM[0][0] === '[') {
824
821
  // At a new footnote definition, make sure we end before any
@@ -829,7 +826,7 @@ class Parser {
829
826
  lines = lines.slice(1, lines.length - 1);
830
827
  while (lines.length) {
831
828
  const line = lines.pop();
832
- if (((_a = line.match(affiliatedRe)) === null || _a === void 0 ? void 0 : _a.index) === 0) {
829
+ if (line.match(affiliatedRe)?.index === 0) {
833
830
  // -1 to compensate for \n
834
831
  this.r.advance(-line.length - 1);
835
832
  }
@@ -845,18 +842,18 @@ class Parser {
845
842
  this.r.widen();
846
843
  this.r.resetOffset(contentsEnd);
847
844
  this.parseEmptyLines();
848
- return unist_builder_1.default('footnote-definition', { affiliated, label, contentsBegin, contentsEnd }, []);
845
+ return u('footnote-definition', { affiliated, label, contentsBegin, contentsEnd }, []);
849
846
  }
850
847
  parseHorizontalRule(affiliated) {
851
848
  this.r.advance(this.r.line());
852
849
  this.parseEmptyLines();
853
- return unist_builder_1.default('horizontal-rule', { affiliated });
850
+ return u('horizontal-rule', { affiliated });
854
851
  }
855
852
  parseDiarySexp(affiliated) {
856
853
  const value = this.r.forceLookingAt(/^(%%\(.*)[ \t]*$/m)[1];
857
854
  this.r.advance(this.r.line());
858
855
  this.parseEmptyLines();
859
- return unist_builder_1.default('diary-sexp', { affiliated, value });
856
+ return u('diary-sexp', { affiliated, value });
860
857
  }
861
858
  parseTable(affiliated) {
862
859
  const contentsBegin = this.r.offset();
@@ -877,10 +874,10 @@ class Parser {
877
874
  }
878
875
  this.parseEmptyLines();
879
876
  if (tableType === 'org') {
880
- return unist_builder_1.default('table', { tableType, tblfm, contentsBegin, contentsEnd }, []);
877
+ return u('table', { tableType, tblfm, contentsBegin, contentsEnd }, []);
881
878
  }
882
879
  else {
883
- return unist_builder_1.default('table', {
880
+ return u('table', {
884
881
  affiliated,
885
882
  tableType,
886
883
  tblfm,
@@ -899,14 +896,14 @@ class Parser {
899
896
  // contentsBegin matches contentsEnd.
900
897
  const contentsEnd = rowType === 'rule' ? contentsBegin : this.r.offset();
901
898
  this.r.advance(this.r.line());
902
- return unist_builder_1.default('table-row', { rowType, contentsBegin, contentsEnd }, []);
899
+ return u('table-row', { rowType, contentsBegin, contentsEnd }, []);
903
900
  }
904
901
  parseTableCell() {
905
902
  this.r.advance(this.r.forceLookingAt(/^[ \t]*/));
906
903
  const contentsBegin = this.r.offset();
907
904
  const m = this.r.advance(this.r.forceLookingAt(/(.*?)[ \t]*(?:\||$)/m));
908
905
  const contentsEnd = contentsBegin + m[1].length;
909
- return unist_builder_1.default('table-cell', { contentsBegin, contentsEnd }, []);
906
+ return u('table-cell', { contentsBegin, contentsEnd }, []);
910
907
  }
911
908
  parseList(structure, affiliated) {
912
909
  const contentsBegin = this.r.offset();
@@ -929,7 +926,7 @@ class Parser {
929
926
  }
930
927
  const contentsEnd = pos;
931
928
  this.r.resetOffset(contentsEnd);
932
- return unist_builder_1.default('plain-list', {
929
+ return u('plain-list', {
933
930
  affiliated,
934
931
  indent,
935
932
  listType,
@@ -941,14 +938,13 @@ class Parser {
941
938
  }, []);
942
939
  }
943
940
  parseListItem(structure) {
944
- var _a, _b;
945
941
  const offset = this.r.offset();
946
942
  const m = this.r.advance(this.r.forceMatch(this.re.fullListItemRe()));
947
943
  const bullet = m.groups.bullet;
948
- const counter = (_a = m.groups.counter) !== null && _a !== void 0 ? _a : null;
944
+ const counter = m.groups.counter ?? null;
949
945
  const checkbox = m.groups.checkbox === '[ ]'
950
946
  ? 'off'
951
- : ((_b = m.groups.checkbox) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === '[x]'
947
+ : m.groups.checkbox?.toLowerCase() === '[x]'
952
948
  ? 'on'
953
949
  : m.groups.checkbox === '[-]'
954
950
  ? 'trans'
@@ -957,21 +953,21 @@ class Parser {
957
953
  const contentsBegin = this.r.offset();
958
954
  const contentsEnd = item.end;
959
955
  this.r.resetOffset(contentsEnd);
960
- return unist_builder_1.default('list-item', {
956
+ return u('list-item', {
961
957
  indent: item.indent,
962
958
  bullet,
963
959
  counter,
964
960
  checkbox,
965
961
  contentsBegin,
966
962
  contentsEnd,
963
+ structure,
967
964
  }, item.tag ? [item.tag] : []);
968
965
  }
969
966
  parseListStructure() {
970
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
971
967
  const items = [];
972
968
  const struct = [];
973
969
  while (true) {
974
- if (this.r.eof() || ((_a = this.r.match(this.re.listEndRe())) === null || _a === void 0 ? void 0 : _a.index) === 0) {
970
+ if (this.r.eof() || this.r.match(this.re.listEndRe())?.index === 0) {
975
971
  break;
976
972
  }
977
973
  const m = this.r.match(this.re.listItemRe());
@@ -994,21 +990,21 @@ class Parser {
994
990
  let tag = null;
995
991
  if (fullM.groups.tag !== undefined) {
996
992
  const tagStartOffset = this.r.offset() +
997
- ((_c = (_b = fullM.groups.indent) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0) +
998
- ((_e = (_d = fullM.groups.bullet) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0) +
999
- ((_g = (_f = fullM.groups.counter_group) === null || _f === void 0 ? void 0 : _f.length) !== null && _g !== void 0 ? _g : 0) +
1000
- ((_j = (_h = fullM.groups.checkbox_group) === null || _h === void 0 ? void 0 : _h.length) !== null && _j !== void 0 ? _j : 0);
993
+ (fullM.groups.indent?.length ?? 0) +
994
+ (fullM.groups.bullet?.length ?? 0) +
995
+ (fullM.groups.counter_group?.length ?? 0) +
996
+ (fullM.groups.checkbox_group?.length ?? 0);
1001
997
  const tagStopOffset = tagStartOffset + fullM.groups.tag.length;
1002
998
  this.r.narrow(tagStartOffset, tagStopOffset);
1003
- tag = unist_builder_1.default('list-item-tag', {}, this.parseObjects(utils_1.restrictionFor('list-item')));
999
+ tag = u('list-item-tag', {}, this.parseObjects(restrictionFor('list-item')));
1004
1000
  this.r.widen();
1005
1001
  }
1006
1002
  const item = {
1007
1003
  begin: this.r.offset(),
1008
1004
  indent,
1009
1005
  bullet,
1010
- counter: counter !== null && counter !== void 0 ? counter : null,
1011
- checkbox: checkbox !== null && checkbox !== void 0 ? checkbox : null,
1006
+ counter: counter ?? null,
1007
+ checkbox: checkbox ?? null,
1012
1008
  tag,
1013
1009
  // will be overwritten later
1014
1010
  end: this.r.offset(),
@@ -1032,7 +1028,14 @@ class Parser {
1032
1028
  // closed full list
1033
1029
  break;
1034
1030
  }
1035
- // TODO: skip blocks
1031
+ // skip blocks (any type) and drawers contents.
1032
+ const mBlock = this.r.lookingAt(/[ \t]*#\+begin(:|_\S+)/i);
1033
+ if (mBlock) {
1034
+ this.r.advance(this.r.match(new RegExp(`^[ \\t]*#\\+end${mBlock[1]}[ \\t]*`, 'im')));
1035
+ }
1036
+ else if (this.r.lookingAt(drawerRe)) {
1037
+ this.r.advance(this.r.match(/^[ \t]*:END:[ \t]*$/im));
1038
+ }
1036
1039
  this.r.advance(this.r.line());
1037
1040
  }
1038
1041
  }
@@ -1057,7 +1060,7 @@ class Parser {
1057
1060
  const contentsBegin = begin + m[2].length + (inside ? 1 : 0);
1058
1061
  const contentsEnd = begin + m[2].length + m[3].length - (inside ? 1 : 0);
1059
1062
  const _end = this.r.offset();
1060
- return unist_builder_1.default('superscript', { contentsBegin, contentsEnd, children: [] });
1063
+ return u('superscript', { contentsBegin, contentsEnd, children: [] });
1061
1064
  }
1062
1065
  parseSubscript() {
1063
1066
  this.r.backoff(1); // backoff by one, to match previous char (should be non-space)
@@ -1070,7 +1073,7 @@ class Parser {
1070
1073
  const contentsBegin = begin + m[2].length + (inside ? 1 : 0);
1071
1074
  const contentsEnd = begin + m[2].length + m[3].length - (inside ? 1 : 0);
1072
1075
  const _end = this.r.offset();
1073
- return unist_builder_1.default('subscript', { contentsBegin, contentsEnd, children: [] });
1076
+ return u('subscript', { contentsBegin, contentsEnd, children: [] });
1074
1077
  }
1075
1078
  parseUnderline() {
1076
1079
  // backoff one char to check border
@@ -1081,7 +1084,7 @@ class Parser {
1081
1084
  const contentsBegin = this.r.offset() + m.index + m[1].length + m[3].length;
1082
1085
  const contentsEnd = contentsBegin + m[4].length;
1083
1086
  this.r.resetOffset(contentsEnd + 1);
1084
- return unist_builder_1.default('underline', { contentsBegin, contentsEnd }, []);
1087
+ return u('underline', { contentsBegin, contentsEnd }, []);
1085
1088
  }
1086
1089
  parseBold() {
1087
1090
  // backoff one char to check border
@@ -1092,7 +1095,7 @@ class Parser {
1092
1095
  const contentsBegin = this.r.offset() + m.index + m[1].length + m[3].length;
1093
1096
  const contentsEnd = contentsBegin + m[4].length;
1094
1097
  this.r.resetOffset(contentsEnd + 1);
1095
- return unist_builder_1.default('bold', { contentsBegin, contentsEnd }, []);
1098
+ return u('bold', { contentsBegin, contentsEnd }, []);
1096
1099
  }
1097
1100
  parseItalic() {
1098
1101
  // backoff one char to check border
@@ -1103,7 +1106,7 @@ class Parser {
1103
1106
  const contentsBegin = this.r.offset() + m.index + m[1].length + m[3].length;
1104
1107
  const contentsEnd = contentsBegin + m[4].length;
1105
1108
  this.r.resetOffset(contentsEnd + 1);
1106
- return unist_builder_1.default('italic', { contentsBegin, contentsEnd }, []);
1109
+ return u('italic', { contentsBegin, contentsEnd }, []);
1107
1110
  }
1108
1111
  parseCode() {
1109
1112
  // backoff one char to check border
@@ -1115,7 +1118,7 @@ class Parser {
1115
1118
  const contentsBegin = this.r.offset() + m.index + m[1].length + m[3].length;
1116
1119
  const contentsEnd = contentsBegin + m[4].length;
1117
1120
  this.r.resetOffset(contentsEnd + 1);
1118
- return unist_builder_1.default('code', { value }, []);
1121
+ return u('code', { value }, []);
1119
1122
  }
1120
1123
  parseVerbatim() {
1121
1124
  this.r.backoff(1);
@@ -1126,7 +1129,7 @@ class Parser {
1126
1129
  const contentsBegin = this.r.offset() + m.index + m[1].length + m[3].length;
1127
1130
  const contentsEnd = contentsBegin + m[4].length;
1128
1131
  this.r.resetOffset(contentsEnd + 1);
1129
- return unist_builder_1.default('verbatim', { value }, []);
1132
+ return u('verbatim', { value }, []);
1130
1133
  }
1131
1134
  parseStrikeThrough() {
1132
1135
  // backoff one char to check border
@@ -1137,10 +1140,9 @@ class Parser {
1137
1140
  const contentsBegin = this.r.offset() + m.index + m[1].length + m[3].length;
1138
1141
  const contentsEnd = contentsBegin + m[4].length;
1139
1142
  this.r.resetOffset(contentsEnd + 1);
1140
- return unist_builder_1.default('strike-through', { contentsBegin, contentsEnd }, []);
1143
+ return u('strike-through', { contentsBegin, contentsEnd }, []);
1141
1144
  }
1142
1145
  parseEntity() {
1143
- var _a;
1144
1146
  const m = this.r.advance(this.r.lookingAt(/^\\(?:(?<value1>_ +)|(?<value2>there4|sup[123]|frac[13][24]|[a-zA-Z]+)(?<brackets>$|\{\}|\P{Letter}))/mu));
1145
1147
  if (!m)
1146
1148
  return null;
@@ -1151,13 +1153,12 @@ class Parser {
1151
1153
  // as text later.
1152
1154
  this.r.backoff(m.groups.brackets.length);
1153
1155
  }
1154
- const value = entities_1.getOrgEntity((_a = m.groups.value1) !== null && _a !== void 0 ? _a : m.groups.value2);
1156
+ const value = getOrgEntity(m.groups.value1 ?? m.groups.value2);
1155
1157
  if (!value)
1156
1158
  return null;
1157
- return unist_builder_1.default('entity', Object.assign({ useBrackets: hasBrackets }, value));
1159
+ return u('entity', { useBrackets: hasBrackets, ...value });
1158
1160
  }
1159
1161
  parseLatexFragment() {
1160
- var _a;
1161
1162
  const begin = this.r.offset();
1162
1163
  const prefix = this.r.peek(2);
1163
1164
  let contents = null;
@@ -1174,20 +1175,20 @@ class Parser {
1174
1175
  default: {
1175
1176
  // Macro.
1176
1177
  const m = this.r.advance(this.r.lookingAt(/^\\[a-zA-Z]+\*?((\[[^\]\[\n{}]*\])|(\{[^{}\n]*\}))*/));
1177
- contents = m === null || m === void 0 ? void 0 : m[0];
1178
+ contents = m?.[0];
1178
1179
  }
1179
1180
  }
1180
1181
  }
1181
1182
  else if (prefix[1] === '$') {
1182
1183
  const m = this.r.advance(this.r.match(/\$\$((?:.|\n)*?)\$\$/m));
1183
- contents = m === null || m === void 0 ? void 0 : m[1];
1184
+ contents = m?.[1];
1184
1185
  }
1185
1186
  else {
1186
1187
  // TODO: limit search to 2 lines
1187
1188
  const charBefore = this.r.substring(this.r.offset() - 1, this.r.offset());
1188
1189
  if (charBefore !== '$' &&
1189
1190
  !' \t\n,.;'.includes(prefix[1]) &&
1190
- (contents = (_a = this.r.advance(this.r.match(/\$((?:.|\n)*?)\$/m))) === null || _a === void 0 ? void 0 : _a[1]) &&
1191
+ (contents = this.r.advance(this.r.match(/\$((?:.|\n)*?)\$/m))?.[1]) &&
1191
1192
  !' \t\n,.'.includes(this.r.substring(this.r.offset() - 1, this.r.offset())) &&
1192
1193
  this.r.lookingAt(/^(\p{Punctuation}|\p{White_Space}|\p{Open_Punctuation}|\p{Close_Punctuation}|\\"|'|$)/mu)) {
1193
1194
  // we've found the end
@@ -1201,10 +1202,9 @@ class Parser {
1201
1202
  if (begin === end)
1202
1203
  return null;
1203
1204
  const value = this.r.substring(begin, end);
1204
- return unist_builder_1.default('latex-fragment', { value, contents: contents !== null && contents !== void 0 ? contents : value });
1205
+ return u('latex-fragment', { value, contents: contents ?? value });
1205
1206
  }
1206
1207
  parseFootnoteReference() {
1207
- var _a;
1208
1208
  const begin = this.r.offset();
1209
1209
  const m = this.r.match(footnoteRe);
1210
1210
  if (!m)
@@ -1233,9 +1233,10 @@ class Parser {
1233
1233
  ? 'inline'
1234
1234
  : 'standard';
1235
1235
  const label = footnoteType === 'inline'
1236
- ? (_a = m.groups.label_inline) !== null && _a !== void 0 ? _a : null : m.groups.label;
1236
+ ? m.groups.label_inline ?? null
1237
+ : m.groups.label;
1237
1238
  if (footnoteType === 'inline') {
1238
- return unist_builder_1.default('footnote-reference', {
1239
+ return u('footnote-reference', {
1239
1240
  label,
1240
1241
  footnoteType,
1241
1242
  contentsBegin,
@@ -1243,7 +1244,7 @@ class Parser {
1243
1244
  }, []);
1244
1245
  }
1245
1246
  else {
1246
- return unist_builder_1.default('footnote-reference', { label, footnoteType }, []);
1247
+ return u('footnote-reference', { label, footnoteType }, []);
1247
1248
  }
1248
1249
  }
1249
1250
  parseLink() {
@@ -1277,9 +1278,13 @@ class Parser {
1277
1278
  .replace(/(\\+)([\[\]])/g, (p1, p2) => '\\'.repeat(p1.length / 2) + p2);
1278
1279
  // TODO: org-link-expand-abbrev
1279
1280
  const { linkType, path } = this.linkType(rawLink);
1280
- return unist_builder_1.default('link', Object.assign({ format: 'bracket', linkType,
1281
+ return u('link', {
1282
+ format: 'bracket',
1283
+ linkType,
1281
1284
  rawLink,
1282
- path }, contents), []);
1285
+ path,
1286
+ ...contents,
1287
+ }, []);
1283
1288
  }
1284
1289
  // TODO: this is different from OrgRegexUtils.linkPlainRe
1285
1290
  // Type 3: Plain link, e.g., https://orgmode.org
@@ -1287,7 +1292,7 @@ class Parser {
1287
1292
  const plainM = this.r.advance(this.r.lookingAt(linkPlainRe));
1288
1293
  if (plainM) {
1289
1294
  const m = plainM;
1290
- return unist_builder_1.default('link', {
1295
+ return u('link', {
1291
1296
  format: 'plain',
1292
1297
  linkType: m[1],
1293
1298
  rawLink: m[0],
@@ -1304,7 +1309,7 @@ class Parser {
1304
1309
  const linkType = m[1];
1305
1310
  const rawLink = m[0].substring(1, m[0].length - 1); // strip < >
1306
1311
  const path = m[2].replace(/[ \t]*\n[ \t]*/g, '');
1307
- return unist_builder_1.default('link', { format: 'angle', linkType, rawLink, path }, []);
1312
+ return u('link', { format: 'angle', linkType, rawLink, path }, []);
1308
1313
  }
1309
1314
  return null;
1310
1315
  }
@@ -1375,8 +1380,9 @@ class Parser {
1375
1380
  : dateEnd
1376
1381
  ? Parser.parseDate(dateEnd)
1377
1382
  : timeRange
1378
- ? Object.assign(Object.assign({}, start), timeRange) : null;
1379
- return unist_builder_1.default('timestamp', {
1383
+ ? { ...start, ...timeRange }
1384
+ : null;
1385
+ return u('timestamp', {
1380
1386
  timestampType,
1381
1387
  rawValue,
1382
1388
  start,
@@ -1419,7 +1425,7 @@ class Parser {
1419
1425
  }
1420
1426
  const drawerRe = /^[ \t]*:((?:\w|[-_])+):[ \t]*$/m;
1421
1427
  const latexBeginEnvironmentRe = /^[ \t]*\\begin\{([A-Za-z0-9*]+)\}/i;
1422
- const latexEndEnvironmentRe = (name) => new RegExp(`\\\\end\\{${utils_1.escapeRegExp(name)}\\}[ \\t]*$`, 'mi');
1428
+ const latexEndEnvironmentRe = (name) => new RegExp(`\\\\end\\{${escapeRegExp(name)}\\}[ \\t]*$`, 'mi');
1423
1429
  const affiliatedKeywords = [
1424
1430
  'CAPTION',
1425
1431
  'DATA',
@@ -1466,9 +1472,8 @@ const footnoteRe = /\[fn:(?:(?<label_inline>[-_\w]+)?(?<inline>:)|(?<label>[-_\w
1466
1472
  const footnoteDefinitionRe = /^\[fn:([-_\w]+)\]/;
1467
1473
  const footnoteDefinitionSeparatorRe = /^\*|^\[fn:([-_\w]+)\]|^([ \t]*\n){2,}/m;
1468
1474
  function appendChildren(node, children) {
1469
- var _a;
1470
1475
  if ('children' in node) {
1471
- const newChildren = [...((_a = node.children) !== null && _a !== void 0 ? _a : []), ...children];
1476
+ const newChildren = [...(node.children ?? []), ...children];
1472
1477
  node.children = newChildren;
1473
1478
  }
1474
1479
  }