UNPKG

5.12 kBJavaScriptView Raw
1var escape = require('escape-html')
2var group = require('commonform-group-series')
3var hash = require('commonform-hash')
4var predicate = require('commonform-predicate')
5
6function renderParagraph (paragraph, offset, path, blanks, html5) {
7 return (
8 '<p>' +
9 paragraph.content
10 .map(function (element, index) {
11 if (predicate.text(element)) {
12 return escape(element)
13 } else if (predicate.use(element)) {
14 return (
15 '<span class="term">' +
16 escape(element.use) +
17 '</span>'
18 )
19 } else if (predicate.definition(element)) {
20 return (
21 (html5 ? '<dfn>' : '<span class="definition">') +
22 escape(element.definition) +
23 (html5 ? '</dfn>' : '</span>')
24 )
25 } else if (predicate.blank(element)) {
26 var elementPath = path.concat('content', offset + index)
27 var value = matchingValue(elementPath, blanks)
28 return (
29 '<span class="blank">' +
30 (value ? escape(value) : escape('[•]')) +
31 '</span>'
32 )
33 } else if (predicate.reference(element)) {
34 return (
35 '<span class="reference">' +
36 escape(element.reference) +
37 '</span>'
38 )
39 }
40 })
41 .join('') +
42 '</p>'
43 )
44}
45
46function matchingValue (path, blanks) {
47 var length = blanks.length
48 for (var index = 0; index < length; index++) {
49 var blank = blanks[index]
50 if (equal(blank.blank, path)) {
51 return blank.value
52 }
53 }
54}
55
56function heading (depth, text) {
57 if (depth <= 6) {
58 return (
59 '<h' + depth + '>' +
60 escape(text) +
61 '</h' + depth + '>'
62 )
63 } else {
64 return (
65 '<span class="h' + depth + '">' +
66 escape(text) +
67 '</span>'
68 )
69 }
70}
71
72function renderSeries (
73 depth, offset, path, series, blanks, html5, lists
74) {
75 var simple = lists && !series.content.some(containsAHeading)
76 if (simple) {
77 return (
78 '<ol>' +
79 series.content
80 .map(function (child, index) {
81 return (
82 (
83 child.form.conspicuous
84 ? '<li class="conspicuous">'
85 : '<li>'
86 ) +
87 renderForm(
88 depth,
89 path.concat('content', offset + index, 'form'),
90 child.form,
91 blanks,
92 html5,
93 lists
94 ) +
95 '</li>'
96 )
97 })
98 .join('') +
99 '</ol>'
100 )
101 } else {
102 return series.content
103 .map(function (child, index) {
104 return (
105 (
106 html5
107 ? child.form.conspicuous
108 ? '<section class="conspicuous">'
109 : '<section>'
110 : child.form.conspicuous
111 ? '<div class="section conspicuous">'
112 : '<div class="section">'
113 ) +
114 ('heading' in child ? heading(depth, child.heading) : '') +
115 renderForm(
116 depth,
117 path.concat('content', offset + index, 'form'),
118 child.form,
119 blanks,
120 html5,
121 lists
122 ) +
123 (html5 ? '</section>' : '</div>')
124 )
125 })
126 .join('')
127 }
128}
129
130function renderForm (depth, path, form, blanks, html5, lists) {
131 var offset = 0
132 return group(form)
133 .map(function (group) {
134 var returned = group.type === 'series'
135 ? renderSeries(
136 depth + 1, offset, path, group, blanks, html5, lists
137 )
138 : renderParagraph(group, offset, path, blanks, html5)
139 offset += group.content.length
140 return returned
141 })
142 .join('')
143}
144
145module.exports = function commonformHTML (form, blanks, options) {
146 blanks = blanks || []
147 options = options || {}
148 var html5 = 'html5' in options && options.html5 === true
149 var lists = 'lists' in options && options.lists === true
150 var title = 'title' in options ? options.title : false
151 var edition = 'edition' in options ? options.edition : false
152 return (
153 (
154 html5
155 ? form.conspicuous
156 ? '<article class="conspicuous">'
157 : '<article>'
158 : form.conspicuous
159 ? '<div class="article conspicuous">'
160 : '<div class="article">'
161 ) +
162 (title ? ('<h1>' + escape(title) + '</h1>') : '') +
163 (edition ? ('<p class="edition">' + escape(edition) + '</p>') : '') +
164 (
165 options.hash
166 ? ('<p class="hash"><code>' + hash(form) + '</code></p>')
167 : ''
168 ) +
169 renderForm((title ? 1 : 0), [], form, blanks, html5, lists) +
170 (html5 ? '</article>' : '</div>')
171 )
172}
173
174function equal (a, b) {
175 return (
176 Array.isArray(a) &&
177 Array.isArray(b) &&
178 a.length === b.length &&
179 a.every(function (_, index) {
180 return a[index] === b[index]
181 })
182 )
183}
184
185function containsAHeading (child) {
186 return (
187 child.hasOwnProperty('heading') ||
188 child.form.content.some(function (element) {
189 return (
190 element.hasOwnProperty('form') &&
191 containsAHeading(element)
192 )
193 })
194 )
195}