Skip to content

Commit 60f50dd

Browse files
committed
refactor(config): put tracToHTML in its own file
1 parent 70342a9 commit 60f50dd

3 files changed

Lines changed: 135 additions & 147 deletions

File tree

eleventy.config.js

Lines changed: 2 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ const fs = require('node:fs')
1010
const path = require('node:path')
1111

1212
const pluginImages = require('./eleventy.config.images.js')
13-
14-
function escapeHTML(string) {
15-
return string.replace(/</g, '&lt;').replace(/>/g, '&gt;')
16-
}
13+
const tracToHTML = require('./eleventy.config.tracToHTML.js')
1714

1815
module.exports = function (eleventyConfig) {
1916
// Copy the contents of the `public` folder to the output folder
@@ -159,147 +156,7 @@ module.exports = function (eleventyConfig) {
159156
)
160157
})
161158

162-
// Customize Markdown library settings:
163-
// eleventyConfig.amendLibrary('md', (mdLib) => {
164-
// mdLib.use(markdownItAnchor, {
165-
// permalink: markdownItAnchor.permalink.ariaHidden({
166-
// placement: 'after',
167-
// class: 'header-anchor',
168-
// symbol: '#',
169-
// ariaHidden: false
170-
// }),
171-
// level: [1, 2, 3, 4],
172-
// slugify: eleventyConfig.getFilter('slugify')
173-
// })
174-
// })
175-
176-
const rasterisks = /^\s*\* /
177-
const rheaders = /^ *(\=+) *([^\n\r]+) *\1? *$/
178-
let listStarted = false
179-
eleventyConfig.addFilter('tracToHTML', (text) => {
180-
const codes = []
181-
const pres = []
182-
return (
183-
escapeHTML(text)
184-
// Newlines have extra escapes in the strings
185-
.replace(/\\\n/g, '\n')
186-
// Replace `` with <code> tags
187-
.replace(/`([^\r\n`]+?)`/g, (_match, code) => {
188-
codes.push(code) // Save the code for later
189-
return `<code></code>`
190-
})
191-
// Replace {{{ }}} with <pre> tags
192-
.replace(/{{{([^]+?)}}}/g, (_match, code) => {
193-
// Save the code for later
194-
pres.push(
195-
// Remove language hints
196-
code.replace(/^#!\w+\r?\n/, '')
197-
)
198-
return `<pre class="wiki"></pre>`
199-
})
200-
// Linkify http links in brackets
201-
.replace(
202-
/\[(https?:\/\/[^\s\]]+)(?:\s+([^\]]+))?\]/g,
203-
function (_match, url, text) {
204-
return `<a href="${url}" class="ext-link"><span class="icon"></span>${
205-
text || url
206-
}</a>`
207-
}
208-
)
209-
// Linkify hash links in brackets
210-
.replace(
211-
/\[(#[^\s\]]+)(?:\s+([^\]]+))?\]/g,
212-
function (_match, url, text) {
213-
return `<a href="${url}" class="ext-link"><span class="icon"></span>${
214-
text || url
215-
}</a>`
216-
}
217-
)
218-
// Linkify CamelCase links in brackets
219-
.replace(
220-
/\[([A-Z][a-z]+[A-Z][\w#-]+)(?:\s+([^\]]+))?\]/g,
221-
function (_match, page, text) {
222-
return `<a href="/wiki/${page}">${text || page}</a>`
223-
}
224-
)
225-
// Linkify trac links
226-
.replace(
227-
/(?:\[trac:([^ ]+) "([^"]+)"\])|(?:\[trac:([^\s\]]+)(?: ([^\]]+))?\])/g,
228-
function (_match, quotepage, quotedtext, page, text) {
229-
return `<a href="https://trac.edgewall.org/intertrac/${
230-
quotepage || page
231-
}" class="ext-link"><span class="icon"></span>${
232-
quotedtext || text || page
233-
}</a>`
234-
}
235-
)
236-
// Linkify ticket references (avoid trac ticket links)
237-
.replace(/#(\d+)(?!<=>)/g, `<a href="/ticket/$1">$&</a>`)
238-
// Linkify CamelCase to wiki
239-
.replace(
240-
/(^|\s)(!)?([A-Z][a-z]+[A-Z]\w+(?:#\w+)?)(?!\w)/g,
241-
function (_match, space, excl, page) {
242-
if (excl) {
243-
return `${space}${page}`
244-
}
245-
return `${space}<a href="/wiki/${page}">${page}</a>`
246-
}
247-
)
248-
// Convert ---- to <hr>
249-
.replace(/^--+$/gm, '<hr />')
250-
// Replace three single quotes with <strong>
251-
.replace(/'''([^']+)'''/g, '<strong>$1</strong>')
252-
// Replace double newlines with paragraphs
253-
.split(/(?:\r?\n)/g)
254-
.map((line) => {
255-
let ret = ''
256-
if (listStarted && !rasterisks.test(line)) {
257-
listStarted = false
258-
ret += '</ul>'
259-
}
260-
if (!line.trim()) {
261-
return ret
262-
}
263-
if (line.startsWith('<pre')) {
264-
return ret + line
265-
}
266-
// Blockquotes
267-
if (line.startsWith('> ')) {
268-
return ret + `<blockquote>${line.slice(2)}</blockquote>`
269-
}
270-
// Headers
271-
if (rheaders.test(line)) {
272-
return (
273-
ret +
274-
line.replace(rheaders, (_all, equals, content) => {
275-
const level = equals.length
276-
return `<h${level}>${content}</h${level}>`
277-
})
278-
)
279-
}
280-
if (rasterisks.test(line)) {
281-
line = line.replace(
282-
/(^|\s+)\* ([^\n]+)/g,
283-
`$1${listStarted ? '' : '<ul>'}<li>$2</li>`
284-
)
285-
listStarted = true
286-
return ret + line
287-
}
288-
return ret + `<p>${line}</p>`
289-
})
290-
.join('')
291-
// Reinsert code
292-
.replace(/<code><\/code>/g, () => {
293-
const code = codes.shift()
294-
return `<code>${code}</code>`
295-
})
296-
// Reinsert pres
297-
.replace(/<pre class="wiki"><\/pre>/g, () => {
298-
const code = pres.shift()
299-
return `<pre class="wiki">${code}</pre>`
300-
})
301-
)
302-
})
159+
eleventyConfig.addFilter('tracToHTML', tracToHTML)
303160

304161
// Shortcodes
305162
eleventyConfig.addShortcode('currentYear', () => {

eleventy.config.tracToHTML.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
const rasterisks = /^\s*\* /
2+
const rheaders = /^ *(\=+) *([^\n\r]+) *\1? *$/
3+
let listStarted = false
4+
5+
function escapeHTML(string) {
6+
return string.replace(/</g, '&lt;').replace(/>/g, '&gt;')
7+
}
8+
9+
module.exports = function tracToHTML(text) {
10+
const codes = []
11+
const pres = []
12+
return (
13+
escapeHTML(text)
14+
// Newlines have extra escapes in the strings
15+
.replace(/\\\n/g, '\n')
16+
// Replace `` with <code> tags
17+
.replace(/`([^\r\n`]+?)`/g, (_match, code) => {
18+
codes.push(code) // Save the code for later
19+
return `<code></code>`
20+
})
21+
// Replace {{{ }}} with <pre> tags
22+
.replace(/{{{([^]+?)}}}/g, (_match, code) => {
23+
// Save the code for later
24+
pres.push(
25+
// Remove language hints
26+
code.replace(/^#!\w+\r?\n/, '')
27+
)
28+
return `<pre class="wiki"></pre>`
29+
})
30+
// Linkify http links in brackets
31+
.replace(
32+
/\[(https?:\/\/[^\s\]]+)(?:\s+([^\]]+))?\]/g,
33+
function (_match, url, text) {
34+
return `<a href="${url}" class="ext-link"><span class="icon"></span>${
35+
text || url
36+
}</a>`
37+
}
38+
)
39+
// Linkify hash links in brackets
40+
.replace(
41+
/\[(#[^\s\]]+)(?:\s+([^\]]+))?\]/g,
42+
function (_match, url, text) {
43+
return `<a href="${url}" class="ext-link"><span class="icon"></span>${
44+
text || url
45+
}</a>`
46+
}
47+
)
48+
// Linkify CamelCase links in brackets
49+
.replace(
50+
/\[([A-Z][a-z]+[A-Z][\w#-]+)(?:\s+([^\]]+))?\]/g,
51+
function (_match, page, text) {
52+
return `<a href="/wiki/${page}">${text || page}</a>`
53+
}
54+
)
55+
// Linkify trac links
56+
.replace(
57+
/(?:\[trac:([^ ]+) "([^"]+)"\])|(?:\[trac:([^\s\]]+)(?: ([^\]]+))?\])/g,
58+
function (_match, quotepage, quotedtext, page, text) {
59+
return `<a href="https://trac.edgewall.org/intertrac/${
60+
quotepage || page
61+
}" class="ext-link"><span class="icon"></span>${
62+
quotedtext || text || page
63+
}</a>`
64+
}
65+
)
66+
// Linkify ticket references (avoid trac ticket links)
67+
.replace(/#(\d+)(?!<=>)/g, `<a href="/ticket/$1">$&</a>`)
68+
// Linkify CamelCase to wiki
69+
.replace(
70+
/(^|\s)(!)?([A-Z][a-z]+[A-Z]\w+(?:#\w+)?)(?!\w)/g,
71+
function (_match, space, excl, page) {
72+
if (excl) {
73+
return `${space}${page}`
74+
}
75+
return `${space}<a href="/wiki/${page}">${page}</a>`
76+
}
77+
)
78+
// Convert ---- to <hr>
79+
.replace(/^--+$/gm, '<hr />')
80+
// Replace three single quotes with <strong>
81+
.replace(/'''([^']+)'''/g, '<strong>$1</strong>')
82+
// Replace double newlines with paragraphs
83+
.split(/(?:\r?\n)/g)
84+
.map((line) => {
85+
let ret = ''
86+
if (listStarted && !rasterisks.test(line)) {
87+
listStarted = false
88+
ret += '</ul>'
89+
}
90+
if (!line.trim()) {
91+
return ret
92+
}
93+
if (line.startsWith('<pre')) {
94+
return ret + line
95+
}
96+
// Blockquotes
97+
if (line.startsWith('> ')) {
98+
return ret + `<blockquote>${line.slice(2)}</blockquote>`
99+
}
100+
// Headers
101+
if (rheaders.test(line)) {
102+
return (
103+
ret +
104+
line.replace(rheaders, (_all, equals, content) => {
105+
const level = equals.length
106+
return `<h${level}>${content}</h${level}>`
107+
})
108+
)
109+
}
110+
if (rasterisks.test(line)) {
111+
line = line.replace(
112+
/(^|\s+)\* ([^\n]+)/g,
113+
`$1${listStarted ? '' : '<ul>'}<li>$2</li>`
114+
)
115+
listStarted = true
116+
return ret + line
117+
}
118+
return ret + `<p>${line}</p>`
119+
})
120+
.join('')
121+
// Reinsert code
122+
.replace(/<code><\/code>/g, () => {
123+
const code = codes.shift()
124+
return `<code>${code}</code>`
125+
})
126+
// Reinsert pres
127+
.replace(/<pre class="wiki"><\/pre>/g, () => {
128+
const code = pres.shift()
129+
return `<pre class="wiki">${code}</pre>`
130+
})
131+
)
132+
}

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
{
22
"name": "bugs.jquery.com",
33
"version": "0.0.1",
4-
"description": "Static archive of the old bugs.jquery.com trac site.",
4+
"description": "Static archive of the old bugs.jquery.com trac site, built with eleventy.",
55
"scripts": {
66
"clean": "rimraf _site/",
77
"build": "npm run clean && npx @11ty/eleventy",
88
"postbuild": "npm run searchindex",
99
"start": "npm run clean && cross-env NODE_ENV=development npx @11ty/eleventy --serve --quiet",
10-
"poststart": "npm run searchindex",
1110
"debug": "npm run clean && DEBUG=Eleventy* npx @11ty/eleventy",
1211
"debugstart": "npm run clean && DEBUG=Eleventy* npx @11ty/eleventy --serve --quiet",
1312
"benchmark": "npm run clean && DEBUG=Eleventy:Benchmark* npx @11ty/eleventy",

0 commit comments

Comments
 (0)