on fdeccfb help sign in
webring/scripts/indental.js
57 lines 1.5 kB history raw
1'use strict'
3function indental (data, Type) {
4 function formatLine (line) {
5 const a = []
6 const h = {}
7 for (const child of line.children) {
8 if (child.key) {
9 if (h[child.key]) { console.warn(`Redefined key: ${child.key}.`) }
10 h[child.key] = child.value
11 } else if (child.children.length === 0 && child.content) {
12 a[a.length] = child.content
13 } else {
14 h[child.content.toUpperCase()] = formatLine(child)
15 }
16 }
17 return a.length > 0 ? a : h
18 }
20 function makeLine (line) {
21 return line.indexOf(' : ') > -1 ? {
22 indent: line.search(/\S|$/),
23 content: line.trim(),
24 key: line.split(' : ')[0].trim().toUpperCase(),
25 value: line.split(' : ')[1].trim()
26 } : {
27 indent: line.search(/\S|$/),
28 content: line.trim(),
29 children: []
30 }
31 }
33 function skipLine (line) {
34 return line.trim() !== '' && line.trim().substr(0, 1) !== ';' && line.trim().slice(-1) !== '`'
35 }
37 const lines = data.split('\n').filter(skipLine).map(makeLine)
39 // Assoc
40 const stack = {}
41 for (const line of lines) {
42 const target = stack[line.indent - 2]
43 if (target) { target.children.push(line) }
44 stack[line.indent] = line
45 }
47 // Format
48 const h = {}
49 for (const id in lines) {
50 const line = lines[id]
51 if (line.indent > 0) { continue }
52 const key = line.content.toUpperCase()
53 if (h[key]) { console.warn(`Redefined key: ${key}, line ${id}.`) }
54 h[key] = Type ? new Type(key, formatLine(line)) : formatLine(line)
55 }
56 return h