Skip to content

Commit 564be68

Browse files
committed
1.1.0
- Add contents, nowiki, magic words, and string functions - Change #time to use length-based timecodes - Fix some bugs
1 parent c5815d5 commit 564be68

File tree

14 files changed

+202
-78
lines changed

14 files changed

+202
-78
lines changed

changelog.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## 1.1.0
4+
*2021-03-28*
5+
- Added `parse` CLI command to implement `parse()`.
6+
- Added support for a table of contents.
7+
- Added support for `nowiki` tag.
8+
- Added support for `onlyinclude`, `includeonly`, and `noinclude` tags in templates.
9+
- Added support for magic words `__TOC__`, `__FORCETOC__`, `__NOTOC__`, and `__NOINDEX__`.
10+
- Added support for control function `{{displaytitle:}}` to control the page's displayed title.
11+
- Added support for string functions `lc:`, `uc:`, `lcfirst:`, `ucfirst:`, `replace:`, `explode:`, `sub:`, `len:`, `pos:`, `padleft:`, `padright:`, `urlencode:`, and `urldecode:`.
12+
- Added support for horizontal rules using `----`.
13+
- Changed time codes in `#datetime`/`#date`/`#time` function to be based on reduplication instead of unique characters with escaping based on quoting instead of prefixing with a backslash (i.e., `{{#time: j F Y (\n\o\w)}}` → `{{#time: dd mmm yyyy "(now)"}}`).
14+
- Fixed inline tags removing whitespace from either end.
15+
- Fixed single-line-only syntax not being parsed correctly.
16+
317
## 1.0.1
418
*2021-03-28*
519
- Changed HTML output to be prettified.

package-lock.json

Lines changed: 19 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "wikity",
3-
"version": "1.0.1",
3+
"version": "1.1.0",
44
"description": "Wikitext as a templating language, with built-in Eleventy support.",
55
"main": "src/index.js",
66
"scripts": {
@@ -21,6 +21,8 @@
2121
"author": "Nixinova (https://nixinova.com)",
2222
"license": "ISC",
2323
"dependencies": {
24+
"dateformat": "^4.5.1",
25+
"escape-html": "^1.0.3",
2426
"glob": "^7.1.6",
2527
"html-formatter": "^0.1.9",
2628
"novasheets": "1.0.0-pre3"

readme.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ Any wiki templates (called using `{{template name}}`) must be inside the `templa
6565
| `##sub-numbered` | <ol><ol><li>sub-numbered</li></ol></ol> |
6666
| `;term` | <dt>**term**</dt> |
6767
| `:definition` | <dd>&emsp;definition</dd> |
68+
| `<ref>Text</ref>` | <sup id=cite-1>[[1]](#ref-1)</sup> |
69+
| `<references/>` | 1. <a id=ref-1>[](#cite-1)</a> Text |
6870
| `[[internal link]]` | [internal link](#internal_link) |
6971
| `[[link\|display text]]` | [display text](#link) |
7072
| `[external-link]` | [[1]](#external-link) |
@@ -79,11 +81,18 @@ Any wiki templates (called using `{{template name}}`) must be inside the `templa
7981
| `{{#var:varname}}` | text *(from memory)* |
8082
| `{{#var:varname\|default val}}` | *(ditto but 'default val' if unset)* |
8183
| `{{#switch:a\|a=1\|b=2\|c=3}}` | 1 |
82-
| `{{#time:d-M-y\|2021-03-28}}` | 28-Mar-21 |
84+
| `{{#time:dd/mm/yy\|2021-03-28}}` | 28/03/21 |
8385
| `{{lc:TEXT}}` | text |
8486
| `{{ucfirst:text}}` | Text |
85-
| `<ref>Text</ref>` | <sup id=cite-1>[[1]](#ref-1)</sup> |
86-
| `<references/>` | 1. <a id=ref-1>[](#cite-1)</a> Text |
87+
| `{{len:12345}}` | 5 |
88+
| `{{sub:string|2|4}}` | ring |
89+
| `{{pos:text|x}}` | 2 |
90+
| `{{padleft:text|5|_}}` | _text |
91+
| `{{padright:msg|5|_}}` | msg__ |
92+
| `{{replace:Message|e|3}}` | M3ssag3 |
93+
| `{{explode:A-B-C-D|-|2}}` | C |
94+
| `{{urlencode:t e x t}}` | t%20e%20x%20t |
95+
| `{{urldecode:a%20b%27c}}` | a b'c |
8796
| `<noinclude>No</noinclude>` | *(blank outside a template)* |
8897
| `<onlyinclude>Yes</onlyinclude>` | Yes |
8998
| `<includeonly>Yes</includeonly>` | Yes *(blank inside a template)* |

src/cli.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import wikity from './index';
44

5-
const VERSION = '1.0.0';
5+
const VERSION = '1.1.0';
66

77
const indent = (n: number): string => ' '.repeat(n * 4);
88
const usage = (command: string, ...desc: string[]): void => {
@@ -16,14 +16,17 @@ if (!arg(1)) {
1616
console.log('Type `wikity help` for a list of commands.');
1717
}
1818
else if (arg(1).includes('h')) {
19-
console.log(`\n${indent(1)}Wikity commands:`);
20-
usage(`wikity help`,
19+
console.log(`\n${indent(1)}Wikity CLI commands:`);
20+
usage(`wikity [--]h[elp]`,
2121
`Display this help message.`,
2222
);
23-
usage(`wikity compile [<folder>]`,
23+
usage(`wikity [--]c[ompile] [<folder>]`,
2424
`Compile wikitext files from a given folder.`,
2525
)
26-
usage(`wikity version`,
26+
usage(`wikity [--]p[arse] "<input>"`,
27+
`Parse raw wikitext from the command line.`,
28+
)
29+
usage(`wikity [--]v[ersion]`,
2730
`Display the current version of Wikity.`,
2831
);
2932
}

src/compile.d.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
1-
declare type Config = {
2-
eleventy?: boolean;
3-
defaultStyles?: boolean;
4-
customStyles?: string;
5-
};
1+
import { Config } from './types';
62
export declare function compile(dir?: string, config?: Config): void;
7-
export {};

src/compile.ts

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,24 @@ const formatter = require('html-formatter');
44
const novasheets = require('novasheets');
55

66
import { parse } from './parse';
7+
import { Config, Result } from './types';
78

89
const OUT_FOLDER = 'wikity-out/';
910

10-
type Config = {
11-
eleventy?: boolean,
12-
defaultStyles?: boolean,
13-
customStyles?: string,
14-
}
15-
1611
export function compile(dir: string = '.', config: Config = {}): void {
1712
let stylesCreated = false;
1813
// Write wikitext files
1914
const files = glob.sync((dir || '.') + "/**/*.wiki", {});
2015
files.forEach((file: string) => {
2116
let data: string = fs.readFileSync(file, { encoding: 'utf8' });
17+
let content: Result = parse(data);
18+
let outText: string = content.toString();
2219

2320
let [, folder, filename]: string[] = file.match(/^(.+?[\/\\])((?:templates[\/\\])?[^\/\\]+)$/) as RegExpMatchArray;
2421
let outFolder: string = (dir || folder || '.') + '/' + OUT_FOLDER;
2522
let outFilename: string = filename.replace(/ /g, '_').replace('.wiki', '.html');
2623
let url: string = outFilename.replace(/(?<=^|\/)\w/g, m => m.toUpperCase())
27-
let displayTitle: string = url.replace('.html', '');
28-
29-
let outText = parse(data);
24+
let displayTitle: string = content.metadata.displayTitle || url.replace('.html', '');
3025

3126
// Eleventy configuration
3227
let frontMatter: string = '';
@@ -39,18 +34,42 @@ export function compile(dir: string = '.', config: Config = {}): void {
3934
}
4035

4136
// Create HTML
37+
let toc: string = '';
38+
if (!content.metadata.notoc && (content.metadata.toc || (outText.match(/<h\d[^>]*>/g)?.length || 0) > 3)) {
39+
let headings = Array.from(content.match(/<h\d[^>]*>.+?<\/h\d>/gs) || []);
40+
headings.forEach(match => {
41+
const text: string = match.replace(/\s*<\/?h\d[^>]*>\s*/g, '');
42+
const lvl: number = +(match.match(/\d/g)?.[0] || -1);
43+
toc += `${`<ol>`.repeat(lvl - 1)} <li> <a href="#${encodeURI(text.replace(/ /g, '_'))}">${text}</a> </li> ${`</ol>`.repeat(lvl - 1)}`;
44+
});
45+
toc = `
46+
<div id="toc">
47+
<span id="toc-heading">
48+
<strong>Contents</strong>
49+
[<a href="javascript:void(0)" onclick="
50+
this.parentNode.parentNode.setAttribute('class', this.innerText === 'hide' ? 'toc-hidden' : '');
51+
this.innerText = this.innerText === 'hide' ? 'show' : 'hide';
52+
">hide</a>]
53+
</span>
54+
<ol>${toc}</ol>
55+
</div>
56+
`;
57+
if (outText.includes('<toc></toc>')) outText = outText.replace('<toc></toc>', toc);
58+
else outText = outText.replace(/<h\d[^>]*>/, toc + '$&');
59+
}
60+
4261
let html = `
4362
<html>
4463
<head>
4564
<meta charset="utf-8">
4665
<meta name="viewport" content="initial-scale=1.0, width=device-width">
4766
<meta name="description" content="${data.substr(0, 256)}">
4867
<title>${displayTitle}</title>
49-
<link rel="stylesheet" href="/wiki.css">
68+
<link id="default-styles" rel="stylesheet" href="/wiki.css">
5069
</head>
5170
<body>
5271
<header>
53-
<h1>${displayTitle}</h1>
72+
<h1 id="page-title">${displayTitle}</h1>
5473
</header>
5574
<main>
5675
<p>\n${outText}
@@ -68,7 +87,8 @@ export function compile(dir: string = '.', config: Config = {}): void {
6887
fs.mkdirSync(outFolder);
6988
fs.mkdirSync(outFolder + 'templates/');
7089
}
71-
fs.writeFileSync(outFolder + outFilename, frontMatter + formatter.render(html), 'utf8');
90+
let renderedHtml = formatter.render(html).replace(/(<\/\w+>)(\S)/g, '$1 $2');
91+
fs.writeFileSync(outFolder + outFilename, frontMatter + renderedHtml, 'utf8');
7292

7393
// Create site files
7494
if (stylesCreated) return;
@@ -87,6 +107,11 @@ export function compile(dir: string = '.', config: Config = {}): void {
87107
a.internal-link {color: #04a;} &:visited {color: #26d;}
88108
a.external-link {color: #36b;} &:visited {color: #58d;} &::after {content: '\\1f855';}
89109
a.redlink {color: #d33;} &:visited {color: #b44;}
110+
111+
#toc {display: inline-block; border: 1px solid #aab; padding: 8px; background-color: #f8f8f8; font-size: 95%;}
112+
&-heading {display: block; text-align: center;}
113+
& ol {margin: 0 0 0 1.3em;}
114+
&.toc-hidden {height: 1em;} % ol {display: none;}
90115
`.replace(/^\s+/gm, ''));
91116
}
92117
if (config.customStyles) styles += config.customStyles;

src/index.d.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { compile } from './compile';
2-
import { parse } from './parse';
32
declare const _default: {
43
compile: typeof compile;
5-
parse: typeof parse;
4+
parse: (data: string) => string;
65
};
76
export = _default;

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import { parse } from './parse';
33

44
export = {
55
compile,
6-
parse,
6+
parse: (data: string): string => parse(data).toString(),
77
};

src/parse.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export declare function parse(data: string): string;
1+
import { Result } from './types';
2+
export declare function parse(data: string): Result;

0 commit comments

Comments
 (0)