1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | 'use strict';
|
15 |
|
16 | const {
|
17 | NS_PREFIX_CommonMarkModel
|
18 | } = require('@accordproject/markdown-common').CommonMarkModel;
|
19 |
|
20 | const jsdom = typeof DOMParser === 'undefined' ? require('jsdom') : null;
|
21 |
|
22 | const typeOf = require('type-of');
|
23 |
|
24 | const defaultRules = require('./rules');
|
25 |
|
26 | const JSDOM = jsdom ? jsdom.JSDOM : null;
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | class ToCiceroMarkVisitor {
|
33 | |
34 |
|
35 |
|
36 |
|
37 | constructor() {
|
38 | let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
39 | let {
|
40 | rules = []
|
41 | } = options;
|
42 | this.options = options;
|
43 | this.rules = [...rules, ...defaultRules];
|
44 | }
|
45 | |
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 | cruftNewline(element) {
|
54 | return !(element.nodeName === '#text' && element.nodeValue === '\n');
|
55 | }
|
56 | |
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 | deserializeElement(element) {
|
65 | let node;
|
66 |
|
67 | if (!element.tagName) {
|
68 | element.tagName = '';
|
69 | }
|
70 |
|
71 | const next = elements => {
|
72 | if (Object.prototype.toString.call(elements) === '[object NodeList]') {
|
73 | elements = Array.from(elements);
|
74 | }
|
75 |
|
76 | switch (typeOf(elements)) {
|
77 | case 'array':
|
78 | return this.deserializeElements(elements);
|
79 |
|
80 | case 'object':
|
81 | return this.deserializeElement(elements);
|
82 |
|
83 | case 'null':
|
84 | case 'undefined':
|
85 | return;
|
86 |
|
87 | default:
|
88 | throw new Error("The `next` argument was called with invalid children: \"".concat(elements, "\"."));
|
89 | }
|
90 | };
|
91 |
|
92 | for (const rule of this.rules) {
|
93 | if (!rule.deserialize) {
|
94 | continue;
|
95 | }
|
96 |
|
97 | const ret = rule.deserialize(element, next);
|
98 | const type = typeOf(ret);
|
99 |
|
100 | if (type !== 'array' && type !== 'object' && type !== 'null' && type !== 'undefined') {
|
101 | throw new Error("A rule returned an invalid deserialized representation: \"".concat(node, "\"."));
|
102 | }
|
103 |
|
104 | if (ret === undefined) {
|
105 | continue;
|
106 | } else if (ret === null) {
|
107 | return null;
|
108 |
|
109 | } else {
|
110 | node = ret;
|
111 | }
|
112 |
|
113 | if (node.object === 'block' || node.object === 'inline') {
|
114 | node.data = node.data || {};
|
115 | node.nodes = node.nodes || [];
|
116 | } else if (node.object === 'text') {
|
117 | node.marks = node.marks || [];
|
118 | node.text = node.text || '';
|
119 | }
|
120 |
|
121 | break;
|
122 | }
|
123 |
|
124 | return node || next(element.childNodes);
|
125 | }
|
126 | |
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 | deserializeElements() {
|
135 | let elements = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
136 | let nodes = [];
|
137 | elements.filter(this.cruftNewline).forEach(element => {
|
138 |
|
139 | const node = this.deserializeElement(element);
|
140 |
|
141 | switch (typeOf(node)) {
|
142 | case 'array':
|
143 | nodes = nodes.concat(node);
|
144 | break;
|
145 |
|
146 | case 'object':
|
147 | nodes.push(node);
|
148 | break;
|
149 | }
|
150 | });
|
151 | return nodes;
|
152 | }
|
153 | |
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 | toCiceroMark(input) {
|
163 | let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'concerto';
|
164 | let fragment;
|
165 |
|
166 | if (typeof DOMParser === 'undefined') {
|
167 | fragment = JSDOM.fragment(input);
|
168 | } else {
|
169 |
|
170 | fragment = new DOMParser().parseFromString(input, 'text/html');
|
171 | }
|
172 |
|
173 | const children = Array.from(fragment.childNodes);
|
174 |
|
175 | const nodes = this.deserializeElements(children);
|
176 |
|
177 | return {
|
178 | '$class': "".concat(NS_PREFIX_CommonMarkModel, 'Document'),
|
179 | nodes,
|
180 | xmlns: 'http://commonmark.org/xml/1.0'
|
181 | };
|
182 | }
|
183 |
|
184 | }
|
185 |
|
186 | module.exports = ToCiceroMarkVisitor; |
\ | No newline at end of file |