UNPKG

1.96 kBJavaScriptView Raw
1'use strict'
2
3/**
4 * This function runs through the message looking for tokens. As it finds a
5 * token matching a wrapper, it pushes the parent in the tree on a stack, and
6 * collects children for that wrapper until the ending token is found.
7 */
8module.exports = function formatChildren (applyChildren, message, wrappers) {
9 if (!wrappers) return message
10 var mm = message.length
11 var stack = []
12 var current = []
13 var currentKey
14 var curlyDepth = 0
15 var last = 0
16 for (var m = 0; m < mm; ++m) {
17 if (message[m] === '{') ++curlyDepth
18 if (message[m] === '}') --curlyDepth
19 if (message[m] !== '<' || curlyDepth % 2 === 1) continue
20
21 var isSelfClosing = false
22 var isEnd = false
23
24 var s = m + 1 // skip <
25 if (message[s] === '/') {
26 isEnd = true
27 ++s
28 }
29
30 var e = s
31 while (message[e] >= '0' && message[e] <= '9') { ++e }
32 if (!isEnd && message.slice(e, e + 2) === '/>') {
33 isSelfClosing = true
34 } else if (message[e] !== '>') {
35 continue
36 }
37
38 var key = +message.slice(s, e)
39 if (!wrappers[key]) continue
40 ++e
41 if (isSelfClosing) ++e
42
43 if (last < m) {
44 current.push(message.slice(last, m))
45 }
46
47 if (isSelfClosing) {
48 current.push(applyChildren(wrappers[key], null))
49 } else if (isEnd) {
50 if (currentKey !== key) {
51 throw new Error('Wrapping tags not properly nested in "' + message + '"')
52 }
53 var children = current
54 current = stack.pop()
55 currentKey = stack.pop()
56 current.push(applyChildren(wrappers[key], children))
57 } else { // start token
58 stack.push(currentKey)
59 stack.push(current)
60 currentKey = key
61 current = []
62 }
63 last = e
64 m = e - 1 // offset next ++
65 }
66 if (stack.length > 0) {
67 throw new Error('Wrapping tags not properly nested in "' + message + '"')
68 }
69 if (last < m) {
70 current.push(message.slice(last, m))
71 }
72 return current.length === 1 ? current[0] : current
73}