Created
February 18, 2017 08:47
-
-
Save Rokt33r/1e109b8ead365c378335175b3d61b98a to your computer and use it in GitHub Desktop.
Unknown MDAST nodes are not compiled to DIV
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"type": "root", | |
"children": [ | |
{ | |
"type": "paragraph", | |
"children": [ | |
{ | |
"type": "text", | |
"value": "Inline math! ", | |
"position": { | |
"start": { | |
"line": 2, | |
"column": 1, | |
"offset": 1 | |
}, | |
"end": { | |
"line": 2, | |
"column": 14, | |
"offset": 14 | |
}, | |
"indent": [] | |
} | |
}, | |
{ | |
"type": "inlineMath", | |
"value": "\\alpha", | |
"position": { | |
"start": { | |
"line": 2, | |
"column": 14, | |
"offset": 14 | |
}, | |
"end": { | |
"line": 2, | |
"column": 22, | |
"offset": 22 | |
}, | |
"indent": [] | |
} | |
} | |
], | |
"position": { | |
"start": { | |
"line": 2, | |
"column": 1, | |
"offset": 1 | |
}, | |
"end": { | |
"line": 2, | |
"column": 22, | |
"offset": 22 | |
}, | |
"indent": [] | |
} | |
}, | |
{ | |
"type": "paragraph", | |
"children": [ | |
{ | |
"type": "text", | |
"value": "Math block", | |
"position": { | |
"start": { | |
"line": 4, | |
"column": 1, | |
"offset": 24 | |
}, | |
"end": { | |
"line": 4, | |
"column": 11, | |
"offset": 34 | |
}, | |
"indent": [] | |
} | |
} | |
], | |
"position": { | |
"start": { | |
"line": 4, | |
"column": 1, | |
"offset": 24 | |
}, | |
"end": { | |
"line": 4, | |
"column": 11, | |
"offset": 34 | |
}, | |
"indent": [] | |
} | |
}, | |
{ | |
"type": "math", | |
"value": "\\beta", | |
"data": { | |
"hName": "div", | |
"hChildren": [ | |
{ | |
"type": "text", | |
"value": "\\beta" | |
} | |
], | |
"hProperties": { | |
"class": "math" | |
} | |
}, | |
"position": { | |
"start": { | |
"line": 6, | |
"column": 1, | |
"offset": 36 | |
}, | |
"end": { | |
"line": 8, | |
"column": 3, | |
"offset": 47 | |
}, | |
"indent": [ | |
1, | |
1 | |
] | |
} | |
}, | |
{ | |
"type": "paragraph", | |
"children": [ | |
{ | |
"type": "text", | |
"value": "Below code should not be parsed as Math block", | |
"position": { | |
"start": { | |
"line": 10, | |
"column": 1, | |
"offset": 49 | |
}, | |
"end": { | |
"line": 10, | |
"column": 46, | |
"offset": 94 | |
}, | |
"indent": [] | |
} | |
} | |
], | |
"position": { | |
"start": { | |
"line": 10, | |
"column": 1, | |
"offset": 49 | |
}, | |
"end": { | |
"line": 10, | |
"column": 46, | |
"offset": 94 | |
}, | |
"indent": [] | |
} | |
}, | |
{ | |
"type": "code", | |
"lang": null, | |
"value": "$$\n\\gamma\n$$", | |
"position": { | |
"start": { | |
"line": 12, | |
"column": 1, | |
"offset": 96 | |
}, | |
"end": { | |
"line": 16, | |
"column": 4, | |
"offset": 116 | |
}, | |
"indent": [ | |
1, | |
1, | |
1, | |
1 | |
] | |
} | |
} | |
], | |
"position": { | |
"start": { | |
"line": 1, | |
"column": 1, | |
"offset": 0 | |
}, | |
"end": { | |
"line": 17, | |
"column": 1, | |
"offset": 117 | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var trim = require('trim-trailing-lines') | |
/* Characters */ | |
var C_NEWLINE = '\n' | |
var C_TAB = '\t' | |
var C_SPACE = ' ' | |
var C_DOLLAR = '$' | |
/* Constants */ | |
var MIN_FENCE_COUNT = 2 | |
var CODE_INDENT_COUNT = 4 | |
/** | |
* Tokenise fenced code. | |
* | |
* @property {Function} locator. | |
* @param {function(string)} eat - Eater. | |
* @param {string} value - Rest of content. | |
* @param {boolean?} [silent] - Whether this is a dry run. | |
* @return {Node?|boolean} - `code` node. | |
*/ | |
function blockTokenizer (eat, value, silent) { | |
var self = this | |
var length = value.length + 1 | |
var index = 0 | |
var subvalue = '' | |
var fenceCount | |
var marker | |
var character | |
var flag | |
var queue | |
var content | |
var exdentedContent | |
var closing | |
var exdentedClosing | |
var indent | |
var now | |
/* Eat initial spacing. */ | |
while (index < length) { | |
character = value.charAt(index) | |
if (character !== C_SPACE && character !== C_TAB) { | |
break | |
} | |
subvalue += character | |
index++ | |
} | |
indent = index | |
/* Eat the fence. */ | |
character = value.charAt(index) | |
if (character !== C_DOLLAR) { | |
return | |
} | |
index++ | |
marker = character | |
fenceCount = 1 | |
subvalue += character | |
while (index < length) { | |
character = value.charAt(index) | |
if (character !== marker) { | |
break | |
} | |
subvalue += character | |
fenceCount++ | |
index++ | |
} | |
if (fenceCount < MIN_FENCE_COUNT) { | |
return | |
} | |
/* Eat spacing before flag. */ | |
while (index < length) { | |
character = value.charAt(index) | |
if (character !== C_SPACE && character !== C_TAB) { | |
break | |
} | |
subvalue += character | |
index++ | |
} | |
/* Eat flag. */ | |
flag = queue = '' | |
while (index < length) { | |
character = value.charAt(index) | |
if ( | |
character === C_NEWLINE || | |
character === C_DOLLAR | |
) { | |
break | |
} | |
if (character === C_SPACE || character === C_TAB) { | |
queue += character | |
} else { | |
flag += queue + character | |
queue = '' | |
} | |
index++ | |
} | |
character = value.charAt(index) | |
if (character && character !== C_NEWLINE) { | |
return | |
} | |
if (silent) { | |
return true | |
} | |
now = eat.now() | |
now.column += subvalue.length | |
now.offset += subvalue.length | |
subvalue += flag | |
flag = self.decode.raw(self.unescape(flag), now) | |
if (queue) { | |
subvalue += queue | |
} | |
queue = closing = exdentedClosing = content = exdentedContent = '' | |
/* Eat content. */ | |
while (index < length) { | |
character = value.charAt(index) | |
content += closing | |
exdentedContent += exdentedClosing | |
closing = exdentedClosing = '' | |
if (character !== C_NEWLINE) { | |
content += character | |
exdentedClosing += character | |
index++ | |
continue | |
} | |
/* Add the newline to `subvalue` if its the first | |
* character. Otherwise, add it to the `closing` | |
* queue. */ | |
if (content) { | |
closing += character | |
exdentedClosing += character | |
} else { | |
subvalue += character | |
} | |
queue = '' | |
index++ | |
while (index < length) { | |
character = value.charAt(index) | |
if (character !== C_SPACE) { | |
break | |
} | |
queue += character | |
index++ | |
} | |
closing += queue | |
exdentedClosing += queue.slice(indent) | |
if (queue.length >= CODE_INDENT_COUNT) { | |
continue | |
} | |
queue = '' | |
while (index < length) { | |
character = value.charAt(index) | |
if (character !== marker) { | |
break | |
} | |
queue += character | |
index++ | |
} | |
closing += queue | |
exdentedClosing += queue | |
if (queue.length < fenceCount) { | |
continue | |
} | |
queue = '' | |
while (index < length) { | |
character = value.charAt(index) | |
if (character !== C_SPACE && character !== C_TAB) { | |
break | |
} | |
closing += character | |
exdentedClosing += character | |
index++ | |
} | |
if (!character || character === C_NEWLINE) { | |
break | |
} | |
} | |
subvalue += content + closing | |
const trimmedValue = trim(exdentedContent) | |
return eat(subvalue)({ | |
type: 'math', | |
value: trimmedValue, | |
data: { | |
hName: 'div', | |
hChildren: [{ | |
type: 'text', | |
value: trimmedValue | |
}], | |
hProperties: { | |
class: 'math' | |
} | |
} | |
}) | |
} | |
module.exports = function plugin (p) { | |
const Parser = p.Parser | |
const blockTokenizers = Parser.prototype.blockTokenizers | |
const blockMethods = Parser.prototype.blockMethods | |
blockTokenizers.math = blockTokenizer | |
blockMethods.splice(blockMethods.indexOf('fencedCode') + 1, 0, 'math') | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function locator (value, fromIndex) { | |
return value.indexOf('$', fromIndex) | |
} | |
const INLINE_MATH = /^\$((?:\\\$|[^$])+)\$/ | |
function inlineTokenizer (eat, value, silent) { | |
const match = INLINE_MATH.exec(value) | |
if (match) { | |
if (silent) { | |
return true | |
} | |
return eat(match[0])({ | |
type: 'inlineMath', | |
value: match[1].trim() | |
}) | |
} | |
} | |
inlineTokenizer.locator = locator | |
inlineTokenizer.notInLink = true | |
module.exports = function plugin (p) { | |
const Parser = p.Parser | |
// Inline math | |
const inlineTokenizers = Parser.prototype.inlineTokenizers | |
const inlineMethods = Parser.prototype.inlineMethods | |
inlineTokenizers.math = inlineTokenizer | |
inlineMethods.splice(inlineMethods.indexOf('text'), 0, 'math') | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<p>Inline math! \alpha</p> | |
<p>Math block</p> | |
\beta | |
<p>Below code should not be parsed as Math block</p> | |
<pre><code>$$ | |
\gamma | |
$$ | |
</code></pre> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const text = ` | |
Inline math! $\\alpha$ | |
Math block | |
$$ | |
\\beta | |
$$ | |
Below code should not be parsed as Math block | |
\`\`\` | |
$$ | |
\\gamma | |
$$ | |
\`\`\` | |
` | |
const processor = remark().use(p => { | |
inlineParser(p) | |
blockParser(p) | |
}) | |
const ast = processor.parse(text) | |
const htmlString = processor.stringify(ast) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment