@@ -5,8 +5,8 @@ complete control over formatting and syntax highlighting */
55'use strict' ;
66
77/**
8- @author Mike Ralphson <[email protected] >9- **/
8+ * @author Mike Ralphson <[email protected] >9+ **/
1010
1111const fs = require ( 'fs' ) ;
1212const path = require ( 'path' ) ;
@@ -34,7 +34,7 @@ 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 {
3939 return '<pre class="nohighlight"><code>' +
4040 hljs . highlight ( str , { language : lang } ) . value +
@@ -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; }' ;
@@ -166,7 +120,7 @@ function preface(title,options) {
166120 preface += 'pre { background-color: #f6f8fa !important; }' ;
167121 preface += 'code { color: #c83500 } th code { color: inherit }' ;
168122 preface += 'a.bibref { text-decoration: underline;}' ;
169- preface += fs . readFileSync ( path . resolve ( __dirname , 'gist.css' ) , 'utf8' ) . split ( '\n' ) . join ( ' ' ) ;
123+ preface += fs . readFileSync ( path . resolve ( __dirname , 'gist.css' ) , 'utf8' ) . split ( / \r ? \n / ) . join ( ' ' ) ;
170124 preface += '</style>' ;
171125 preface += `<h1 id="title">${ title . split ( '|' ) [ 0 ] } </h1>` ;
172126 preface += `<p class="copyright">Copyright © ${ options . publishDate . getFullYear ( ) } the Linux Foundation</p>` ;
@@ -247,68 +201,31 @@ 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 ;
262219 line += '\n' ; // fixes formatting of first line of syntax-highlighted blocks
263220 }
264221
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 ;
303- }
304-
305222 if ( line . indexOf ( '<a name="' ) >= 0 ) {
306223 if ( line . indexOf ( '<a name="parameterAllowEmptyValue"/>' ) >= 0 )
307224 // fix syntax error in 2.0.md
308225 line = line . replace ( '<a name="parameterAllowEmptyValue"/>' , '<span id="parameterAllowEmptyValue"></span>' ) ;
309226 else {
310- line = line . replace ( ' <a name=' , '< span id=' ) ;
311- line = line . replace ( '< /a>' , ' </span>') ;
227+ // replace deprecated <a name="..."></a> with < span id="..."></span>
228+ line = line . replace ( / < a n a m e = " ( [ ^ " ] + ) " > < \ /a > / g , '<span id="$1"> </span>') ;
312229 }
313230 }
314231
@@ -352,6 +269,7 @@ for (let l in lines) {
352269 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)' ) ;
353270 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]]' ) ;
354271 line = line . replace ( '[IANA Authentication Scheme registry](https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml)' , '[[IANA-HTTP-AUTHSCHEMES]]' ) ;
272+ line = line . replace ( '[JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03)' , '[[JSON-Reference|JSON Reference]]' ) ;
355273 line = line . replace ( '[JSON Schema Specification Draft 4](https://json-schema.org/)' , '[[JSON-Schema-04|JSON Schema Specification Draft 4]]' ) ;
356274 line = line . replace ( '[JSON Schema Core](https://tools.ietf.org/html/draft-zyp-json-schema-04)' , '[[JSON-Schema-04|JSON Schema Core]]' ) ;
357275 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 +279,15 @@ for (let l in lines) {
361279 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]]' ) ;
362280 line = line . replace ( '[JSON Schema Core](https://tools.ietf.org/html/draft-bhutton-json-schema-00)' , '[[JSON-Schema-2020-12|JSON Schema Core]]' ) ;
363281 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]]' ) ;
282+ line = line . replace ( '[SPDX](https://spdx.org/licenses/) license ' , '[[SPDX-Licenses ]]' ) ;
365283 line = line . replace ( '[XML namespaces](https://www.w3.org/TR/xml-names11/)' , '[[xml-names11|XML namespaces]]' ) ;
366284 line = line . replace ( 'JSON standards. YAML,' , '[[RFC7159|JSON]] standards. [[YAML|YAML]],' ) ; // 2.0.md only
367285 line = line . replace ( 'JSON or YAML format.' , '[[RFC7159|JSON]] or [[YAML|YAML]] format.' ) ;
368286 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]]' ) ;
369287 }
370288
289+ // fix relative links (to examples)
290+ //TODO: adjust when moving examples to a different repo
371291 if ( ! inCodeBlock && line . indexOf ( '](../' ) >= 0 ) {
372292 const regExp = / \( ( \. \. [ ^ ) ] + ) \) / g;
373293 line = line . replace ( regExp , function ( match , group1 ) {
@@ -376,6 +296,50 @@ for (let l in lines) {
376296 } ) ;
377297 }
378298
299+ // fix indentation of headings
300+ // - make sure that each heading is at most one level deeper than the previous heading
301+ // - reduce heading level by one if we're in respec mode except for h1
302+ if ( ! inCodeBlock && line . startsWith ( '#' ) ) {
303+ let indent = 0 ;
304+ while ( line [ indent ] === '#' ) indent ++ ;
305+ let originalIndent = indent ;
306+
307+ let prevIndent = indents [ indents . length - 1 ] ; // peek
308+ let delta = indent - prevIndent ;
309+
310+ if ( ! argv . respec ) {
311+ if ( delta === 0 ) indent = lastIndent
312+ else if ( delta < 0 ) indent = lastIndent - 1
313+ else if ( delta > 0 ) indent = lastIndent + 1 ;
314+ }
315+
316+ if ( indent < 0 ) {
317+ indent = 1 ;
318+ }
319+ if ( argv . respec && ( indent > 1 ) ) {
320+ indent -- ;
321+ }
322+ let newIndent = indent ;
323+ if ( ! argv . respec && ( indent <= 2 ) && bsFix ) {
324+ newIndent ++ ;
325+ }
326+
327+ let title = line . split ( '# ' ) [ 1 ] ;
328+ if ( inDefs ) title = '<dfn>' + title + '</dfn>' ;
329+ line = ( '#' . repeat ( newIndent ) + ' ' + title ) ;
330+
331+ if ( delta > 0 ) indents . push ( originalIndent ) ;
332+ if ( delta < 0 ) {
333+ let d = Math . abs ( delta ) ;
334+ while ( d > 0 ) {
335+ indents . pop ( ) ;
336+ d -- ;
337+ }
338+ }
339+ lastIndent = indent ;
340+ }
341+
342+ // wrap section text in <section>...</section> tags for respec
379343 if ( ! inCodeBlock && argv . respec && line . startsWith ( '#' ) ) {
380344 let heading = 0 ;
381345 while ( line [ heading ] === '#' ) heading ++ ;
@@ -384,16 +348,23 @@ for (let l in lines) {
384348 if ( delta > 0 ) delta = 1 ;
385349 let prefix = '' ;
386350 let newSection = '<section>' ;
387- if ( line . includes ( '## Version ' ) ) {
351+ const m = line . match ( / # V e r s i o n ( [ 0 - 9 . ] + ) $ / ) ;
352+ if ( m ) {
388353 // our conformance section is headlined with 'Version x.y.z'
354+ // and respec needs a conformance section in a "formal" specification
389355 newSection = '<section class="override" id="conformance">' ;
356+ // adjust the heading to be at level 2 because respec insists on h2 here
357+ // Note: older specs had this at h4, newer specs at h2, and all heading levels have been reduced by 1 in the preceding block
358+ line = '#' + m [ 0 ] ;
359+ delta = 1 ;
360+ heading = 2 ;
390361 }
391362 if ( line . includes ( 'Appendix' ) ) {
392363 newSection = '<section class="appendix">' ;
393364 }
394365
395366 // 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 */
367+ // respec insists on <section>...</section> breaks around headings
397368
398369 if ( delta === 0 ) {
399370 prefix = '</section>' + newSection ;
0 commit comments