@@ -5,8 +5,8 @@ complete control over formatting and syntax highlighting */
55'use strict' ;
66
77/**
8- @author Mike Ralphson <mike.ralphson@gmail.com>
9- **/
8+ * @author Mike Ralphson <mike.ralphson@gmail.com>
9+ **/
1010
1111const fs = require ( 'fs' ) ;
1212const path = require ( 'path' ) ;
@@ -34,9 +34,9 @@ const md = require('markdown-it')({
3434 linkify : true ,
3535 typographer : true ,
3636 highlight : function ( str , lang ) {
37- if ( lang && hljs . getLanguage ( lang ) ) { // && !argv.respec) {
37+ if ( lang && hljs . getLanguage ( lang ) ) {
3838 try {
39- return '<pre class="nohighlight"><code>' +
39+ return '<pre class="nohighlight" tabindex="0" ><code>' +
4040 hljs . highlight ( str , { language : lang } ) . value +
4141 '</code></pre>' ;
4242 } catch ( __ ) { }
@@ -86,56 +86,9 @@ function preface(title,options) {
8686 ] ,
8787 } ,
8888 ] ,
89- localBiblio : {
90- "OpenAPI-Learn" : {
91- title : "OpenAPI - Getting started, and the specification explained" ,
92- href : "https://learn.openapis.org/" ,
93- publisher : "OpenAPI Initiative"
94- } ,
95- "OpenAPI-Registry" : {
96- title : "OpenAPI Initiative Registry" ,
97- href : "https://spec.openapis.org/registry/index.html" ,
98- publisher : "OpenAPI Initiative"
99- } ,
100- //TODO: remove localBiblio once Specref PRs https://github.com/tobie/specref/pulls/ralfhandl are merged
101- "JSON-Schema-Validation-04" : {
102- authors : [ "Kris Zyp" , "Francis Galiegue" , "Gary Court" ] ,
103- href : "https://datatracker.ietf.org/doc/html/draft-fge-json-schema-validation-00" ,
104- publisher : "Internet Engineering Task Force (IETF)" ,
105- status : "Internet-Draft" ,
106- title : "JSON Schema: interactive and non interactive validation. Draft 4" ,
107- date : "1 February 2013"
108- } ,
109- "JSON-Schema-05" : {
110- authors : [ "Austin Wright" ] ,
111- href : "https://datatracker.ietf.org/doc/html/draft-wright-json-schema-00" ,
112- publisher : "Internet Engineering Task Force (IETF)" ,
113- status : "Internet-Draft" ,
114- title : "JSON Schema: A Media Type for Describing JSON Documents. Draft 5" ,
115- date : "13 October 2016"
116- } ,
117- "JSON-Schema-Validation-05" : {
118- authors : [ "Austin Wright" , "G. Luff" ] ,
119- href : "https://datatracker.ietf.org/doc/html/draft-wright-json-schema-validation-00" ,
120- publisher : "Internet Engineering Task Force (IETF)" ,
121- status : "Internet-Draft" ,
122- title : "JSON Schema Validation: A Vocabulary for Structural Validation of JSON. Draft 5" ,
123- date : "13 October 2016"
124- } ,
125- "JSON-Schema-Validation-2020-12" : {
126- authors : [ "Austin Wright" , "Henry Andrews" , "Ben Hutton" ] ,
127- href : "https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-validation-00" ,
128- publisher : "Internet Engineering Task Force (IETF)" ,
129- status : "Internet-Draft" ,
130- title : "JSON Schema Validation: A Vocabulary for Structural Validation of JSON. Draft 2020-12" ,
131- date : "8 December 2020"
132- } ,
133- "SPDX" : {
134- href : "https://spdx.org/licenses/" ,
135- title : "SPDX License List" ,
136- publisher : "Linux Foundation"
137- }
138- }
89+ // localBiblio: {
90+ // // add local bibliography entries here, add them to https://www.specref.org/, and remove them here once published
91+ // }
13992 } ;
14093
14194 let preface = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>${ md . utils . escapeHtml ( title ) } </title>` ;
@@ -154,9 +107,10 @@ function preface(title,options) {
154107 preface += '</head><body>' ;
155108 preface += '<style>' ;
156109 preface += '#respec-ui { visibility: hidden; }' ;
157- preface += 'h1,h2,h3 { color: #629b34; }' ;
158- preface += '.dt-published { color: #629b34; } .dt-published::before { content: "Published "; }' ;
159- preface += 'a[href] { color: #45512c; }' ; // third OAI colour is #8ad000
110+ preface += '#title { color: #578000; } #subtitle { color: #578000; }' ;
111+ preface += '.dt-published { color: #578000; } .dt-published::before { content: "Published "; }' ;
112+ preface += 'h1,h2,h3,h4,h5,h6 { color: #578000; font-weight: normal; font-style: normal; }' ;
113+ preface += 'a[href] { color: #45512c; }' ;
160114 preface += 'body:not(.toc-inline) #toc h2 { color: #45512c; }' ;
161115 preface += 'table { display: block; width: 100%; overflow: auto; }' ;
162116 preface += 'table th { font-weight: 600; }' ;
@@ -247,68 +201,30 @@ let indents = [0];
247201for ( let l in lines ) {
248202 let line = lines [ l ] ;
249203
204+ // remove TOC from older spec versions, respec will generate a new one
250205 if ( line . startsWith ( '## Table of Contents' ) ) inTOC = true ;
251206 if ( line . startsWith ( '<!-- /TOC' ) ) inTOC = false ;
252207 if ( inTOC ) line = '' ;
253208
209+ // special formatting for Definitions section
254210 if ( line . startsWith ( '## Definitions' ) ) {
255211 inDefs = true ;
256212 bsFix = false ;
257213 }
258214 else if ( line . startsWith ( '## ' ) ) inDefs = false ;
259215
216+ // recognize code blocks
260217 if ( line . startsWith ( '```' ) ) {
261218 inCodeBlock = ! inCodeBlock ;
262- line += '\n' ; // fixes formatting of first line of syntax-highlighted blocks
263- }
264-
265- if ( ! inCodeBlock && line . startsWith ( '#' ) ) {
266- let indent = 0 ;
267- while ( line [ indent ] === '#' ) indent ++ ;
268- let originalIndent = indent ;
269-
270- let prevIndent = indents [ indents . length - 1 ] ; // peek
271- let delta = indent - prevIndent ;
272-
273- if ( ! argv . respec ) {
274- if ( delta === 0 ) indent = lastIndent
275- else if ( delta < 0 ) indent = lastIndent - 1
276- else if ( delta > 0 ) indent = lastIndent + 1 ;
277- }
278-
279- if ( indent < 0 ) {
280- indent = 1 ;
281- }
282- if ( argv . respec && ( indent > 1 ) ) {
283- indent -- ;
284- }
285- let newIndent = indent ;
286- if ( ! argv . respec && ( indent <= 2 ) && bsFix ) {
287- newIndent ++ ;
288- }
289-
290- let title = line . split ( '# ' ) [ 1 ] ;
291- if ( inDefs ) title = '<dfn>' + title + '</dfn>' ;
292- line = ( '#' . repeat ( newIndent ) + ' ' + title ) ;
293-
294- if ( delta > 0 ) indents . push ( originalIndent ) ;
295- if ( delta < 0 ) {
296- let d = Math . abs ( delta ) ;
297- while ( d > 0 ) {
298- indents . pop ( ) ;
299- d -- ;
300- }
301- }
302- lastIndent = indent ;
303219 }
304220
305221 if ( line . indexOf ( '<a name="' ) >= 0 ) {
306222 if ( line . indexOf ( '<a name="parameterAllowEmptyValue"/>' ) >= 0 )
307223 // fix syntax error in 2.0.md
308224 line = line . replace ( '<a name="parameterAllowEmptyValue"/>' , '<span id="parameterAllowEmptyValue"></span>' ) ;
309225 else {
310- line = line . replace ( ' <a name=' , '< span id=' ) ;
311- line = line . replace ( '< /a>' , ' </span>') ;
226+ // replace deprecated <a name="..."></a> with < span id="..."></span>
227+ line = line . replace ( / < a n a m e = " ( [ ^ " ] + ) " > < \ /a > / g , '<span id="$1"> </span>') ;
312228 }
313229 }
314230
@@ -352,6 +268,7 @@ for (let l in lines) {
352268 line = line . replace ( 'consult http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4)' , 'consult [[HTML401]] [Section 17.13.4](http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4)' ) ;
353269 line = line . replace ( '[IANA Status Code Registry](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml)' , '[[IANA-HTTP-STATUS-CODES|IANA Status Code Registry]]' ) ;
354270 line = line . replace ( '[IANA Authentication Scheme registry](https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml)' , '[[IANA-HTTP-AUTHSCHEMES]]' ) ;
271+ line = line . replace ( '[JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03)' , '[[JSON-Reference|JSON Reference]]' ) ;
355272 line = line . replace ( '[JSON Schema Specification Draft 4](https://json-schema.org/)' , '[[JSON-Schema-04|JSON Schema Specification Draft 4]]' ) ;
356273 line = line . replace ( '[JSON Schema Core](https://tools.ietf.org/html/draft-zyp-json-schema-04)' , '[[JSON-Schema-04|JSON Schema Core]]' ) ;
357274 line = line . replace ( '[JSON Schema Validation](https://tools.ietf.org/html/draft-fge-json-schema-validation-00)' , '[[JSON-Schema-Validation-04|JSON Schema Validation]]' ) ;
@@ -361,13 +278,15 @@ for (let l in lines) {
361278 line = line . replace ( '[JSON Schema Specification Draft 2020-12](https://tools.ietf.org/html/draft-bhutton-json-schema-00)' , '[[JSON-Schema-2020-12|JSON Schema Specification Draft 2020-12]]' ) ;
362279 line = line . replace ( '[JSON Schema Core](https://tools.ietf.org/html/draft-bhutton-json-schema-00)' , '[[JSON-Schema-2020-12|JSON Schema Core]]' ) ;
363280 line = line . replace ( '[JSON Schema Validation](https://tools.ietf.org/html/draft-bhutton-json-schema-validation-00)' , '[[JSON-Schema-Validation-2020-12|JSON Schema Validation]]' ) ;
364- line = line . replace ( '[SPDX](https://spdx.org/licenses/)' , '[[SPDX]]' ) ;
281+ line = line . replace ( '[SPDX](https://spdx.org/licenses/) license ' , '[[SPDX-Licenses ]]' ) ;
365282 line = line . replace ( '[XML namespaces](https://www.w3.org/TR/xml-names11/)' , '[[xml-names11|XML namespaces]]' ) ;
366283 line = line . replace ( 'JSON standards. YAML,' , '[[RFC7159|JSON]] standards. [[YAML|YAML]],' ) ; // 2.0.md only
367284 line = line . replace ( 'JSON or YAML format.' , '[[RFC7159|JSON]] or [[YAML|YAML]] format.' ) ;
368285 line = line . replace ( / Y A M L v e r s i o n \[ 1 \. 2 \] \( h t t p s : \/ \/ ( w w w \. ) ? y a m l \. o r g \/ s p e c \/ 1 \. 2 \/ s p e c \. h t m l \) / , '[[YAML|YAML version 1.2]]' ) ;
369286 }
370287
288+ // fix relative links (to examples)
289+ //TODO: adjust when moving examples to a different repo
371290 if ( ! inCodeBlock && line . indexOf ( '](../' ) >= 0 ) {
372291 const regExp = / \( ( \. \. [ ^ ) ] + ) \) / g;
373292 line = line . replace ( regExp , function ( match , group1 ) {
@@ -376,6 +295,50 @@ for (let l in lines) {
376295 } ) ;
377296 }
378297
298+ // fix indentation of headings
299+ // - make sure that each heading is at most one level deeper than the previous heading
300+ // - reduce heading level by one if we're in respec mode except for h1
301+ if ( ! inCodeBlock && line . startsWith ( '#' ) ) {
302+ let indent = 0 ;
303+ while ( line [ indent ] === '#' ) indent ++ ;
304+ let originalIndent = indent ;
305+
306+ let prevIndent = indents [ indents . length - 1 ] ; // peek
307+ let delta = indent - prevIndent ;
308+
309+ if ( ! argv . respec ) {
310+ if ( delta === 0 ) indent = lastIndent
311+ else if ( delta < 0 ) indent = lastIndent - 1
312+ else if ( delta > 0 ) indent = lastIndent + 1 ;
313+ }
314+
315+ if ( indent < 0 ) {
316+ indent = 1 ;
317+ }
318+ if ( argv . respec && ( indent > 1 ) ) {
319+ indent -- ;
320+ }
321+ let newIndent = indent ;
322+ if ( ! argv . respec && ( indent <= 2 ) && bsFix ) {
323+ newIndent ++ ;
324+ }
325+
326+ let title = line . split ( '# ' ) [ 1 ] ;
327+ if ( inDefs ) title = '<dfn>' + title + '</dfn>' ;
328+ line = ( '#' . repeat ( newIndent ) + ' ' + title ) ;
329+
330+ if ( delta > 0 ) indents . push ( originalIndent ) ;
331+ if ( delta < 0 ) {
332+ let d = Math . abs ( delta ) ;
333+ while ( d > 0 ) {
334+ indents . pop ( ) ;
335+ d -- ;
336+ }
337+ }
338+ lastIndent = indent ;
339+ }
340+
341+ // wrap section text in <section>...</section> tags for respec
379342 if ( ! inCodeBlock && argv . respec && line . startsWith ( '#' ) ) {
380343 let heading = 0 ;
381344 while ( line [ heading ] === '#' ) heading ++ ;
@@ -384,16 +347,23 @@ for (let l in lines) {
384347 if ( delta > 0 ) delta = 1 ;
385348 let prefix = '' ;
386349 let newSection = '<section>' ;
387- if ( line . includes ( '## Version ' ) ) {
350+ const m = line . match ( / # V e r s i o n ( [ 0 - 9 . ] + ) $ / ) ;
351+ if ( m ) {
388352 // our conformance section is headlined with 'Version x.y.z'
353+ // and respec needs a conformance section in a "formal" specification
389354 newSection = '<section class="override" id="conformance">' ;
355+ // adjust the heading to be at level 2 because respec insists on h2 here
356+ // Note: older specs had this at h4, newer specs at h2, and all heading levels have been reduced by 1 in the preceding block
357+ line = '#' + m [ 0 ] ;
358+ delta = 1 ;
359+ heading = 2 ;
390360 }
391361 if ( line . includes ( 'Appendix' ) ) {
392362 newSection = '<section class="appendix">' ;
393363 }
394364
395365 // heading level delta is either 0 or is +1/-1, or we're in respec mode
396- /* respec insists on <section>...</section> breaks around headings */
366+ // respec insists on <section>...</section> breaks around headings
397367
398368 if ( delta === 0 ) {
399369 prefix = '</section>' + newSection ;
0 commit comments