highmark-markdown 0.0.379 → 0.0.382

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 (100) hide show
  1. package/example.js +4764 -3417
  2. package/lib/attributeNames.js +5 -1
  3. package/lib/constants.js +1 -5
  4. package/lib/defaultMarkdownStyle.js +2 -2
  5. package/lib/example/constants.js +15 -7
  6. package/lib/example/customEventTypes.js +5 -1
  7. package/lib/example/view/button/page.js +168 -0
  8. package/lib/example/view/div/html.js +2 -2
  9. package/lib/example/view/div/pageButtons.js +270 -0
  10. package/lib/example/view/div/preview.js +105 -13
  11. package/lib/example/view/textarea/css.js +2 -2
  12. package/lib/example/view/xmp.js +2 -4
  13. package/lib/example/view.js +88 -34
  14. package/lib/example.js +2 -2
  15. package/lib/index.js +15 -11
  16. package/lib/markdown/bnf.js +2 -2
  17. package/lib/mixins/node.js +10 -3
  18. package/lib/node/markdown/anchor.js +5 -2
  19. package/lib/node/markdown/blockLine.js +3 -2
  20. package/lib/node/markdown/contentsLink.js +4 -4
  21. package/lib/node/markdown/directive/contents.js +6 -6
  22. package/lib/node/markdown/directive/embee.js +12 -12
  23. package/lib/node/markdown/directive/footnotes.js +6 -6
  24. package/lib/node/markdown/directive/ignore.js +6 -6
  25. package/lib/node/markdown/directive/include.js +6 -6
  26. package/lib/node/markdown/directive/pageNumber.js +74 -9
  27. package/lib/node/markdown/directive.js +128 -0
  28. package/lib/node/markdown/directives.js +33 -2
  29. package/lib/node/markdown/division.js +128 -28
  30. package/lib/node/markdown/emailLink.js +8 -1
  31. package/lib/node/markdown/endOfLine.js +8 -1
  32. package/lib/node/markdown/footnoteItem.js +3 -3
  33. package/lib/node/markdown/footnotesList.js +95 -27
  34. package/lib/node/markdown/heading/primary.js +2 -1
  35. package/lib/node/markdown/heading/quaternary.js +2 -1
  36. package/lib/node/markdown/heading/secondary.js +2 -1
  37. package/lib/node/markdown/heading/tertiary.js +2 -1
  38. package/lib/node/markdown/heading.js +8 -1
  39. package/lib/node/markdown/line.js +8 -1
  40. package/lib/node/markdown/subDivision.js +17 -10
  41. package/lib/node/markdown.js +15 -1
  42. package/lib/replacement.js +185 -0
  43. package/lib/utilities/childNodes.js +7 -5
  44. package/lib/utilities/content.js +7 -7
  45. package/lib/utilities/markdown.js +87 -0
  46. package/lib/utilities/node.js +163 -0
  47. package/lib/utilities/query.js +25 -9
  48. package/package.json +1 -1
  49. package/src/attributeNames.js +1 -0
  50. package/src/constants.js +0 -1
  51. package/src/defaultMarkdownStyle.js +5 -1
  52. package/src/example/constants.js +4 -2
  53. package/src/example/customEventTypes.js +1 -0
  54. package/src/example/view/button/page.js +48 -0
  55. package/src/example/view/div/html.js +0 -1
  56. package/src/example/view/div/pageButtons.js +98 -0
  57. package/src/example/view/div/preview.js +51 -11
  58. package/src/example/view/textarea/css.js +1 -1
  59. package/src/example/view/xmp.js +1 -5
  60. package/src/example/view.js +117 -51
  61. package/src/example.js +2 -2
  62. package/src/index.js +9 -6
  63. package/src/markdown/bnf.js +21 -23
  64. package/src/mixins/node.js +20 -2
  65. package/src/node/markdown/anchor.js +7 -2
  66. package/src/node/markdown/blockLine.js +3 -3
  67. package/src/node/markdown/contentsLink.js +3 -3
  68. package/src/node/markdown/directive/contents.js +3 -3
  69. package/src/node/markdown/directive/embee.js +8 -8
  70. package/src/node/markdown/directive/footnotes.js +3 -3
  71. package/src/node/markdown/directive/ignore.js +3 -3
  72. package/src/node/markdown/directive/include.js +3 -3
  73. package/src/node/markdown/directive/pageNumber.js +53 -5
  74. package/src/node/markdown/directive.js +13 -0
  75. package/src/node/markdown/directives.js +10 -1
  76. package/src/node/markdown/division.js +144 -26
  77. package/src/node/markdown/emailLink.js +6 -0
  78. package/src/node/markdown/endOfLine.js +6 -0
  79. package/src/node/markdown/footnoteItem.js +1 -1
  80. package/src/node/markdown/footnotesList.js +87 -31
  81. package/src/node/markdown/heading/primary.js +2 -0
  82. package/src/node/markdown/heading/quaternary.js +2 -0
  83. package/src/node/markdown/heading/secondary.js +2 -0
  84. package/src/node/markdown/heading/tertiary.js +2 -0
  85. package/src/node/markdown/heading.js +6 -0
  86. package/src/node/markdown/line.js +12 -1
  87. package/src/node/markdown/subDivision.js +18 -12
  88. package/src/node/markdown.js +19 -0
  89. package/src/replacement.js +158 -0
  90. package/src/utilities/childNodes.js +6 -4
  91. package/src/utilities/content.js +12 -20
  92. package/src/utilities/markdown.js +103 -0
  93. package/src/utilities/node.js +158 -0
  94. package/src/utilities/query.js +22 -6
  95. package/lib/replacementNodeAndTokens.js +0 -149
  96. package/lib/utilities/footnotes.js +0 -20
  97. package/lib/utilities/replace.js +0 -66
  98. package/src/replacementNodeAndTokens.js +0 -152
  99. package/src/utilities/footnotes.js +0 -16
  100. package/src/utilities/replace.js +0 -31
