@kenjura/ursa 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,486 @@
1
+ let instance = {};
2
+
3
+ export function wikiToHtml({ wikitext, articleName, args } = {}) {
4
+ if (!args) args = { db: "noDB", noSection: true, noTOC: true };
5
+ if (!wikitext) return "nothing to render";
6
+
7
+ const linkbase = ("/" + args.db + "/").replace(/\/\//g, "/");
8
+ const imageroot = ("/" + args.db + "/img/").replace(/\/\//g, "/");
9
+
10
+ const allArticles = args.allArticles || [];
11
+
12
+ // console.log('wikitext=',wikitext);
13
+ var html = String(wikitext);
14
+ // instance.article = article;
15
+
16
+ // convenience features
17
+ // 1 - add title if none present
18
+ if (
19
+ !args.noH1 &&
20
+ !articleName.match(/^_(menu|style)/) &&
21
+ !html.match(/^=([^=\n]+)=/) &&
22
+ !html.match(/^__NOH1__/)
23
+ )
24
+ html = "=" + articleName.replace(/^_/, "") + "=\n" + html;
25
+ html = html.replace(/__NOH1__/g, "");
26
+
27
+ // basic formatting ------------------------------------------
28
+ // nowiki
29
+ html = html.replace(/<nowiki>([\d\D]*?)<\/nowiki>/g, processNoWiki);
30
+ html = html.replace(/^ ([^\n]*)$/gm, processCodeBlock);
31
+ html = html.replace(/<\/?[A-Za-z][^>]*>/g, processHTML);
32
+ //html = html.replace( /{(?!\|)([^\|]+\|)?([^}]*)}/g , processJSON );
33
+ // headers
34
+ html = html.replace(/^===([^=\n]+)===/gm, "<h3>$1</h3>");
35
+ html = html.replace(/^==([^=\n]+)==/gm, "<h2>$1</h2>");
36
+ html = html.replace(/^=([^=\n]+)=/gm, "<h1>$1</h1>");
37
+
38
+ // bullets
39
+ html = html.replace(/(\n|^)#([\d\D]*?)(\n(?!#)|$)/g, processNumberedLists);
40
+ html = html.replace(/(\n|^)\*([\d\D]*?)(\n(?!\*)|$)/g, processBullets);
41
+
42
+ // dd/dt
43
+ html = html.replace(
44
+ /^;([^:\n]*)\n?(?::(.*))?/gm,
45
+ "<dl><dt>$1</dt><dd>$2</dd></dl>"
46
+ );
47
+ html = html.replace(/^:(.*)/m, "<dd>$1</dd>\n");
48
+ // hr
49
+ html = html.replace(/---/g, "<hr>");
50
+ // inline
51
+ html = html.replace(/'''''([^']+)'''''/g, "<b><i>$1</i></b>");
52
+ html = html.replace(/'''([^']+)'''/g, "<b>$1</b>");
53
+ html = html.replace(/''([^']+)''/g, "<i>$1</i>");
54
+ // html = html.replace( /''(.*?)''/g , '<i>$1</i>' );
55
+ // strikethrough
56
+ // html = html.replace( /--(.*?)--/g , '<strike>$1</strike>' );
57
+ // embiggen
58
+ html = html.replace(
59
+ /\+\+\+([^\+]+)\+\+\+/g,
60
+ '<span style="font-size: 200%;">$1</span>'
61
+ );
62
+ html = html.replace(
63
+ /\+\+([^\+]+)\+\+/g,
64
+ '<span style="font-size: 150%;">$1</span>'
65
+ );
66
+ // tables
67
+ html = html.replace(/\{\|([\d\D]*?)\|\}/g, processTable);
68
+ // div/indent
69
+ html = html.replace(/^\.\.\.(.*)$/gm, '<div class="indent2">$1</div>');
70
+ html = html.replace(/^\.\.(.*)$/gm, '<div class="indent1">$1</div>');
71
+ html = html.replace(/^\.(.*)$/gm, "<div>$1</div>");
72
+ // links
73
+ html = html.replace(
74
+ /\[\[([^\[\]\|#]*)(?:(\|[^\]\|#]*)+)?(?:#([^\]\|#]*))?\]\]/g,
75
+ processLink
76
+ );
77
+ html = html.replace(
78
+ /\[\[([^\[\]\|#\n]*)((\|[^\]\|#\n]*)+)?(?:#([^\]\|#\n]*))?\]\]/g,
79
+ processLink
80
+ );
81
+ html = html.replace(/\[([^\]\n ]*)(?: ([^\]\n]+))?\]/g, processExternalLink);
82
+
83
+ // code
84
+ // html = html.replace( /^ (.*)$/mg , '<code>$1</code>' );
85
+ // paragraphs
86
+ html = html.trim();
87
+ // html = html.replace( /^.*$/gm , processParagraphs );
88
+ html = html.replace(/^[^\$\n].*$/gm, processParagraphs);
89
+ html = html.replace(/<p><\/p>/g, "");
90
+ // beautify HTML
91
+ //html = beautifyHTML(html);
92
+
93
+ // superscript
94
+ html = html.replace(/\^([^\^]*)\^/g, "<sup>$1</sup>");
95
+
96
+ // restore nowiki blocks
97
+ html = html.replace(/\$NOWIKI_(\d*)\$/g, processNoWikiRestore);
98
+ html = html.replace(/\$CODE_(\d*)\$/g, processCodeBlockRestore);
99
+ html = html.replace(/<\/code>\s*<code>/g, "\n");
100
+ html = html.replace(/\$HTML_(\d*)\$/g, processHTMLRestore);
101
+ //html = html.replace( /\$JSON_(\d*)\$/g , processJSONRestore );
102
+
103
+ // WORKING CODE for sectioning h1 and h2
104
+ if (!args.noSection) {
105
+ var find =
106
+ /(?:<h1>)([^\|<]*)(?:\|([^<\|]*))?(?:\|([^<]*))?(?:<\/h1>)([\d\D]*?)(?=<h1|$)/g;
107
+ var replace =
108
+ '\
109
+ <div class="sectionOuter sectionOuter1 $2" style="$3">\
110
+ <h1>$1</h1>\
111
+ <a name="$1"></a>\
112
+ <div class="section section1">\
113
+ $4\
114
+ <!--SECTION-END-->\
115
+ <!--<div style="clear: both;"></div>-->\
116
+ </div>\
117
+ </div>';
118
+ var sidebarHtml = "";
119
+ // html = html.replace( find , replace );
120
+ html = html.replace(find, function (em, title, args, style, body) {
121
+ if (args == "right") {
122
+ sidebarHtml += em.replace(
123
+ find,
124
+ '<aside class="sidebarSection">$4</aside>'
125
+ );
126
+ return em.replace(
127
+ find,
128
+ '<aside class="right sidebarSection">$4</aside>'
129
+ );
130
+ }
131
+ return em.replace(find, replace);
132
+ });
133
+
134
+ var find =
135
+ /(?:<h2>)([^\|<]*)(?:\|([^<\|]*))?(?:\|([^<]*))?(?:<\/h2>)([\d\D]*?)(?=<h2|<\!--SECTION-END|$)/g;
136
+ var replace =
137
+ '\
138
+ <div class="sectionOuter2 $2">\
139
+ <h2>$1</h2>\
140
+ <a id="$1" name="$1"></a>\
141
+ <div class="section2">\
142
+ $4\
143
+ <!--<div style="clear: both;"></div>-->\
144
+ </div>\
145
+ </div>';
146
+ html = html.replace(find, replace);
147
+ }
148
+
149
+ // adding IDs to headers for TOC seeks
150
+ if (!args.noTOC) {
151
+ var find = /(?:<h(\d)>)([^<]*)(?:<\/h\1>)/g;
152
+ var replace = '<h$1 id="$2">$2</h$1>';
153
+ html = html.replace(find, function (em, g1, g2) {
154
+ var id = g2.replace(/\s/g, "_");
155
+ return "<h" + g1 + ' id="' + id + '">' + g2 + "</h" + g1 + ">";
156
+ });
157
+ }
158
+ // toc html
159
+ if (args.toc) return html;
160
+ var tocHtml = getTOC(wikitext);
161
+
162
+ // return html;
163
+ return {
164
+ html: html,
165
+ sidebarHtml: sidebarHtml,
166
+ wikitext: wikitext,
167
+ tocHtml: tocHtml,
168
+ };
169
+
170
+ function getTOC(wikitext) {
171
+ if (!wikitext) return "";
172
+ var headerRows = wikitext.match(/^=.*/gm);
173
+ if (!headerRows || !headerRows.length) return "";
174
+ headerRows = headerRows.filter((hr) => hr.indexOf("|right") < 0);
175
+ var headers = headerRows.join("\n");
176
+ headers = headers.replace(/\[\[/g, "");
177
+ headers = headers.replace(/\]\]/g, "");
178
+ headers = headers.replace(/^===([^=|]*)(.*)$/gm, "*** $1");
179
+ headers = headers.replace(/^==([^=|]*)(.*)$/gm, "** $1");
180
+ headers = headers.replace(/^=([^=|]*)(.*)$/gm, "* $1");
181
+ headers = headers.replace(/=([^=|]*)/g, "$1");
182
+ headers = headers.replace(/\* (.*)$/gm, "* [[#$1]]");
183
+ return wikiToHtml(headers, "toc", {
184
+ toc: true,
185
+ noSection: true,
186
+ noH1: true,
187
+ });
188
+ }
189
+
190
+ function processLink(entireMatch, articleName, displayName, anchor) {
191
+ var namespace = [].concat(articleName.match(/([^:]+)(?=:)/g)).pop();
192
+ if (namespace)
193
+ var res = processSpecialLink(
194
+ entireMatch,
195
+ namespace,
196
+ articleName,
197
+ displayName
198
+ );
199
+ if (res) return res;
200
+ if (!anchor) anchor = "";
201
+
202
+ if (articleName.match(/^(\d+d\d+)([+-]\d+)/))
203
+ return (
204
+ "<a onclick=\"roll('" + articleName + "')\">" + articleName + "</a>"
205
+ );
206
+ if (articleName.match(/^[+-]/))
207
+ return '<a onclick="roll(' + articleName + ')">' + articleName + "</a>";
208
+
209
+ // if (isNullOrEmpty(articleName)) return '<a href="#'+anchor+'" onclick="instance.findHeader(\''+anchor+'\')">'+anchor+'</a>';
210
+ if (!articleName)
211
+ return (
212
+ '<a data-scroll href="#' +
213
+ anchor.replace(/\s/g, "_") +
214
+ '">' +
215
+ anchor +
216
+ "</a>"
217
+ );
218
+
219
+ if (!displayName) displayName = anchor || articleName;
220
+ else if (displayName.substr(0, 1) == "|")
221
+ displayName = displayName.substr(1);
222
+
223
+ if (!anchor) anchor = "";
224
+ else anchor = "#" + anchor;
225
+
226
+ var active = true;
227
+
228
+ active = !!allArticles.find((article) => article.match(articleName));
229
+
230
+ if (articleName.indexOf("/") >= 0) {
231
+ // assume the link is fully formed
232
+ return `<a class="wikiLink${
233
+ active ? " active" : ""
234
+ } data-articleName="${articleName}" href="${articleName}">${
235
+ displayName || articleName
236
+ }</a>`;
237
+ } else {
238
+ var link = linkbase + articleName + anchor;
239
+
240
+ // not sure what this did, but I need a new handler for this case
241
+ // if (articleName.indexOf('/')>-1) {
242
+ // link = '/'+articleName+anchor;
243
+ // displayName = articleName.substr(articleName.indexOf('/')+1);
244
+ // console.log('link=',link);
245
+ // }
246
+
247
+ return (
248
+ '<a class="wikiLink ' +
249
+ (active ? "active" : "inactive") +
250
+ '" data-articleName="' +
251
+ articleName +
252
+ '" href="' +
253
+ link +
254
+ '">' +
255
+ displayName +
256
+ "</a>"
257
+ );
258
+ }
259
+ }
260
+
261
+ function processNumberedLists(entireMatch) {
262
+ var lines = entireMatch.match(/^(.*)$/gm);
263
+ var level = 1;
264
+ var html = "\n<ol>";
265
+ for (var i = 0; i < lines.length; i++) {
266
+ var line = lines[i];
267
+ if (line.substr(0, 1) != "#") continue;
268
+ var lineLevel = line.match(/#+/)[0].length;
269
+ if (lineLevel > level) html += stringRepeat("<ol>", lineLevel - level);
270
+ if (lineLevel < level)
271
+ html += stringRepeat("</li></ol>", level - lineLevel);
272
+ if (lineLevel == level && html != "\n<ol>") html += "</li>";
273
+ level = lineLevel;
274
+ //html += '\n'+stringRepeat('\t',lineLevel);
275
+ html += "<li>" + line.replace(/#+/, "");
276
+ }
277
+
278
+ if (level > 1) html += stringRepeat("</li></ol>", level);
279
+ html += "</li></ol>\n";
280
+ return html;
281
+ }
282
+
283
+ function processBullets(entireMatch) {
284
+ var lines = entireMatch.match(/^(.*)$/gm);
285
+ var level = 1;
286
+ var html = "\n<ul>";
287
+ for (var i = 0; i < lines.length; i++) {
288
+ var line = lines[i];
289
+ if (line.substr(0, 1) != "*") continue;
290
+ var lineLevel = line.match(/\*+/)[0].length;
291
+ if (lineLevel > level) html += stringRepeat("<ul>", lineLevel - level);
292
+ if (lineLevel < level)
293
+ html += stringRepeat("</li></ul>", level - lineLevel);
294
+ if (lineLevel == level && html != "\n<ul>") html += "</li>";
295
+ level = lineLevel;
296
+ //html += '\n'+stringRepeat('\t',lineLevel);
297
+ html += "<li>" + line.replace(/\*+/, "");
298
+ }
299
+
300
+ if (level > 1) html += stringRepeat("</li></ul>", level);
301
+ html += "</li></ul>\n";
302
+ return html;
303
+ }
304
+ function processExternalLink(entireMatch, url, displayName) {
305
+ if (!displayName) displayName = url;
306
+ return '<a href="' + url + '">' + displayName + "</a>";
307
+ }
308
+ function processSpecialLink(
309
+ entireMatch,
310
+ namespace,
311
+ articleName,
312
+ displayName
313
+ ) {
314
+ var args = [];
315
+ if (!displayName) displayName = "";
316
+ else {
317
+ args = getMatches(entireMatch, /\|([^\|\]]+)/g, 0);
318
+ // var str = [].concat(entireMatch.match( /\[\[([^\]]+)\]\]/ )).pop();
319
+ // if (str) args = str.split('|');
320
+ }
321
+
322
+ articleName = articleName.replace(namespace + ":", "");
323
+
324
+ function getArg(index) {
325
+ if (args.length >= index) return args[index];
326
+ else return "";
327
+ }
328
+
329
+ switch (namespace.toUpperCase()) {
330
+ case "IFRAME":
331
+ return '<iframe src="' + articleName + '"' + getArg(0) + "></iframe>";
332
+ case "IMAGE":
333
+ return WikiImage.getImageTag({
334
+ name: articleName,
335
+ args: args,
336
+ imgUrl: imageroot + articleName,
337
+ });
338
+ default:
339
+ return null;
340
+ }
341
+ }
342
+
343
+ function processJSON(entireMatch, options, tag) {
344
+ if (!instance._JSONTags) instance._JSONTags = [];
345
+ instance._JSONTags.push(
346
+ new JSONTag({ options: options, body: "{" + tag + "}" })
347
+ );
348
+ return "$JSON_" + (instance._JSONTags.length - 1) + "$";
349
+ }
350
+ function processJSONRestore(entireMatch, arrayIndex) {
351
+ var tag = instance._JSONTags[parseInt(arrayIndex)];
352
+ return "JSON tag: " + tag.render();
353
+ }
354
+ function processHTML(entireMatch) {
355
+ if (!instance._htmlTags) instance._htmlTags = [];
356
+ instance._htmlTags.push(entireMatch);
357
+ return "$HTML_" + (instance._htmlTags.length - 1) + "$";
358
+ }
359
+ function processHTMLRestore(entireMatch, arrayIndex) {
360
+ return instance._htmlTags[parseInt(arrayIndex)];
361
+ }
362
+ function processNoWiki(entireMatch, wikiText) {
363
+ if (!instance._noWiki) instance._noWiki = [];
364
+ instance._noWiki.push(wikiText);
365
+ return "$NOWIKI_" + (instance._noWiki.length - 1) + "$";
366
+ }
367
+ function processNoWikiRestore(entireMatch, arrayIndex) {
368
+ return instance._noWiki[parseInt(arrayIndex)];
369
+ }
370
+ function processCodeBlock(entireMatch, wikiText) {
371
+ if (!instance._CodeBlock) instance._CodeBlock = [];
372
+ instance._CodeBlock.push(wikiText);
373
+ return "$CODE_" + (instance._CodeBlock.length - 1) + "$";
374
+ }
375
+ function processCodeBlockRestore(entireMatch, arrayIndex) {
376
+ return "<code>" + instance._CodeBlock[parseInt(arrayIndex)] + "</code>";
377
+ }
378
+ function processParagraphs(entireMatch) {
379
+ if (entireMatch.substr(0, 1) == "<") return entireMatch; // html? looks like it's already been converted, let's leave it alone
380
+ if (entireMatch.indexOf("$HTML") > -1) return entireMatch;
381
+
382
+ return "<p>" + entireMatch + "</p>";
383
+ }
384
+
385
+ function processTable(entireMatch, tableBody) {
386
+ // ***************** LEX ***************
387
+ // protect pipe characters inside a table that have nothing to do with cell boundaries
388
+ entireMatch = entireMatch.replace(/\[\[[^\]\n]+\]\]/g, function (em) {
389
+ return em.replace(/\|/g, "$BAR$");
390
+ });
391
+
392
+ // table boundaries
393
+ entireMatch = entireMatch.replace(/\{\|(?:([^>\n]*)>)?/g, "¦TABLE¦$1¦");
394
+ entireMatch = entireMatch.replace(/\|\}/g, "¦END TABLE¦");
395
+
396
+ // table rows
397
+ entireMatch = entireMatch.replace(/^\|-/gm, "¦ROW BOUNDARY¦");
398
+
399
+ // table headers
400
+
401
+ // note 2013-04-02: tweaked TH regex to allow ! characters inside TD cells. Basically, a single ! is only a "start TH" if it is preceded by a newline.
402
+ // note 2014-06-19: swapped out $ for \n inside the TH/TD optional HTML attributes section. In a character class, $ doesn't mean "end of line", it's always literal. For some reason.
403
+
404
+ //entireMatch = entireMatch.replace( /!{1,2}(?:([^$>\|!]+)>|([0-9]+)\|)?([^!\|¦]+)(?=\n!|!!|\n\||\|\||¦)/gm , function(wholeMatch,m0,m1,m2,m3,m4,m5) {
405
+ entireMatch = entireMatch.replace(
406
+ /(?:^!|!!)(?:([^\n>\|!]+)>|([0-9]+)\|)?([^!\|¦]+)(?=\n!|!!|\n\||\|\||¦)/gm,
407
+ function (wholeMatch, m0, m1, m2, m3, m4, m5) {
408
+ m0 = m0 || "";
409
+ m2 = m2 || "";
410
+ if (m1 != "" && typeof m1 != "undefined")
411
+ return '¦TH¦colspan="' + m1 + '" ' + m0 + "¦" + m2 + "¦END TH¦";
412
+ else return "¦TH¦" + m0 + "¦" + m2 + "¦END TH¦";
413
+ // m0 = !m0>
414
+ // m1 = !m1| aka colspan
415
+ // m2 = actual cell content
416
+ }
417
+ );
418
+ //return entireMatch;
419
+ entireMatch = entireMatch.replace(
420
+ /\|{1,2}(?:([^\n>\|!]+)>|([0-9]+)\|)?([^\|¦]+)(?=\n!|!!|\n\||\|\||¦)/gm,
421
+ function (wholeMatch, m0, m1, m2, m3) {
422
+ m0 = m0 || "";
423
+ m2 = m2 || "";
424
+ if (m1 != "" && typeof m1 != "undefined")
425
+ return '¦TD¦colspan="' + m1 + '" ' + m0 + "¦" + m2 + "¦END TD¦";
426
+ else return "¦TD¦" + m0 + "¦" + m2 + "¦END TD¦";
427
+ }
428
+ );
429
+
430
+ // ***************** FINAL ******************
431
+ entireMatch = entireMatch.replace(
432
+ /¦TABLE¦([^¦]*)¦/g,
433
+ '<div class="tableContainer"><table $1><tr>'
434
+ );
435
+ entireMatch = entireMatch.replace(/¦END TABLE¦/g, "</tr></table></div>");
436
+
437
+ entireMatch = entireMatch.replace(/¦ROW BOUNDARY¦/g, "</tr><tr>");
438
+
439
+ entireMatch = entireMatch.replace(
440
+ /¦TH¦([^¦]*)¦([^¦]*)¦END TH¦/g,
441
+ "<th $1>$2</th>"
442
+ );
443
+ entireMatch = entireMatch.replace(
444
+ /¦TD¦([^¦]*)¦([^¦]*)¦END TD¦/g,
445
+ function (wholeMatch, m0, m1, m2) {
446
+ return "<td " + (m0 || "") + ">\n" + (m1 || "") + "\n</td>";
447
+ }
448
+ );
449
+
450
+ entireMatch = entireMatch.replace(/\$BAR\$/g, "|");
451
+
452
+ // **************** RETURN *****************
453
+ return entireMatch;
454
+ }
455
+
456
+ function findHeader(name) {
457
+ smoothScroll.animateScroll(null, "#" + name);
458
+ // var headers = document.querySelectorAll('h1,h2,h3');
459
+ // for (var i = 0; i < headers.length; i++) {
460
+ // if (headers[i].innerHTML.trim()==name) {
461
+ // var y = UIUtil.getPageOffset(headers[i]).y;
462
+ // UIUtil.animate( document.body, 300, { scrollTop: y});
463
+ // // document.body.scrollTop = y;
464
+ // return;
465
+ // }
466
+ // }
467
+ }
468
+ }
469
+
470
+ const stringRepeat = function (chr, count) {
471
+ var ret = "";
472
+ for (var i = 0; i < count; i++) {
473
+ ret += chr;
474
+ }
475
+ return ret;
476
+ };
477
+
478
+ const getMatches = function (string, regex, index) {
479
+ index || (index = 1); // default to the first capturing group
480
+ var matches = [];
481
+ var match;
482
+ while ((match = regex.exec(string))) {
483
+ matches.push(match[index]);
484
+ }
485
+ return matches;
486
+ };
@@ -0,0 +1,8 @@
1
+ import yargs from 'yargs';
2
+
3
+ import { describeGenerate, generate } from './commands/generate.js';
4
+ import { hideBin } from 'yargs/helpers';
5
+
6
+ yargs(hideBin(process.argv))
7
+ .command(['$0', 'generate'], 'generates a static site', describeGenerate, generate);
8
+
package/src/index.js ADDED
@@ -0,0 +1,8 @@
1
+ import { generate } from "./jobs/generate.js";
2
+
3
+ import { join, resolve } from "path";
4
+
5
+ const source = process.env.SOURCE ?? join(process.cwd(), "source");
6
+ const build = process.env.BUILD ?? join(process.cwd(), "build");
7
+
8
+ generate({ source, build });