-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
158 lines (130 loc) · 5.03 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
const highlightJs = require('highlight.js')
/**
* Add GOV.UK typography classes to blockquotes, headings, paragraphs, links,
* lists, section breaks and tables
*
* @param {object} [options] - Options for the extension
* @returns {object} A MarkedExtension to be passed to `marked.use()`
*/
module.exports = function (options = {}) {
return {
renderer: {
// Block quotes
blockquote({ tokens }) {
const body = this.parser.parse(tokens)
return `<blockquote class="govuk-inset-text govuk-!-margin-left-0">${body}</blockquote>\n`
},
// Headings
heading({ tokens, depth, raw }) {
const text = this.parser.parseInline(tokens)
const id = raw
.toLowerCase()
.replace(/[^\w\s]+/g, '') // Replace all but words and spaces
.trim()
.replace(/\s/g, '-') // Replace spaces with hyphens
// Make modifiers relative to the starting heading depth
const modifiers = ['xl', 'l', 'm', 's']
const headingsStartWith = modifiers.includes(options.headingsStartWith)
? options.headingsStartWith
: 'l'
const modifierStartIndex = modifiers.indexOf(headingsStartWith)
const modifier = modifiers[modifierStartIndex + depth - 1] || 's'
return `<h${depth} class="govuk-heading-${modifier}" id="${id}">${text}</h${depth}>`
},
// Paragraphs
paragraph({ tokens }) {
const text = this.parser.parseInline(tokens)
// Don’t place figure (or figure within an anchor) within paragraph
const FIGURE_RE = /(<a([^>]+)>)?<figure/
if (FIGURE_RE.test(text)) {
return text
}
return `<p class="govuk-body">${text}</p>\n`
},
// Links
link({ href, title, tokens }) {
const text = this.parser.parseInline(tokens)
if (title) {
return `<a class="govuk-link" href="${href}" title="${title}">${text}</a>`
}
return `<a class="govuk-link" href="${href}">${text}</a>`
},
// Lists
list({ ordered, start, items }) {
let body = ''
for (const item in items) {
body += this.listitem(items[item])
}
const element = ordered ? 'ol' : 'ul'
const modifier = ordered ? 'number' : 'bullet'
const startAttr = ordered && start !== 1 ? ` start="${start}"` : ''
return `<${element}${startAttr} class="govuk-list govuk-list--${modifier}">${body}</${element}>\n`
},
// Checkbox
checkbox({ checked }) {
return `<span class="x-govuk-checkbox"><input class="x-govuk-checkbox__input" type="checkbox"${
checked ? ' checked' : ''
} disabled><span class="x-govuk-checkbox__pseudo"></span></span>`
},
// Section break
hr() {
return '<hr class="govuk-section-break govuk-section-break--xl govuk-section-break--visible">\n'
},
// Tables
table({ header, rows }) {
// Table head
let head = ''
let text = ''
for (const cell in header) {
text += this.tablecell(header[cell])
}
head += this.tablerow({ text })
// Table body
let body = ''
for (let row in rows) {
row = rows[row]
text = ''
for (const cell in row) {
text += this.tablecell(row[cell])
}
body += this.tablerow({ text })
}
if (body) {
body = `<tbody class="govuk-table__body">${body}</tbody>\n`
}
return `<table class="govuk-table">\n<thead class="govuk-table__head">\n${head}</thead>\n${body}</table>\n`
},
tablerow({ text }) {
return `<tr class="govuk-table__row">\n${text}</tr>\n`
},
tablecell({ tokens, header, align }) {
const text = this.parser.parseInline(tokens)
const element = header ? 'th' : 'td'
const className = header ? 'govuk-table__header' : 'govuk-table__cell'
const alignClass = align ? ` govuk-!-text-align-${align}` : ''
return `<${element} class="${className}${alignClass}">${text}</${element}>\n`
},
// Block code
// By not using marked’s `highlight` option, we can add a class to the container
code({ text, lang: language }) {
highlightJs.configure({ classPrefix: 'x-govuk-code__' })
if (language) {
// Code language has been set, or can be determined
let code
if (highlightJs.getLanguage(language)) {
code = highlightJs.highlight(text, { language }).value
} else {
code = highlightJs.highlightAuto(text).value
}
return `<pre class="x-govuk-code x-govuk-code--block x-govuk-code__language--${language}" tabindex="0"><code>${code}</code></pre>\n`
}
// No language found, so render as plain text
return `<pre class="x-govuk-code x-govuk-code--block" tabindex="0">${text}</pre>\n`
},
// Inline code
codespan({ text }) {
return `<code class="x-govuk-code x-govuk-code--inline">${text}</code>`
}
}
}
}