@@ -4,7 +4,7 @@ import { arrayUtilities } from "necessary";
4
4
 
5
5
  import MarkdownNode from "../../node/markdown";
6
6
 
7
- const { first, push } = arrayUtilities;
7
+ const { clear, first, push } = arrayUtilities;
8
8
 
9
9
  export default class DirectivesMarkdownNode extends MarkdownNode {
10
10
  constructor(ruleName, childNodes, opacity, precedence, domElement, domElements) {
@@ -42,6 +42,8 @@ export default class DirectivesMarkdownNode extends MarkdownNode {
42
42
  const domElement = null,
43
43
  childNodes = this.getChildNodes();
44
44
 
45
+ clear(this.domElements);
46
+
45
47
  childNodes.forEach((childNode) => {
46
48
  const childNodeNonTerminalNode = childNode.isNonTerminalNode();
47
49
 
@@ -60,6 +62,13 @@ export default class DirectivesMarkdownNode extends MarkdownNode {
60
62
  return domElement;
61
63
  }
62
64
 
65
+ clone() {
66
+ const domElements = [],
67
+ directivesMarkdownNode = super.clone(domElements);
68
+
69
+ return directivesMarkdownNode;
70
+ }
71
+
63
72
  static fromRuleNameChildNodesAndOpacity(ruleName, childNodes, opacity) {
64
73
  const domElements = [],
65
74
  directivesMarkdownNode = MarkdownNode.fromRuleNameChildNodesAndOpacity(DirectivesMarkdownNode, ruleName, childNodes, opacity, domElements);
@@ -2,20 +2,24 @@
2
2
 
3
3
  import { arrayUtilities } from "necessary";
4
4
 
5
+ import Replacement from "../../replacement";
5
6
  import MarkdownNode from "../../node/markdown";
6
7
  import ContentsListMarkdownNode from "../../node/markdown/contentsList";
7
8
  import FootnotesListMarkdownNode from "../../node/markdown/footnotesList";
8
9
 
9
10
  import { EMPTY_STRING } from "../../constants";
10
- import { renumberLinkMarkdownNodes } from "../../utilities/footnotes";
11
- import { replaceNode, replaceNodes, replaceTokens } from "../../utilities/replace";
12
- import { headingMarkdownNodesFromNode,
11
+ import { DIVISION_RULE_NAME } from "../../ruleNames";
12
+ import { removeNode, removeTokens, replaceNode, replaceNodes, replaceTokens } from "../../utilities/node";
13
+ import { footnoteMarkdownNodsFromNode,
14
+ headingMarkdownNodesFromNode,
15
+ subDivisionMarkdownNodesFromNode,
13
16
  embedDirectiveMarkdownNodesFromNode,
14
17
  ignoreDirectiveMarkdownNodeFromNode,
15
18
  contentsDirectiveMarkdownNodeFromNode,
16
- footnotesDirectiveMarkdownNodeFromNode } from "../../utilities/query";
19
+ footnotesDirectiveMarkdownNodeFromNode,
20
+ pageNumberDirectiveMarkdownNodeFromNode } from "../../utilities/query";
17
21
 
18
- const { filter } = arrayUtilities;
22
+ const { clear, filter } = arrayUtilities;
19
23
 
20
24
  export default class DivisionMarkdownNode extends MarkdownNode {
21
25
  constructor(ruleName, childNodes, precedence, opacity, domElement, divisionClassName) {
@@ -74,6 +78,52 @@ export default class DivisionMarkdownNode extends MarkdownNode {
74
78
  return parentNode;
75
79
  }
76
80
 
81
+ paginate(context) {
82
+ const { linesPerPage } = context,
83
+ childNodes = this.getChildNodes(),
84
+ paginatedChildNodes = [],
85
+ divisionMarkdownNodes = [],
86
+ subDivisionReplacements = this.removeSubdivisionMarkdownNodes(pageNumberDirectiveMarkdownNodeFromNode, context);
87
+
88
+ let totalLines = 0;
89
+
90
+ childNodes.forEach((childNode) => {
91
+ const lines = childNode.lines(context),
92
+ paginatedChildNode = childNode; ///
93
+
94
+ totalLines += lines;
95
+
96
+ paginatedChildNodes.push(paginatedChildNode);
97
+
98
+ if (totalLines > linesPerPage) {
99
+ const divisionMarkdownNode = DivisionMarkdownNode.fromSubdivisionReplacementsPaginatedChildNodesAndDivisionClassName(subDivisionReplacements, paginatedChildNodes, this.divisionClassName, context);
100
+
101
+ divisionMarkdownNodes.push(divisionMarkdownNode);
102
+
103
+ clear(paginatedChildNodes);
104
+
105
+ totalLines = 0;
106
+ }
107
+ });
108
+
109
+ if (totalLines > 0) {
110
+ const divisionMarkdownNode = DivisionMarkdownNode.fromSubdivisionReplacementsPaginatedChildNodesAndDivisionClassName(subDivisionReplacements, paginatedChildNodes, this.divisionClassName, context);
111
+
112
+ divisionMarkdownNodes.push(divisionMarkdownNode);
113
+ }
114
+
115
+ return divisionMarkdownNodes;
116
+ }
117
+
118
+ setPageNumber(pageNumber) {
119
+ const node = this,
120
+ pageNumberDirective = pageNumberDirectiveMarkdownNodeFromNode(node);
121
+
122
+ if (pageNumberDirective !== null) {
123
+ pageNumberDirective.setPageNumber(pageNumber);
124
+ }
125
+ }
126
+
77
127
  createContents(context) {
78
128
  let contentsCreated = false;
79
129
 
@@ -108,22 +158,40 @@ export default class DivisionMarkdownNode extends MarkdownNode {
108
158
  return contentsCreated;
109
159
  }
110
160
 
111
- createFootnotes(context) {
112
- const node = this, ///
113
- footnotesDirectiveMarkdownNode = footnotesDirectiveMarkdownNodeFromNode(node);
161
+ createFootnotes(footnoteReplacements, context) {
162
+ if (footnoteReplacements === null) {
163
+ return;
164
+ }
114
165
 
115
- if (footnotesDirectiveMarkdownNode !== null) {
116
- const divisionMarkdownNode = this, ///
117
- footnotesListMarkdownNode = FootnotesListMarkdownNode.fromDivisionMarkdownNode(divisionMarkdownNode, context);
166
+ const divisionMarkdownNode = this, ///
167
+ footnotesListMarkdownNode = FootnotesListMarkdownNode.fromFootnoteReplacementsAndDivisionMarkdownNode(footnoteReplacements, divisionMarkdownNode, context);
118
168
 
119
- if (footnotesListMarkdownNode !== null) {
120
- const childNode = footnotesListMarkdownNode; ///
169
+ if (footnotesListMarkdownNode === null) {
170
+ return;
171
+ }
121
172
 
122
- divisionMarkdownNode.appendChildNode(childNode);
173
+ const node = footnotesListMarkdownNode, ///
174
+ replacement = Replacement.fromNode(node, context);
123
175
 
124
- renumberLinkMarkdownNodes(divisionMarkdownNode, footnotesListMarkdownNode, context)
125
- }
176
+ replacement.appendTo(divisionMarkdownNode, context);
177
+ }
178
+
179
+ prepareFootnotes(context) {
180
+ let subdivisionReplacements;
181
+
182
+ subdivisionReplacements = this.removeSubdivisionMarkdownNodes(footnoteMarkdownNodsFromNode, context);
183
+
184
+ let footnoteReplacements = footnoteReplacementsFromSubdivisionReplacements(subdivisionReplacements);
185
+
186
+ subdivisionReplacements = this.removeSubdivisionMarkdownNodes(footnotesDirectiveMarkdownNodeFromNode, context);
187
+
188
+ const subdivisionReplacementsLength = subdivisionReplacements.length;
189
+
190
+ if (subdivisionReplacementsLength === 0) {
191
+ footnoteReplacements = null;
126
192
  }
193
+
194
+ return footnoteReplacements;
127
195
  }
128
196
 
129
197
  resolveEmbeddings(context) {
@@ -131,14 +199,14 @@ export default class DivisionMarkdownNode extends MarkdownNode {
131
199
  embedDirectiveMarkdownNodes = embedDirectiveMarkdownNodesFromNode(node);
132
200
 
133
201
  embedDirectiveMarkdownNodes.map((embedDirectiveMarkdownNode) => {
134
- const replacementNodeAndTokens = embedDirectiveMarkdownNode.replacementNodeAndTokens(context);
202
+ const replacement = embedDirectiveMarkdownNode.replacement(context);
135
203
 
136
- if (replacementNodeAndTokens !== null) {
204
+ if (replacement !== null) {
137
205
  let tokens;
138
206
 
139
- tokens = replacementNodeAndTokens.getTokens();
207
+ tokens = replacement.getTokens();
140
208
 
141
- const childNodes = replacementNodeAndTokens.getChildNodes(),
209
+ const childNodes = replacement.getChildNodes(),
142
210
  replacementNodes = childNodes, ///
143
211
  replacementTokens = tokens; ///
144
212
 
@@ -155,6 +223,32 @@ export default class DivisionMarkdownNode extends MarkdownNode {
155
223
  });
156
224
  }
157
225
 
226
+ removeSubdivisionMarkdownNodes(markdownNodeFromNode, context) {
227
+ const { tokens } = context,
228
+ node = this, ///
229
+ parentNode = this, ///
230
+ subDivisionMarkdownNodes = subDivisionMarkdownNodesFromNode(node),
231
+ subDivisionReplacements = subDivisionMarkdownNodes.reduce((subDivisionReplacements, subDivisionMarkdownNode) => {
232
+ const node = subDivisionMarkdownNode, ///
233
+ markdownNode = markdownNodeFromNode(node);
234
+
235
+ if (markdownNode !== null) {
236
+ const removedNode = subDivisionMarkdownNode, ///
237
+ subDivisionReplacement = Replacement.fromNode(subDivisionMarkdownNode, context);
238
+
239
+ subDivisionReplacements.push(subDivisionReplacement);
240
+
241
+ removeTokens(removedNode, tokens);
242
+
243
+ removeNode(removedNode, parentNode);
244
+ }
245
+
246
+ return subDivisionReplacements;
247
+ }, []);
248
+
249
+ return subDivisionReplacements;
250
+ }
251
+
158
252
  createFootnotesListMarkdownNode(context) {
159
253
  const divisionMarkdownNode = this, ///
160
254
  footnotesListMarkdownNode = FootnotesListMarkdownNode.fromDivisionMarkdownNode(divisionMarkdownNode, context);
@@ -162,12 +256,6 @@ export default class DivisionMarkdownNode extends MarkdownNode {
162
256
  return footnotesListMarkdownNode;
163
257
  }
164
258
 
165
- removeFootnotesListMarkdownNode(footnotesListMarkdownNode) {
166
- const childNode = footnotesListMarkdownNode; ///
167
-
168
- this.removeChildNode(childNode);
169
- }
170
-
171
259
  asHTML(context) {
172
260
  let html = null;
173
261
 
@@ -194,6 +282,36 @@ ${childNodesHTML}${indent}${closingTag}
194
282
 
195
283
  return divisionMarkdownNode;
196
284
  }
285
+
286
+ static fromSubdivisionReplacementsPaginatedChildNodesAndDivisionClassName(subDivisionReplacements, paginatedChildNodes, divisionClassName, context) {
287
+ const ruleName = DIVISION_RULE_NAME,
288
+ childNodes = [
289
+ ...paginatedChildNodes
290
+ ],
291
+ opacity = null,
292
+ divisionMarkdownNode = MarkdownNode.fromRuleNameChildNodesAndOpacity(DivisionMarkdownNode, ruleName, childNodes, opacity, divisionClassName);
293
+
294
+ subDivisionReplacements.some((subDivisionReplacement) => {
295
+ subDivisionReplacement.appendTo(divisionMarkdownNode, context);
296
+
297
+ return true; ///
298
+ });
299
+
300
+ return divisionMarkdownNode;
301
+ }
302
+ }
303
+
304
+ function footnoteReplacementsFromSubdivisionReplacements(subdivisionReplacements) {
305
+ const footnoteReplacements = subdivisionReplacements.map((subdivisionReplacement) => {
306
+ const node = subdivisionReplacement.getNode(),
307
+ footnoteMarkdownNode = footnoteMarkdownNodsFromNode(node),
308
+ descendentNode = footnoteMarkdownNode, ///
309
+ footnoteReplacement = subdivisionReplacement.contract(descendentNode);
310
+
311
+ return footnoteReplacement;
312
+ });
313
+
314
+ return footnoteReplacements;
197
315
  }
198
316
 
199
317
  function headingMarkdownNodesFromDivisionMarkdownNodeAndContentsDirectiveMarkdownNode(divisionMarkdownNode, contentsDirectiveMarkdownNode, context) {
@@ -10,6 +10,12 @@ import { HREF_ATTRIBUTE_NAME } from "../../attributeNames";
10
10
  const { first, second, secondLast } = arrayUtilities;
11
11
 
12
12
  class EmailLinkMarkdownNode extends MarkdownNode {
13
+ lines(context) {
14
+ const lines = 0;
15
+
16
+ return lines;
17
+ }
18
+
13
19
  inlineText(context) {
14
20
  let inlineText = null;
15
21
 
@@ -5,6 +5,12 @@ import MarkdownNode from "../../node/markdown";
5
5
  import { CARRIAGE_RETURN } from "../../constants";
6
6
 
7
7
  export default class EndOfLineMarkdownNode extends MarkdownNode {
8
+ lines(context) {
9
+ const lines = 0;
10
+
11
+ return lines;
12
+ }
13
+
8
14
  content(context) {
9
15
  const content = CARRIAGE_RETURN;
10
16
 
@@ -19,7 +19,7 @@ export default class FootnoteItemMarkdownNode extends MarkdownNode {
19
19
  return identifier;
20
20
  }
21
21
 
22
- static fromFootnoteMarkdownNodeAndIdentifier(footnoteMarkdownNode, identifier) {
22
+ static fromFootnotesMarkdownNodeAndIdentifier(footnoteMarkdownNode, identifier) {
23
23
  const anchorMarkdownNode = AnchorMarkdownNode.fromIdentifier(identifier),
24
24
  footnoteMarkdownNodeChildNodes = footnoteMarkdownNode.getChildNodes(),
25
25
  secondFootnoteMarkdownNodeChildNode = second(footnoteMarkdownNodeChildNodes),
@@ -1,65 +1,121 @@
1
1
  "use strict";
2
2
 
3
+ import { arrayUtilities } from "necessary";
4
+
3
5
  import MarkdownNode from "../../node/markdown";
4
6
  import FootnoteItemMarkdownNode from "./footnoteItem";
5
7
 
8
+ import { START_ATTRIBUTE_NAME } from "../../attributeNames";
6
9
  import { FOOTNOTES_LIST_RULE_NAME } from "../../ruleNames";
7
- import { linkMarkdownNodesFromNode, footnoteMarkdownNodesFromNode } from "../../utilities/query";
10
+ import { linkMarkdownNodesFromNode } from "../../utilities/query";
11
+
12
+ const { extract } = arrayUtilities;
8
13
 
9
14
  export default class FootnotesListMarkdownNode extends MarkdownNode {
10
- identifierToNumberMap(context) {
11
- const childNodes = this.getChildNodes(),
12
- footnoteItemMarkdownNodes = childNodes, ///
13
- identifierToNumberMap = footnoteItemMarkdownNodes.reduce((identifierToNumberMap, footnoteItemMarkdownNode, index) => {
14
- const number = index + 1,
15
- identifier = footnoteItemMarkdownNode.identifier(context);
15
+ constructor(ruleName, childNodes, opacity, precedence, domElement, start) {
16
+ super(ruleName, childNodes, opacity, precedence, domElement);
17
+
18
+ this.start = start;
19
+ }
20
+
21
+ getStart() {
22
+ return this.start;
23
+ }
24
+
25
+ attributeName(context) {
26
+ const attributeName = START_ATTRIBUTE_NAME;
16
27
 
17
- identifierToNumberMap[identifier] = number;
28
+ return attributeName;
29
+ }
18
30
 
19
- return identifierToNumberMap;
20
- }, {});
31
+ attributeValue(context) {
32
+ const attributeValue = this.start; ///
21
33
 
22
- return identifierToNumberMap;
34
+ return attributeValue;
23
35
  }
24
36
 
25
- static fromDivisionMarkdownNode(divisionMarkdownNode, context) {
37
+ clone() { return super.clone(this.start); }
38
+
39
+ static fromFootnoteReplacementsAndDivisionMarkdownNode(footnoteReplacements, divisionMarkdownNode, context) {
26
40
  let footnotesListMarkdownNode = null;
27
41
 
42
+ const { footnoteNumberMap } = context;
43
+
28
44
  const node = divisionMarkdownNode, ///
45
+ footnoteNumbers = Object.values(footnoteNumberMap),
29
46
  linkMarkdownNodes = linkMarkdownNodesFromNode(node),
30
- footnoteMarkdownNodes = footnoteMarkdownNodesFromNode(node),
31
- footnoteItemMarkdownNodes = [],
32
- identifierToFootnoteMarkdownNodeMap = {};
47
+ footnoteNumbersLength = footnoteNumbers.length,
48
+ footnoteItemReplacements = [];
33
49
 
34
- footnoteMarkdownNodes.forEach((footnoteMarkdownNode) => {
35
- const identifier = footnoteMarkdownNode.identifier(context);
36
-
37
- identifierToFootnoteMarkdownNodeMap[identifier] = footnoteMarkdownNode;
38
- });
50
+ let count = 0;
39
51
 
40
52
  linkMarkdownNodes.forEach((linkMarkdownNode) => {
41
- const identifier = linkMarkdownNode.identifier(context),
42
- footnoteMarkdownNode = identifierToFootnoteMarkdownNodeMap[identifier] || null;
53
+ const identifier = linkMarkdownNode.identifier(context);
54
+
55
+ let footnoteNumber = footnoteNumberMap[identifier] || null;
56
+
57
+ if (footnoteNumber === null) {
58
+ const footnoteReplacement = footnoteReplacementFromFootnoteReplacementsAndIdentifier(footnoteReplacements, identifier, context);
43
59
 
44
- if (footnoteMarkdownNode !== null) {
45
- const footnoteItemMarkdownNode = FootnoteItemMarkdownNode.fromFootnoteMarkdownNodeAndIdentifier(footnoteMarkdownNode, identifier);
60
+ if (footnoteReplacement !== null) {
61
+ const footnoteItemReplacement = footnoteItemReplacementFromFootnoteReplacementAndIdentifier(footnoteReplacement, identifier);
46
62
 
47
- footnoteItemMarkdownNodes.push(footnoteItemMarkdownNode);
63
+ footnoteItemReplacements.push(footnoteItemReplacement);
48
64
 
49
- delete identifierToFootnoteMarkdownNodeMap[identifier];
65
+ count++;
66
+
67
+ footnoteNumber = footnoteNumbersLength + count;
68
+
69
+ footnoteNumberMap[identifier] = footnoteNumber;
70
+ }
71
+ }
72
+
73
+ if (footnoteNumber !== null) {
74
+ const number = footnoteNumber; ///
75
+
76
+ linkMarkdownNode.setNumber(number);
50
77
  }
51
78
  });
52
79
 
53
- const footnoteItemMarkdownNodesLength = footnoteItemMarkdownNodes.length;
80
+ const footnoteItemReplacementsLength = footnoteItemReplacements.length;
54
81
 
55
- if (footnoteItemMarkdownNodesLength > 0) {
82
+ if (footnoteItemReplacementsLength > 0) {
56
83
  const ruleName = FOOTNOTES_LIST_RULE_NAME,
57
- childNodes = footnoteItemMarkdownNodes, ///
58
- opacity = null;
84
+ childNodes = [], ///
85
+ opacity = null,
86
+ start = footnoteNumbersLength + 1;
87
+
88
+ footnotesListMarkdownNode = MarkdownNode.fromRuleNameChildNodesAndOpacity(FootnotesListMarkdownNode, ruleName, childNodes, opacity, start);
59
89
 
60
- footnotesListMarkdownNode = MarkdownNode.fromRuleNameChildNodesAndOpacity(FootnotesListMarkdownNode, ruleName, childNodes, opacity);
90
+ footnoteItemReplacements.forEach((footnotesItemReplacement) => {
91
+ footnotesItemReplacement.appendTo(footnotesListMarkdownNode, context);
92
+ });
61
93
  }
62
94
 
63
95
  return footnotesListMarkdownNode;
64
96
  }
65
97
  }
98
+
99
+ function footnoteReplacementFromFootnoteReplacementsAndIdentifier(footnoteReplacements, identifier, context) {
100
+ const footnoteReplacement = extract(footnoteReplacements, (footnoteReplacement) => {
101
+ const node = footnoteReplacement.getNode(),
102
+ footnoteMarkdownNode = node, ///
103
+ footnoteMarkdownNodeIdentifier = footnoteMarkdownNode.identifier(context);
104
+
105
+ if (footnoteMarkdownNodeIdentifier === identifier) {
106
+ return true;
107
+ }
108
+ }) || null;
109
+
110
+ return footnoteReplacement;
111
+ }
112
+
113
+ function footnoteItemReplacementFromFootnoteReplacementAndIdentifier(footnoteReplacement, identifier) {
114
+ const node = footnoteReplacement.getNode(),
115
+ footnoteMarkdownNode = node, ///
116
+ footnoteItemMarkdownNode = FootnoteItemMarkdownNode.fromFootnotesMarkdownNodeAndIdentifier(footnoteMarkdownNode, identifier),
117
+ ascendantNode = footnoteItemMarkdownNode, ///
118
+ footnoteItemReplacement = footnoteReplacement.expand(ascendantNode);
119
+
120
+ return footnoteItemReplacement;
121
+ }
@@ -3,6 +3,8 @@
3
3
  import HeadingMarkdownNode from "../../../node/markdown/heading";
4
4
 
5
5
  export default class PrimaryHeadingMarkdownNode extends HeadingMarkdownNode {
6
+ static lines = 3;
7
+
6
8
  static depth = 1;
7
9
 
8
10
  static fromRuleNameChildNodesAndOpacity(ruleName, childNodes, opacity) { return HeadingMarkdownNode.fromRuleNameChildNodesAndOpacity(PrimaryHeadingMarkdownNode, ruleName, childNodes, opacity); }
@@ -3,6 +3,8 @@
3
3
  import HeadingMarkdownNode from "../../../node/markdown/heading";
4
4
 
5
5
  export default class QuaternaryHeadingMarkdownNode extends HeadingMarkdownNode {
6
+ static lines = 2;
7
+
6
8
  static depth = 4;
7
9
 
8
10
  static fromRuleNameChildNodesAndOpacity(ruleName, childNodes, opacity) { return HeadingMarkdownNode.fromRuleNameChildNodesAndOpacity(QuaternaryHeadingMarkdownNode, ruleName, childNodes, opacity); }
@@ -3,6 +3,8 @@
3
3
  import HeadingMarkdownNode from "../../../node/markdown/heading";
4
4
 
5
5
  export default class SecondaryHeadingMarkdownNode extends HeadingMarkdownNode {
6
+ static lines = 2.5;
7
+
6
8
  static depth = 2;
7
9
 
8
10
  static fromRuleNameChildNodesAndOpacity(ruleName, childNodes, opacity) { return HeadingMarkdownNode.fromRuleNameChildNodesAndOpacity(SecondaryHeadingMarkdownNode, ruleName, childNodes, opacity); }
@@ -3,6 +3,8 @@
3
3
  import HeadingMarkdownNode from "../../../node/markdown/heading";
4
4
 
5
5
  export default class TertiaryHeadingMarkdownNode extends HeadingMarkdownNode {
6
+ static lines = 2.25;
7
+
6
8
  static depth = 3;
7
9
 
8
10
  static fromRuleNameChildNodesAndOpacity(ruleName, childNodes, opacity) { return HeadingMarkdownNode.fromRuleNameChildNodesAndOpacity(TertiaryHeadingMarkdownNode, ruleName, childNodes, opacity); }
@@ -11,6 +11,12 @@ import { replaceSpacesWithHyphens, removedLeadingWhitespace, removeNonAlphabetic
11
11
  const { last } = arrayUtilities;
12
12
 
13
13
  export default class HeadingMarkdownNode extends MarkdownNode {
14
+ lines(context) {
15
+ const { lines } = this.constructor;
16
+
17
+ return lines;
18
+ }
19
+
14
20
  getDepth() {
15
21
  const { depth } = this.constructor;
16
22
 
@@ -2,9 +2,20 @@
2
2
 
3
3
  import MarkdownNode from "../../node/markdown";
4
4
 
5
- import { htmlFromChildNodes, domElementsFromChildNodes } from "../../utilities/childNodes";
5
+ import { htmlFromChildNodes, plainTextFromChildNodes, domElementsFromChildNodes } from "../../utilities/childNodes";
6
6
 
7
7
  export default class LineMarkdownNode extends MarkdownNode {
8
+ lines(context) {
9
+ const { charactersPerLine } = context,
10
+ childNodes = this.getChildNodes(),
11
+ plainText = plainTextFromChildNodes(childNodes, context),
12
+ plainTextLength = plainText.length,
13
+ characters = plainTextLength, ///
14
+ lines = (characters / charactersPerLine) + 1;
15
+
16
+ return lines;
17
+ }
18
+
8
19
  asHTML(indent, context) {
9
20
  indent = this.adjustIndent(indent);
10
21
 
@@ -8,42 +8,48 @@ const { second } = arrayUtilities;
8
8
 
9
9
  export default class SubDivisionMarkdownNode extends MarkdownNode {
10
10
  getDOMElement() {
11
- const markdownNode = this.getMarkdownNode(),
12
- domElement = markdownNode.getDOMElement();
11
+ const secondMarkdownNode = this.getSecondMarkdownNode(),
12
+ domElement = secondMarkdownNode.getDOMElement();
13
13
 
14
14
  return domElement;
15
15
  }
16
16
 
17
17
  getDOMElements() {
18
- const markdownNode = this.getMarkdownNode(),
19
- domElements = markdownNode.getDOMElements();
18
+ const secondMarkdownNode = this.getSecondMarkdownNode(),
19
+ domElements = secondMarkdownNode.getDOMElements();
20
20
 
21
21
  return domElements;
22
22
  }
23
23
 
24
+ lines(context) {
25
+ const secondMarkdownNode = this.getSecondMarkdownNode(),
26
+ lines = secondMarkdownNode.lines(context);
27
+
28
+ return lines;
29
+ }
30
+
24
31
  asHTML(indent, context) {
25
- const markdownNode = this.getMarkdownNode(),
26
- markdownNodeHTML = markdownNode.asHTML(indent, context),
27
- html = markdownNodeHTML; ///
32
+ const secondMarkdownNode = this.getSecondMarkdownNode(),
33
+ html = secondMarkdownNode.asHTML(indent, context);
28
34
 
29
35
  return html;
30
36
  }
31
37
 
32
38
  createDOMElement(context) {
33
39
  const domElement = null,
34
- markdownNode = this.getMarkdownNode();
40
+ secondMarkdownNode = this.getSecondMarkdownNode();
35
41
 
36
- markdownNode.createDOMElement(context);
42
+ secondMarkdownNode.createDOMElement(context);
37
43
 
38
44
  return domElement;
39
45
  }
40
46
 
41
- getMarkdownNode() {
47
+ getSecondMarkdownNode() {
42
48
  const childNodes = this.getChildNodes(),
43
49
  secondChildNode = second(childNodes),
44
- markdownNode = secondChildNode; ///
50
+ secondMarkdownNode = secondChildNode; ///
45
51
 
46
- return markdownNode;
52
+ return secondMarkdownNode;
47
53
  }
48
54
 
49
55
  static fromRuleNameChildNodesAndOpacity(ruleName, childNodes, opacity) {
@@ -132,6 +132,25 @@ class MarkdownNode extends NonTerminalNode {
132
132
  });
133
133
  }
134
134
 
135
+ lines(context) {
136
+ const childNodes = this.getChildNodes(),
137
+ lines = childNodes.reduce((lines, childNode) => {
138
+ const childNodeNonTerminalNode = childNode.isNonTerminalNode();
139
+
140
+ if (childNodeNonTerminalNode) {
141
+ const nonTerminalNode = childNode, ///
142
+ markdownNode = nonTerminalNode, ///
143
+ markdownNodeLines = markdownNode.lines(context);
144
+
145
+ lines += markdownNodeLines;
146
+ }
147
+
148
+ return lines;
149
+ }, 0);
150
+
151
+ return lines;
152
+ }
153
+
135
154
  asHTML(indent, context) {
136
155
  const tagName = this.tagName(context);
137
156