1 |
|
2 | (function() {
|
3 | var _, calcIds, calcRefs, fixLinks, fs, ppNode, walkTree;
|
4 |
|
5 | fs = require('fs');
|
6 |
|
7 | _ = require('lodash');
|
8 |
|
9 | walkTree = require('@resin.io/doxx-utils').walkTree;
|
10 |
|
11 | fixLinks = walkTree({
|
12 | visitNode: function(node) {
|
13 | var ref;
|
14 | if ((node.level != null) && !node.link) {
|
15 | if (!((ref = node.children) != null ? ref.length : void 0)) {
|
16 | throw new Error("No link and no child lines. " + node.raw);
|
17 | }
|
18 | node.isGateway = true;
|
19 | return node.link = node.children[0].link;
|
20 | }
|
21 | }
|
22 | });
|
23 |
|
24 | calcRefs = walkTree({
|
25 | visitNode: function(node) {
|
26 | var link;
|
27 | link = node.link;
|
28 | if (link && link[0] === '/') {
|
29 | node.ref = link.slice(1);
|
30 | }
|
31 | if ((node.level != null) && (node.ref == null) && !node.title) {
|
32 | throw new Error("No title for external link node. " + node.raw);
|
33 | }
|
34 | }
|
35 | });
|
36 |
|
37 | calcIds = function(rootNode, rootId) {
|
38 | var setId;
|
39 | setId = function(node, id) {
|
40 | var child, i, j, len, ref, results;
|
41 | node.$id = id;
|
42 | if (node.children) {
|
43 | ref = node.children;
|
44 | results = [];
|
45 | for (i = j = 0, len = ref.length; j < len; i = ++j) {
|
46 | child = ref[i];
|
47 | results.push(setId(child, id + "." + (i + 1)));
|
48 | }
|
49 | return results;
|
50 | }
|
51 | };
|
52 | return setId(rootNode, rootId);
|
53 | };
|
54 |
|
55 | exports.parse = function(config) {
|
56 | var currentNode, j, len, line, lines, result, trees;
|
57 | lines = fs.readFileSync(config.parseNav).toString().split('\n').map(function(s) {
|
58 | return s.trimRight();
|
59 | }).filter(function(s) {
|
60 | return s && !s.match(/\s*#/);
|
61 | }).map(function(s) {
|
62 | var line, pad, ref;
|
63 | ref = s.match(/^(\s*)(.*)$/).slice(1), pad = ref[0], line = ref[1];
|
64 | if (pad.length % 2 || !pad.match(/^ *$/)) {
|
65 | throw new Error("Wrong indent! Must be even and spaces-only. " + s);
|
66 | }
|
67 | return {
|
68 | level: pad.length / 2,
|
69 | raw: line
|
70 | };
|
71 | }).map(function(arg) {
|
72 | var level, link, linkReParts, node, raw, ref, skip, title, titleParts;
|
73 | level = arg.level, raw = arg.raw;
|
74 | ref = raw.match(/^([^\[]+)?(\[(.+)\])?$/).slice(1), title = ref[0], skip = ref[1], link = ref[2];
|
75 | node = {
|
76 | level: level,
|
77 | raw: raw,
|
78 | title: title,
|
79 | link: link
|
80 | };
|
81 | if (link != null ? link.match(/\$/) : void 0) {
|
82 | node.isDynamic = true;
|
83 | linkReParts = link.split(/\$[\w_]+/).map(_.escapeRegExp);
|
84 | node.linkRe = new RegExp('^' + linkReParts.join('.*') + '$');
|
85 | if (!title) {
|
86 | throw new Error("Dynamic pages must specify the title. " + raw);
|
87 | }
|
88 | titleParts = title.split(/\s*~\s*/);
|
89 | node.title = titleParts[0];
|
90 | node.titleTemplate = titleParts[1] || titleParts[0];
|
91 | }
|
92 | return node;
|
93 | });
|
94 | trees = [];
|
95 | currentNode = null;
|
96 | for (j = 0, len = lines.length; j < len; j++) {
|
97 | line = lines[j];
|
98 | if (currentNode == null) {
|
99 | if (line.level !== 0) {
|
100 | throw new Error("First line must have no indent. " + line.raw);
|
101 | }
|
102 | trees.push(line);
|
103 | } else {
|
104 | if (line.level > currentNode.level + 1) {
|
105 | throw new Error("Indent too big. " + line.raw);
|
106 | }
|
107 | while (currentNode && line.level <= currentNode.level) {
|
108 | currentNode = currentNode.parent;
|
109 | }
|
110 | if (!currentNode) {
|
111 | trees.push(line);
|
112 | } else {
|
113 | if (currentNode.children == null) {
|
114 | currentNode.children = [];
|
115 | }
|
116 | currentNode.children.push(line);
|
117 | line.parent = currentNode;
|
118 | }
|
119 | }
|
120 | currentNode = line;
|
121 | }
|
122 | result = {
|
123 | level: null,
|
124 | ref: void 0,
|
125 | link: null,
|
126 | title: '<root>',
|
127 | raw: '<root>',
|
128 | children: trees
|
129 | };
|
130 | fixLinks(result);
|
131 | calcRefs(result);
|
132 | calcIds(result, '$0');
|
133 | return result;
|
134 | };
|
135 |
|
136 | ppNode = walkTree({
|
137 | visitNode: function(node, indent) {
|
138 | var link, title;
|
139 | if (indent == null) {
|
140 | indent = '';
|
141 | }
|
142 | title = node.title || '(No title)';
|
143 | link = node.link ? "[" + node.link + "]" : '';
|
144 | return console.log(indent + "|--" + title + link);
|
145 | },
|
146 | buildNextArgs: function(node, indent) {
|
147 | if (indent == null) {
|
148 | indent = '';
|
149 | }
|
150 | return [indent + '| '];
|
151 | }
|
152 | });
|
153 |
|
154 | exports.pp = function(tree) {
|
155 | return ppNode(tree);
|
156 | };
|
157 |
|
158 | exports.serialize = function(tree, path) {};
|
159 |
|
160 | }).call(this);
|