Skip to content

Commit b0a8229

Browse files
committed
fix(Slate) Redo emphasis support, including for inlines #148
Signed-off-by: Jerome Simeon <[email protected]>
1 parent 8d89241 commit b0a8229

File tree

2 files changed

+127
-68
lines changed

2 files changed

+127
-68
lines changed

packages/markdown-slate/src/ToSlateVisitor.js

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,25 @@ class ToSlateVisitor {
2121

2222
/**
2323
* Converts a sub-tree of formatting nodes to an array of marks
24-
* @param {*} thing a concerto Strong, Emph or Text node
25-
* @param {*} marks an initial set of marks
24+
* @param {*} parameters the parameters
2625
* @returns {*} the array of slate marks to use
2726
*/
28-
static getMarks(thing, marks) {
29-
let result = Array.from(marks);
27+
static getMarks(parameters) {
28+
let result = [];
3029

31-
switch(thing.getType()) {
32-
case 'Strong':
30+
if (parameters.emph) {
3331
result.push({
3432
object: 'mark',
35-
type: 'bold',
33+
type: 'italic',
3634
data: {}
3735
});
38-
break;
39-
case 'Emph':
36+
}
37+
if (parameters.strong) {
4038
result.push({
4139
object: 'mark',
42-
type: 'italic',
40+
type: 'bold',
4341
data: {}
4442
});
45-
break;
46-
}
47-
48-
// recurse on child nodes
49-
if(thing.nodes && thing.nodes.length > 0) {
50-
result = ToSlateVisitor.getMarks(thing.nodes[0], result);
5143
}
5244

5345
return result;
@@ -67,7 +59,7 @@ class ToSlateVisitor {
6759
return ToSlateVisitor.getText(thing.nodes[0]);
6860
}
6961
else {
70-
return null;
62+
return '';
7163
}
7264
}
7365
}
@@ -92,32 +84,62 @@ class ToSlateVisitor {
9284
/**
9385
* Converts a formatted text node to a slate text node with marks
9486
* @param {*} thing a concerto Strong, Emph or Text node
87+
* @param {*} parameters the parameters
9588
* @returns {*} the slate text node with marks
9689
*/
97-
static handleFormattedText(thing) {
90+
static handleFormattedText(thing, parameters) {
9891
return {
9992
object: 'text',
10093
text: ToSlateVisitor.getText(thing),
101-
marks: ToSlateVisitor.getMarks(thing, []),
94+
marks: ToSlateVisitor.getMarks(parameters),
95+
};
96+
}
97+
98+
/**
99+
* Converts a formatted inline node to a slate text node with marks
100+
* @param {*} type - the type of inline
101+
* @param {*} data - the data for the inline
102+
* @param {*} text - the text for the inline
103+
* @param {*} parameters the parameters
104+
* @returns {*} the slate text node with marks
105+
*/
106+
static handleInline(type, data, text, parameters) {
107+
return {
108+
object: 'inline',
109+
type: type,
110+
data: data,
111+
nodes: [{
112+
object: 'text',
113+
text: text,
114+
marks: ToSlateVisitor.getMarks(parameters),
115+
}],
102116
};
103117
}
104118

105119
/**
106120
* Returns the processed child nodes
107121
* @param {*} thing a concerto ast nodes
122+
* @param {*} parameters the parameters
108123
* @returns {*} an array of slate nodes
109124
*/
110-
processChildNodes(thing) {
125+
processChildNodes(thing,parameters) {
111126
const result = [];
112127
if(!thing.nodes) {
113128
thing.nodes = []; // Treat no nodes as empty array of nods
114129
}
115130

116131
thing.nodes.forEach(node => {
117132
//console.log(`Processing ${thing.getType()} > ${node.getType()}`);
118-
const child = {};
119-
node.accept(this, child);
120-
result.push(child.result);
133+
const newParameters = {
134+
strong: parameters.strong,
135+
emph: parameters.emph,
136+
};
137+
node.accept(this, newParameters);
138+
if (Array.isArray(newParameters.result)) {
139+
Array.prototype.push.apply(result,newParameters.result);
140+
} else {
141+
result.push(newParameters.result);
142+
}
121143
});
122144

123145
return result;
@@ -141,45 +163,17 @@ class ToSlateVisitor {
141163
clauseid: thing.clauseid,
142164
src: thing.src
143165
},
144-
nodes: this.processChildNodes(thing),
166+
nodes: this.processChildNodes(thing,parameters),
145167
};
146168
break;
147169
case 'Variable':
148-
result = {
149-
object: 'inline',
150-
type: 'variable',
151-
data: {
152-
id: thing.id,
153-
},
154-
nodes: [{
155-
object: 'text',
156-
text: thing.value,
157-
}],
158-
};
170+
result = ToSlateVisitor.handleInline('variable', { id: thing.id }, thing.value, parameters);
159171
break;
160172
case 'ConditionalVariable':
161-
result = {
162-
object: 'inline',
163-
type: 'conditional',
164-
data: {
165-
id: thing.id,
166-
},
167-
nodes: [{
168-
object: 'text',
169-
text: thing.value,
170-
}],
171-
};
173+
result = ToSlateVisitor.handleInline('conditional', { id: thing.id }, thing.value, parameters);
172174
break;
173175
case 'ComputedVariable':
174-
result = {
175-
object: 'inline',
176-
type: 'computed',
177-
data: {},
178-
nodes: [{
179-
object: 'text',
180-
text: thing.value,
181-
}],
182-
};
176+
result = ToSlateVisitor.handleInline('computed', {}, thing.value, parameters);
183177
break;
184178
case 'CodeBlock':
185179
result = {
@@ -212,23 +206,29 @@ class ToSlateVisitor {
212206
};
213207
break;
214208
case 'Emph':
209+
parameters.emph = true;
210+
result = this.processChildNodes(thing,parameters);
211+
break;
215212
case 'Strong':
213+
parameters.strong = true;
214+
result = this.processChildNodes(thing,parameters);
215+
break;
216216
case 'Text':
217-
result = ToSlateVisitor.handleFormattedText(thing);
217+
result = ToSlateVisitor.handleFormattedText(thing, parameters);
218218
break;
219219
case 'BlockQuote':
220220
result = {
221221
object: 'block',
222222
type: 'block_quote',
223-
nodes: this.processChildNodes(thing)
223+
nodes: this.processChildNodes(thing,parameters)
224224
};
225225
break;
226226
case 'Heading':
227227
result = {
228228
'object': 'block',
229229
'data': {},
230230
'type': ToSlateVisitor.getHeadingType(thing),
231-
'nodes': this.processChildNodes(thing)
231+
'nodes': this.processChildNodes(thing,parameters)
232232
};
233233
break;
234234
case 'ThematicBreak':
@@ -288,7 +288,7 @@ class ToSlateVisitor {
288288
result = {
289289
'object': 'block',
290290
'type': 'paragraph',
291-
'nodes': this.processChildNodes(thing),
291+
'nodes': this.processChildNodes(thing,parameters),
292292
'data': {}
293293
};
294294
break;
@@ -321,7 +321,7 @@ class ToSlateVisitor {
321321
'object': 'block',
322322
'data': { tight: thing.tight, start: thing.start, delimiter: thing.delimiter},
323323
'type': thing.type === 'ordered' ? 'ol_list' : 'ul_list',
324-
'nodes': this.processChildNodes(thing)
324+
'nodes': this.processChildNodes(thing,parameters)
325325
};
326326
break;
327327
case 'ListVariable':
@@ -330,21 +330,21 @@ class ToSlateVisitor {
330330
'object': 'block',
331331
'data': { tight: thing.tight, start: thing.start, delimiter: thing.delimiter, kind: 'variable' },
332332
'type': thing.type === 'ordered' ? 'ol_list' : 'ul_list',
333-
'nodes': this.processChildNodes(thing)
333+
'nodes': this.processChildNodes(thing,parameters)
334334
};
335335
break;
336336
case 'Item':
337337
result = {
338338
'object': 'block',
339339
'type': 'list_item',
340340
'data': {},
341-
'nodes': this.processChildNodes(thing)
341+
'nodes': this.processChildNodes(thing,parameters)
342342
};
343343
break;
344344
case 'Document':
345345
result = {
346346
'object': 'document',
347-
'nodes': this.processChildNodes(thing),
347+
'nodes': this.processChildNodes(thing,parameters),
348348
'data' : {}
349349
};
350350
break;

packages/markdown-slate/src/slateToCiceroMarkDom.js

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,9 @@ function _recursive(parent, nodes) {
7777
result = {$class : `${NS_CICERO}.Clause`, clauseid: node.data.clauseid, src: node.data.src, nodes: []};
7878
break;
7979
case 'variable':
80-
result = {$class : `${NS_CICERO}.Variable`, id: node.data.id, value: node.nodes[0].text};
81-
break;
8280
case 'conditional':
83-
result = {$class : `${NS_CICERO}.ConditionalVariable`, id: node.data.id, value: node.nodes[0].text};
84-
break;
8581
case 'computed':
86-
result = {$class : `${NS_CICERO}.ComputedVariable`, value: node.nodes[0].text};
82+
result = handleInline(node);
8783
break;
8884
case 'paragraph':
8985
result = {$class : `${NS}.Paragraph`, nodes: []};
@@ -219,4 +215,67 @@ function handleText(node) {
219215
return result;
220216
}
221217

218+
/**
219+
* Handles an inline node
220+
* @param {*} node the slate inline node
221+
* @returns {*} the ast node
222+
*/
223+
function handleInline(node) {
224+
225+
let strong = null;
226+
let emph = null;
227+
let result = null;
228+
229+
const textNode = node.nodes[0]; // inlines always contain a single text node
230+
node.nodes = []; // Reset the children for the inline to avoid recursion
231+
232+
const isBold = textNode.marks.some(mark => mark.type === 'bold');
233+
const isItalic = textNode.marks.some(mark => mark.type === 'italic');
234+
235+
const type = node.type;
236+
const baseName = type === 'variable' ? 'Variable' : type === 'conditional' ? 'ConditionalVariable' : 'ComputedVariable';
237+
const className = `${NS_CICERO}.${baseName}`;
238+
239+
const inline = {
240+
$class : className,
241+
value : textNode.text
242+
};
243+
244+
const data = node.data;
245+
if (data.id) {
246+
inline.id = data.id;
247+
}
248+
249+
if (isBold) {
250+
strong = {$class : `${NS}.Strong`, nodes: []};
251+
}
252+
253+
if (isItalic) {
254+
emph = {$class : `${NS}.Emph`, nodes: []};
255+
}
256+
257+
if(strong && emph) {
258+
result = emph;
259+
emph.nodes.push(strong);
260+
strong.nodes.push(inline);
261+
}
262+
else {
263+
if(strong) {
264+
result = strong;
265+
strong.nodes.push(inline);
266+
}
267+
268+
if(emph) {
269+
result = emph;
270+
emph.nodes.push(inline);
271+
}
272+
}
273+
274+
if(!result) {
275+
result = inline;
276+
}
277+
278+
return result;
279+
}
280+
222281
module.exports = slateToCiceroMarkDom;

0 commit comments

Comments
 (0)