Files
30-seconds-of-code/node_modules/parse-latin/lib/plugin/merge-inner-word-symbol.js
2019-08-20 15:52:05 +02:00

83 lines
2.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict'
var toString = require('nlcst-to-string')
var modifyChildren = require('unist-util-modify-children')
var expressions = require('../expressions')
module.exports = modifyChildren(mergeInnerWordSymbol)
// Symbols part of surrounding words.
var wordSymbolInner = expressions.wordSymbolInner
// Merge words joined by certain punctuation marks.
function mergeInnerWordSymbol(child, index, parent) {
var siblings
var sibling
var prev
var last
var position
var tokens
var queue
if (
index !== 0 &&
(child.type === 'SymbolNode' || child.type === 'PunctuationNode')
) {
siblings = parent.children
prev = siblings[index - 1]
if (prev && prev.type === 'WordNode') {
position = index - 1
tokens = []
queue = []
// - If a token which is neither word nor inner word symbol is found,
// the loop is broken
// - If an inner word symbol is found, its queued
// - If a word is found, its queued (and the queue stored and emptied)
while (siblings[++position]) {
sibling = siblings[position]
if (sibling.type === 'WordNode') {
tokens = tokens.concat(queue, sibling.children)
queue = []
} else if (
(sibling.type === 'SymbolNode' ||
sibling.type === 'PunctuationNode') &&
wordSymbolInner.test(toString(sibling))
) {
queue.push(sibling)
} else {
break
}
}
if (tokens.length !== 0) {
// If there is a queue, remove its length from `position`.
if (queue.length !== 0) {
position -= queue.length
}
// Remove every (one or more) inner-word punctuation marks and children
// of words.
siblings.splice(index, position - index)
// Add all found tokens to `prev`s children.
prev.children = prev.children.concat(tokens)
last = tokens[tokens.length - 1]
// Update position.
if (prev.position && last.position) {
prev.position.end = last.position.end
}
// Next, iterate over the node *now* at the current position.
return index
}
}
}
}