wikity 1.3.4 → 1.3.6
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.
- package/dist/compile.js +19 -14
- package/dist/parse.js +59 -18
- package/dist/wiki.css.js +6 -8
- package/package.json +3 -4
- package/readme.md +4 -0
package/dist/compile.js
CHANGED
|
@@ -8,7 +8,6 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const glob_1 = __importDefault(require("glob"));
|
|
10
10
|
const dedent_1 = __importDefault(require("dedent"));
|
|
11
|
-
const formatter = require('html-formatter'); // does not have type package
|
|
12
11
|
const parse_1 = require("./parse");
|
|
13
12
|
const wiki_css_1 = __importDefault(require("./wiki.css"));
|
|
14
13
|
function eleventyCompile(dir = '.', config = {}) {
|
|
@@ -40,7 +39,7 @@ function compile(dir = '.', config = {}) {
|
|
|
40
39
|
const outFilename = filename.replace(/ /g, '_').replace('.wiki', '.html');
|
|
41
40
|
const outFilePath = path_1.default.join(outputFolder, outFilename);
|
|
42
41
|
const urlPath = outFilename.replace(/(?<=^|\/)\w/g, m => m.toUpperCase()); // capitalise first letters
|
|
43
|
-
const displayTitle = metadata.displayTitle || urlPath.replace('.html', '');
|
|
42
|
+
const displayTitle = metadata.displayTitle || urlPath.replace('.html', '').replace(/_/g, ' ');
|
|
44
43
|
// Eleventy configuration
|
|
45
44
|
const frontMatter = config.eleventy ? (0, dedent_1.default) `
|
|
46
45
|
---
|
|
@@ -50,33 +49,39 @@ function compile(dir = '.', config = {}) {
|
|
|
50
49
|
// Create TOC
|
|
51
50
|
if (!metadata.notoc && (metadata.toc || (((_a = outText.match(/<h\d[^>]*>/g)) === null || _a === void 0 ? void 0 : _a.length) || 0) > 3)) {
|
|
52
51
|
let toc = '';
|
|
53
|
-
let headings = Array.from(parsedContent.match(/<h\d[^>]*>.+?<\/h\d>/gs) || []);
|
|
52
|
+
let headings = Array.from(parsedContent.match(/<h\d auto[^>]*>.+?<\/h\d>/gs) || []);
|
|
54
53
|
headings.forEach(match => {
|
|
55
54
|
var _a;
|
|
56
|
-
const
|
|
55
|
+
const headingInner = match.replace(/\s*<\/?h\d[^>]*>\s*/g, '');
|
|
56
|
+
const text = headingInner.replace(/<.+?>/g, ''); // remove tags from inner
|
|
57
57
|
const lvl = +(((_a = match.match(/\d/g)) === null || _a === void 0 ? void 0 : _a[0]) || -1);
|
|
58
58
|
toc += `${`<ol>`.repeat(lvl - 1)} <li> <a href="#${encodeURI(text.replace(/ /g, '_'))}">${text}</a> </li> ${`</ol>`.repeat(lvl - 1)}`;
|
|
59
59
|
});
|
|
60
|
+
toc = toc.replace(/<\/ol>\s*<ol>/g, '');
|
|
60
61
|
const tocElem = (0, dedent_1.default) `
|
|
61
|
-
<div id="
|
|
62
|
-
<span id="
|
|
62
|
+
<div id="page_toc">
|
|
63
|
+
<span id="page_toc_heading">
|
|
63
64
|
<strong>Contents</strong>
|
|
64
65
|
[<a href="javascript:void(0)" onclick="
|
|
65
|
-
document.getElementById('
|
|
66
|
+
document.getElementById('page_toc_contents').setAttribute('style', this.innerText === 'hide' ? 'display: none;' : '');
|
|
66
67
|
this.innerText = this.innerText === 'hide' ? 'show' : 'hide';
|
|
67
68
|
">hide</a>]
|
|
68
69
|
</span>
|
|
69
|
-
<ol id="
|
|
70
|
+
<ol id="page_toc_contents">${toc}</ol>
|
|
70
71
|
</div>
|
|
71
72
|
`;
|
|
72
73
|
// Set TOC on page
|
|
73
|
-
if (outText.includes('<toc></toc>'))
|
|
74
|
+
if (outText.includes('<toc></toc>')) {
|
|
75
|
+
// put TOC where explicitly declared
|
|
74
76
|
outText = outText.replace('<toc></toc>', tocElem);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// put TOC above first auto heading
|
|
80
|
+
outText = outText.replace(/<h[1-6] auto/, tocElem + '$&');
|
|
81
|
+
}
|
|
77
82
|
}
|
|
78
83
|
// Create plaintext of HTML for use as description/metadata property.
|
|
79
|
-
const plaintextData = parsedContent.replace(/<.+?>/gs, '
|
|
84
|
+
const plaintextData = parsedContent.replace(/<.+?>/gs, '');
|
|
80
85
|
// Create HTML
|
|
81
86
|
const folderUpCount = file.split(/[\/\\]/).length - dir.split(/[\/\\]/).length; // number of folders to go up by to get to root
|
|
82
87
|
const html = (0, dedent_1.default) `
|
|
@@ -106,8 +111,8 @@ function compile(dir = '.', config = {}) {
|
|
|
106
111
|
if (!fs_1.default.existsSync(path_1.default.dirname(outFilePath))) {
|
|
107
112
|
fs_1.default.mkdirSync(path_1.default.dirname(outFilePath));
|
|
108
113
|
}
|
|
109
|
-
const
|
|
110
|
-
fs_1.default.writeFileSync(outFilePath, frontMatter + '\n' +
|
|
114
|
+
const formattedHtml = html.replace(/\n[\n\s]+/g, '\n');
|
|
115
|
+
fs_1.default.writeFileSync(outFilePath, frontMatter + '\n' + formattedHtml, 'utf8');
|
|
111
116
|
// Move images
|
|
112
117
|
(0, glob_1.default)(imagesFolder + '/*', {}, (err, files) => {
|
|
113
118
|
if (err) {
|
package/dist/parse.js
CHANGED
|
@@ -11,8 +11,13 @@ const common_1 = require("./common");
|
|
|
11
11
|
const r = String.raw;
|
|
12
12
|
const MAX_RECURSION = 20;
|
|
13
13
|
const arg = r `\s*([^|}]+?)\s*`;
|
|
14
|
-
function
|
|
15
|
-
|
|
14
|
+
function toLinkText(link) {
|
|
15
|
+
const cleanedLink = encodeURI(link.trim().replace(/ /g, '_'));
|
|
16
|
+
return cleanedLink[0].toUpperCase() + cleanedLink.slice(1);
|
|
17
|
+
}
|
|
18
|
+
function toFileText(link) {
|
|
19
|
+
const cleanedLink = link.trim().replace(/ /g, '_');
|
|
20
|
+
return cleanedLink[0].toUpperCase() + cleanedLink.slice(1);
|
|
16
21
|
}
|
|
17
22
|
function parseDimensions(dimStr) {
|
|
18
23
|
const regex = /(\d*)(?:x(\d*))?px/;
|
|
@@ -59,8 +64,11 @@ function parse(data, config = {}) {
|
|
|
59
64
|
.replace(/^-{4,}/gm, '<hr>')
|
|
60
65
|
// Images: [[File:Image.png|options|caption]]
|
|
61
66
|
.replace((0, common_1.RegExpBuilder)(r `\[\[ (?:File|Image): (.*?) (\|.+?)? \]\]`), (_, file, params = '') => {
|
|
67
|
+
var _a;
|
|
62
68
|
if (params.includes('{{'))
|
|
63
69
|
return _;
|
|
70
|
+
if (params.includes('[['))
|
|
71
|
+
return _;
|
|
64
72
|
if (!file)
|
|
65
73
|
return '';
|
|
66
74
|
const path = path_1.default.join(imagesFolder, file.trim().replace(/ /g, '_'));
|
|
@@ -78,6 +86,7 @@ function parse(data, config = {}) {
|
|
|
78
86
|
imageData.type = { framed: 'frame', thumbnail: 'thumb' }[param] || param;
|
|
79
87
|
if (imageData.type === 'thumb') {
|
|
80
88
|
imageData.hasCaption = true;
|
|
89
|
+
(_a = imageData.float) !== null && _a !== void 0 ? _a : (imageData.float = 'right');
|
|
81
90
|
}
|
|
82
91
|
}
|
|
83
92
|
else if (param.endsWith('px')) {
|
|
@@ -112,9 +121,11 @@ function parse(data, config = {}) {
|
|
|
112
121
|
image-${imageData.type || 'default'}
|
|
113
122
|
"
|
|
114
123
|
style="
|
|
115
|
-
|
|
124
|
+
margin: 8px;
|
|
116
125
|
float: ${imageData.float || 'none'};
|
|
126
|
+
clear: ${imageData.float || 'none'};
|
|
117
127
|
vertical-align: ${imageData.align || 'unset'};
|
|
128
|
+
background: #fff;
|
|
118
129
|
${imageData.style || ''}
|
|
119
130
|
"
|
|
120
131
|
>
|
|
@@ -122,28 +133,34 @@ function parse(data, config = {}) {
|
|
|
122
133
|
src="${path_1.default.basename(imagesFolder)}/${path_1.default.relative(imagesFolder, path)}"
|
|
123
134
|
alt="${imageData.alt || file}"
|
|
124
135
|
width="${imageData.width || 300}"
|
|
125
|
-
height="${imageData.height ||
|
|
136
|
+
height="${imageData.height || ''}"
|
|
126
137
|
>
|
|
127
138
|
${imageData.hasCaption ? `<figcaption>${caption}</figcaption>` : ''}
|
|
128
139
|
</figure>
|
|
129
140
|
`;
|
|
130
141
|
const imageLink = imageData.link;
|
|
131
142
|
if (imageLink) {
|
|
132
|
-
content = `<a href="${
|
|
143
|
+
content = `<a href="${toLinkText(imageLink)}" title="${imageLink}">${content}</a>`;
|
|
133
144
|
}
|
|
134
145
|
return content;
|
|
135
146
|
})
|
|
136
|
-
// Internal links
|
|
147
|
+
// Internal links
|
|
148
|
+
// [[Page]]
|
|
137
149
|
.replace((0, common_1.RegExpBuilder)(r `\[\[ ([^\]|]+?) \]\]`), (_, link) => {
|
|
138
150
|
if (_.includes('{{'))
|
|
139
151
|
return _;
|
|
140
|
-
|
|
152
|
+
if (/(?:File|Image):/.test(link))
|
|
153
|
+
return _;
|
|
154
|
+
const content = `<a class="internal-link" title="${link}" href="./${toLinkText(link)}">${link}</a>`;
|
|
141
155
|
return content;
|
|
142
156
|
})
|
|
157
|
+
// [[Page|Text]]
|
|
143
158
|
.replace((0, common_1.RegExpBuilder)(r `\[\[ ([^\]|]+?) \| ([^\]]+?) \]\]`), (_, link, text) => {
|
|
144
159
|
if (link.includes('{{'))
|
|
145
160
|
return _;
|
|
146
|
-
|
|
161
|
+
if (/(?:File|Image):/.test(link))
|
|
162
|
+
return _;
|
|
163
|
+
const content = `<a class="internal-link" title="${link}" href="./${toLinkText(link)}">${text}</a>`;
|
|
147
164
|
return content;
|
|
148
165
|
})
|
|
149
166
|
.replace((0, common_1.RegExpBuilder)(r `(</a>)([a-z]+)`), '$2$1')
|
|
@@ -240,14 +257,19 @@ function parse(data, config = {}) {
|
|
|
240
257
|
const errMsg = `Wikity does not use Wikipedia's #time function syntax. Use repetition-based formatting (e.g. yyyy-mm-dd) instead.`;
|
|
241
258
|
console.warn(`<Wikity> [WARN] ${errMsg}`);
|
|
242
259
|
}
|
|
243
|
-
|
|
260
|
+
try {
|
|
261
|
+
return (0, dateformat_1.default)(args[1] ? new Date(args[1]) : new Date(), args[0]);
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return args[1] || args[0];
|
|
265
|
+
}
|
|
244
266
|
}
|
|
245
267
|
})
|
|
246
268
|
// Templates: {{template}}
|
|
247
269
|
.replace((0, common_1.RegExpBuilder)(r `(?<!{) {{ \s* ([^#{}|]+?) \s* (\|[^{}]+)? }} (?!})`), (_, title, params = '') => {
|
|
248
270
|
if (params.includes('{{'))
|
|
249
271
|
return _;
|
|
250
|
-
const templateFile = title
|
|
272
|
+
const templateFile = toFileText(title);
|
|
251
273
|
const page = path_1.default.join(templatesFolder, templateFile);
|
|
252
274
|
let content = '';
|
|
253
275
|
// Try retrieve template content
|
|
@@ -285,7 +307,10 @@ function parse(data, config = {}) {
|
|
|
285
307
|
.replace((0, common_1.RegExpBuilder)(r `''' ([^']+?) '''`), '<b>$1</b>')
|
|
286
308
|
.replace((0, common_1.RegExpBuilder)(r `'' ([^']+?) ''`), '<i>$1</i>')
|
|
287
309
|
// Headings: ==heading==
|
|
288
|
-
.replace((0, common_1.RegExpBuilder)(r `^ (=+) \s* (.+?) \s* \1 \s* $`), (_, lvl, txt) =>
|
|
310
|
+
.replace((0, common_1.RegExpBuilder)(r `^ (=+) \s* (.+?) \s* \1 \s* $`), (_, lvl, txt) => {
|
|
311
|
+
const linkForm = encodeURI(txt.replace(/ /g, '_').replace(/<.+?>/g, ''));
|
|
312
|
+
return `<h${lvl.length} auto id="${linkForm}">${txt}</h${lvl.length}>`;
|
|
313
|
+
})
|
|
289
314
|
// Bulleted list: *item
|
|
290
315
|
.replace((0, common_1.RegExpBuilder)(r `^ (\*+) (.+?) $`), (_, lvl, content) => {
|
|
291
316
|
if (content.includes('{{'))
|
|
@@ -314,6 +339,8 @@ function parse(data, config = {}) {
|
|
|
314
339
|
.replace((0, common_1.RegExpBuilder)(r `</dl> (\s*?) <dl>`), '$1')
|
|
315
340
|
// Tables: {|, |+, !, |-, |, |}
|
|
316
341
|
.replace(/\{\|.+\|\}/gs, (tableInner) => {
|
|
342
|
+
if (tableInner.includes('{{'))
|
|
343
|
+
return tableInner;
|
|
317
344
|
return tableInner
|
|
318
345
|
// {| data (open table)
|
|
319
346
|
.replace((0, common_1.RegExpBuilder)(r `^ \{\| (.*?) $`), (_, attrs) => `<table ${attrs}><tr>`)
|
|
@@ -333,15 +360,17 @@ function parse(data, config = {}) {
|
|
|
333
360
|
.replace((0, common_1.RegExpBuilder)(r `< ref \s* (?: name \s* = \s* ["']? ([^>'"]+) ["']? [^>]* )?> (.+?) </ ref >`), (_, refname, text) => {
|
|
334
361
|
if (_.includes('{{'))
|
|
335
362
|
return _;
|
|
336
|
-
const refData = { ref: text,
|
|
363
|
+
const refData = { ref: text, id: refs.length + 1, name: refname, i: 0 };
|
|
337
364
|
refs.push(refData);
|
|
338
|
-
return `<sup class="refnote"><a id="cite-${refData.
|
|
365
|
+
return `<sup class="refnote"><a id="cite-${refData.id}" class="ref" href="#ref-${refData.id}">[${refData.id}]</a></sup>`;
|
|
339
366
|
})
|
|
340
|
-
.replace((0, common_1.RegExpBuilder)(r `< ref \s* name \s* = \s* ["']? ( [^>"']+ ) ["']? \s* (?: /> | >
|
|
367
|
+
.replace((0, common_1.RegExpBuilder)(r `< ref \s* name \s* = \s* ["']? ( [^>"']+ ) ["']? \s* (?: /> | > .*? </ref> )`), (_, refname) => {
|
|
341
368
|
const ref = refs.find(ref => ref.name === refname);
|
|
342
369
|
if (!ref)
|
|
343
|
-
return
|
|
344
|
-
|
|
370
|
+
return _;
|
|
371
|
+
ref.i++;
|
|
372
|
+
const citeId = `cite-${ref.id}${ref.i > 0 ? `_${ref.i}` : ''}`;
|
|
373
|
+
return `<sup class="refnote"><a id="${citeId}" class="ref" href="#ref-${ref.id}">[${ref.id}]</a></sup>`;
|
|
345
374
|
})
|
|
346
375
|
// Nonstandard: ``code`` and ```code blocks```
|
|
347
376
|
.replace((0, common_1.RegExpBuilder)(r ` \`\`\` ([^\`]+?) \`\`\` `), '<pre>$1</pre>')
|
|
@@ -358,8 +387,20 @@ function parse(data, config = {}) {
|
|
|
358
387
|
outText = outText
|
|
359
388
|
// References: <references />
|
|
360
389
|
.replace((0, common_1.RegExpBuilder)(r `<references \s* /?>`), () => {
|
|
361
|
-
const references = refs.map((
|
|
362
|
-
|
|
390
|
+
const references = refs.map((refdata) => {
|
|
391
|
+
let multiRefContent = '';
|
|
392
|
+
if (refdata.i > 0) {
|
|
393
|
+
for (let i = 0; i <= refdata.i; i++) {
|
|
394
|
+
multiRefContent += `<sup><a href="#cite-${refdata.id}${i > 0 ? `_${i}` : ''}">${i + 1}</a></sup> `;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
const refline = `
|
|
398
|
+
<li id="ref-${refdata.id}">
|
|
399
|
+
${refdata.i > 0 ? '↑' : `<a href="#cite-${refdata.id}">↑</a>`}
|
|
400
|
+
${multiRefContent}
|
|
401
|
+
${refdata.ref}
|
|
402
|
+
</li>
|
|
403
|
+
`;
|
|
363
404
|
return refline;
|
|
364
405
|
}).join('\n');
|
|
365
406
|
return `<ol>${references}</ol>`;
|
package/dist/wiki.css.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = String.raw `
|
|
4
|
-
body {font-family: sans-serif; margin:
|
|
4
|
+
body {font-family: sans-serif; margin: auto; max-width: 1000px; background: #eee;}
|
|
5
5
|
main {margin: 3em -1em; background: #fff; padding: 1em;}
|
|
6
6
|
h1, h2 {margin-bottom: 0.6em; font-weight: normal; border-bottom: 1px solid #a2a9b1;}
|
|
7
7
|
ul, ol {margin: 0.3em 0 0 1.6em; padding: 0;}
|
|
8
8
|
dt {font-weight: bold;}
|
|
9
9
|
dd, dl dl {margin-block: 0; margin-inline-start: 30px;}
|
|
10
10
|
|
|
11
|
-
figure {margin: 1em;}
|
|
11
|
+
figure {margin: 1em; width: 300px;}
|
|
12
12
|
.image-thumb, .image-frame {padding: 6px; border: 1px solid gray;}
|
|
13
13
|
.image-default {margin: 0;}
|
|
14
14
|
figcaption {padding-top: 6px;}
|
|
@@ -26,13 +26,11 @@ a.external-link::after {content: '\1f855';}
|
|
|
26
26
|
a.redlink {color: #d33;}
|
|
27
27
|
a.redlink:visited {color: #b44;}
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
#page+toc-heading {display: block; text-align: center;}
|
|
33
|
-
#page+toc ol {margin: 0 0 0 1.3em;}
|
|
29
|
+
#page_toc {border: 1px solid #aab; padding: 8px; width: fit-content; background-color: #f8f8f8; font-size: 95%;}
|
|
30
|
+
#page_toc_heading {display: block; text-align: center;}
|
|
31
|
+
#page_toc ol {margin: 0 0 0 1.3em;}
|
|
34
32
|
|
|
35
33
|
#infobox {float: right; clear: right; margin: 0 0 1em 1em; width: 300px; padding: 2px; border: 1px solid #CCC; overflow: auto; font-size: 90%;}
|
|
36
|
-
#infobox tr:first-child :first-child {padding: 10px
|
|
34
|
+
#infobox tr:first-child :first-child {padding: 10px; text-align: center; font-weight: bold; font-size: 120%;}
|
|
37
35
|
#infobox th {padding-left: 10px; text-align: left;}
|
|
38
36
|
`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wikity",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "Compile wikitext to HTML
|
|
3
|
+
"version": "1.3.6",
|
|
4
|
+
"description": "Compile wikitext to HTML! Supporst use of wikitext as a templating language.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "tsc && cd test && eleventy"
|
|
@@ -41,8 +41,7 @@
|
|
|
41
41
|
"dateformat": "^4.6.3",
|
|
42
42
|
"dedent": "^1.5.3",
|
|
43
43
|
"escape-html": "^1.0.3",
|
|
44
|
-
"glob": "^8.1.0"
|
|
45
|
-
"html-formatter": "^0.1.9"
|
|
44
|
+
"glob": "^8.1.0"
|
|
46
45
|
},
|
|
47
46
|
"devDependencies": {
|
|
48
47
|
"@types/dateformat": "^3.0.1",
|
package/readme.md
CHANGED
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
This package comes with built-in support for compilation using [Eleventy](https://11ty.dev).
|
|
10
10
|
|
|
11
|
+
## Exemplar
|
|
12
|
+
|
|
13
|
+
See the `example` folder for a template on making your own wiki site!
|
|
14
|
+
|
|
11
15
|
## Install
|
|
12
16
|
|
|
13
17
|
Wikity is available [on npm](https://www.npmjs.com/package/wikity).
|