diff --git a/PUBLISHING.md b/PUBLISHING.md new file mode 100644 index 00000000..b6ec6c6e --- /dev/null +++ b/PUBLISHING.md @@ -0,0 +1,28 @@ +# Generating a PDF from ecmarkup + +In order to produce a PDF, the front matter `title`, `shortname`, `version`, and `date` are **mandatory**. If generating a final annual edition, date should reflect the date of the Ecma GA which will ratify the Standard. For example: + +``` +title: ECMAScript® 2024 Language Specification +shortname: ECMA-262 +version: 15th Edition +date: 2024-06-25 +``` + +To generate markup for use in PDF conversion, make sure to include the options `--assets`, `--assets-dir`, and `--printable`. If you have images and styles to include, make sure to move them into your assets directory before running `ecmarkup`. For example: + +```shell +mkdir -p out && +mv images out && +mv print.css out && +ecmarkup --assets external --assets-dir out --printable spec.html out/index.html +``` + +Then, from your spec's working directory, run [`prince`](https://www.princexml.com/) to generate your PDF. + +```shell +cd path/to/spec +prince --script ./node_modules/ecmarkup/js/print.js out/index.html -o path/to/output.pdf +``` + +This has been extensively tested with Prince 15. Earlier and later editions not guaranteed. \ No newline at end of file diff --git a/css/elements.css b/css/elements.css index 94347e74..7987be55 100644 --- a/css/elements.css +++ b/css/elements.css @@ -100,7 +100,7 @@ body { font-size: 18px; line-height: 1.5; font-family: - IBM Plex Serif, + 'IBM Plex Serif', serif; font-variant-numeric: slashed-zero; padding: 0; @@ -119,6 +119,8 @@ body { padding-bottom: 1em; } +h1.shortname { display: none; } + body.oldtoc { margin: 0 auto; } @@ -159,7 +161,7 @@ span.e-user-code::before { vertical-align: middle; text-transform: uppercase; font-family: - IBM Plex Sans, + 'IBM Plex Sans', sans-serif; font-weight: 900; font-size: x-small; @@ -184,8 +186,8 @@ span.e-user-code::before { code { font-weight: bold; font-family: - Comic Code, - IBM Plex Mono, + 'Comic Code', + 'IBM Plex Mono', monospace; white-space: pre; } @@ -256,7 +258,7 @@ var.referenced6 { emu-const { font-family: - IBM Plex Sans, + 'IBM Plex Sans', sans-serif; font-variant: small-caps; text-transform: uppercase; @@ -458,7 +460,7 @@ emu-rhs emu-nt { emu-t { display: inline-block; font-family: - IBM Plex Mono, + 'IBM Plex Mono', monospace; font-weight: bold; white-space: nowrap; @@ -495,7 +497,7 @@ emu-params, emu-opt { margin-right: 1ex; font-family: - IBM Plex Mono, + 'IBM Plex Mono', monospace; } @@ -511,7 +513,7 @@ emu-opt { emu-gprose { font-size: 0.9em; font-family: - IBM Plex Sans, + 'IBM Plex Sans', sans-serif; } @@ -780,6 +782,10 @@ emu-table td { background: #fff; } +td[colspan]:not([colspan="1"]), th[colspan]:not([colspan="1"]) { + text-align: center; +} + /* Note: the left content edges of table.lightweight-table >tbody >tr >td and div.display line up. */ table.lightweight-table { @@ -925,7 +931,7 @@ tr.del > td { height: 18px; font-size: 12px; margin: 0 5px 0 10px; - font-family: IBM Plex Sans; + font-family: 'IBM Plex Sans', sans-serif; } #menu-pins .unpin-all:hover { background: #ddd; @@ -950,7 +956,7 @@ tr.del > td { align-self: center; } -#menu-pins-list > li:before, +#menu-pins-list > li::before, #menu-pins-list > li > .unpin { flex-shrink: 0; flex-grow: 0; @@ -960,7 +966,7 @@ tr.del > td { background: none; border: none; } -#menu-pins-list > li:before, +#menu-pins-list > li::before, #menu-pins-list > li > .unpin:hover { background: #ccc; } @@ -974,7 +980,7 @@ tr.del > td { color: #bb1212; } -#menu-pins-list > li:before { +#menu-pins-list > li::before { content: counter(pins-counter); counter-increment: pins-counter; font-size: 16px; @@ -1152,7 +1158,7 @@ a.menu-pane-header-production { overflow-y: auto; } -li.menu-search-result-clause:before { +li.menu-search-result-clause::before { content: 'clause'; width: 40px; display: inline-block; @@ -1161,7 +1167,7 @@ li.menu-search-result-clause:before { color: #666; font-size: 75%; } -li.menu-search-result-op:before { +li.menu-search-result-op::before { content: 'op'; width: 40px; display: inline-block; @@ -1171,7 +1177,7 @@ li.menu-search-result-op:before { font-size: 75%; } -li.menu-search-result-prod:before { +li.menu-search-result-prod::before { content: 'prod'; width: 40px; display: inline-block; @@ -1181,7 +1187,7 @@ li.menu-search-result-prod:before { font-size: 75%; } -li.menu-search-result-term:before { +li.menu-search-result-term::before { content: 'term'; width: 40px; display: inline-block; @@ -1211,10 +1217,10 @@ li.menu-search-result-term:before { white-space: nowrap; } -#menu-trace-list li .secnum:after { +#menu-trace-list li .secnum::after { content: ' '; } -#menu-trace-list li:before { +#menu-trace-list li::before { content: counter(item) ' '; background-color: #222; counter-increment: item; @@ -1301,8 +1307,8 @@ li.menu-search-result-term:before { text-decoration: underline; } -.toolbox:after, -.toolbox:before { +.toolbox::after, +.toolbox::before { top: 100%; left: 15px; border: solid transparent; @@ -1313,13 +1319,13 @@ li.menu-search-result-term:before { pointer-events: none; } -.toolbox:after { +.toolbox::after { border-color: rgba(0, 0, 0, 0); border-top-color: #ddd; border-width: 10px; margin-left: -10px; } -.toolbox:before { +.toolbox::before { border-color: rgba(204, 204, 204, 0); border-top-color: #aaa; border-width: 12px; @@ -1358,7 +1364,7 @@ li.menu-search-result-term:before { display: flex; } -#references-pane-close:after { +#references-pane-close::after { content: '\2716'; float: right; cursor: pointer; @@ -1373,10 +1379,18 @@ li.menu-search-result-term:before { padding-right: 5px; } +emu-normative-optional::before { + display: block; + color: #884400; + content: "NORMATIVE OPTIONAL"; +} + +emu-normative-optional, [normative-optional], [deprecated], [legacy] { border-left: 5px solid #ff6600; + display: block; padding: 0.5em; background: #ffeedd; } @@ -1430,3 +1444,22 @@ li.menu-search-result-term:before { background-color: #eee; box-shadow: inset 0 -1px 0 #ccc; } + +#metadata-block { + margin: 4em 0; + padding: 10px; + border: 1px solid #ee8421; +} + +#metadata-block h1 { + font-size: 1.5em; + margin-top: 0; +} +#metadata-block > ul { + list-style-type: none; + margin: 0; padding: 0; +} + +#ecma-logo { + width: 500px; +} diff --git a/css/print.css b/css/print.css index 7f3b1238..7c772636 100644 --- a/css/print.css +++ b/css/print.css @@ -1,12 +1,213 @@ +@font-face { + font-family: "Arial Plus"; + src: local("Arial"); +} + +@font-face { + font-family: "Arial Plus"; + unicode-range: U+30; + font-style: normal; + font-weight: 400; + src: local(IBM Plex Mono Regular), local(IBMPlexMono-Regular); +} + +@font-face { + font-family: "Arial Plus"; + unicode-range: U+221e; + font-style: normal; + font-weight: 400; + src: local("DejaVu Math TeX Gyre"); +} + +@font-face { + font-family: "Arial Plus"; + unicode-range: U+30; + font-style: normal; + font-weight: 700; + src: local(IBM Plex Mono Bold), local(IBMPlexMono-Bold); +} + +@font-face { + font-family: "Arial Plus"; + unicode-range: U+221e; + font-style: normal; + font-weight: 700; + src: local("DejaVu Math TeX Gyre"); +} + +@font-face { + font-family: "Arial Plus"; + unicode-range: U+30; + font-style: italic; + font-weight: 400; + src: local(IBM Plex Mono Italic), local(IBMPlexMono-Italic); +} + +@font-face { + font-family: "Arial Plus"; + unicode-range: U+221e; + font-style: italic; + font-weight: 400; + src: local("DejaVu Math TeX Gyre"); +} + +@font-face { + font-family: "Arial Plus"; + unicode-range: U+30; + font-style: italic; + font-weight: 700; + src: local(IBM Plex Mono Bold Italic), local(IBMPlexMono-BoldItalic); +} + +@font-face { + font-family: "Arial Plus"; + unicode-range: U+221e; + font-style: italic; + font-weight: 700; + src: local("DejaVu Math TeX Gyre"); +} + +:root { + --page-number-style: decimal; +} + +@page { + size: A4; + margin-top: 28mm; + margin-bottom: 20mm; + margin-inside: 19mm; + margin-outside: 13mm; + -prince-page-fill: prefer-fill; + + /* Uncomment when producing WIP versions of final standards */ + /* + @prince-overlay { + color: rgba(0,0,0,0.15); + content: "WORK IN PROGRESS"; + font-family: Arial; + font-weight: bolder; + font-size: 100pt; + transform: rotate(-60deg); + } + */ + + @bottom-left { + font-family: Arial; + } + + @bottom-right { + font-family: Arial; + } +} + +@page :verso { + @top-left { + content: url('../img/ecma-header.svg'); + padding-top: 5mm; + } + + @bottom-left { + content: counter(page, var(--page-number-style)); + font-size: 10pt; + } + + @bottom-right { + content: '© Ecma International ' string(year, first); + font-size: 8pt; + } +} + +@page :recto { + @top-right { + content: url('../img/ecma-header.svg'); + padding-top: 5mm; + } + + @bottom-left { + content: '© Ecma International ' string(year, first); + font-size: 8pt; + } + + @bottom-right { + content: counter(page, var(--page-number-style)); + font-size: 10pt; + } +} + +@page :first, :nth(2) { + margin: 0; + + @top-left { + content: none; + } + + @top-right { + content: none; + } + + @bottom-left { + content: none; + } + + @bottom-right { + content: none; + } +} + +@page toc, copyright, intro { + --page-number-style: lower-roman; +} + +@page :blank { + @bottom-left { + content: none; + } + + @bottom-right { + content: none; + } +} + +@page front-cover { + background-image: url('../img/print-front-cover.svg'); +} + +@page inside-cover { + background-image: url('../img/print-inside-cover.svg'); +} + +@page front-cover, inside-cover { + background-color: transparent; + background-position: center; + background-repeat: no-repeat; + margin: 0; + padding: 0; + page-break-after: always; +} + +html, body { + background-color: initial; +} + body { - font-family: Arial, Helvetica, sans-serif; + font-family: 'Arial Plus', Arial, Helvetica, sans-serif, "DejaVu Math TeX Gyre", Symbola, monospace; font-size: 10pt; - background: #fff; color: #000; + line-height: 1.15; } -.title { +h1, h2, h3, h4, h5, h6 { -prince-bookmark-level: none } + +.copyright-notice + h1.title { + break-before: recto; + color: black; + counter-reset: page 1; + display: block; + font-size: 15pt; font-family: Verdana; + font-weight: bold; + margin-bottom: 2.5ex; + margin-top: initial; } p { @@ -24,6 +225,62 @@ h1 { line-height: 1.4; } +emu-alg { + display: block; /* Can't render block elements inside inline elements. */ +} + +emu-alg li { + orphans: 2; + widows: 2; +} + +emu-note, +emu-note p, +emu-table tr, +emu-table th, +emu-table td, +pre, +h1, +emu-production, +emu-figure:has(> figure > img) figure, +#metadata-block { + break-inside: avoid; + border: unset; +} + +p:has(+ .math-display), +emu-table thead, +h1, +figcaption, +emu-alg > ol > li:first-child, +emu-grammar:has(+ emu-alg), +figcaption:has(+ emu-table) { + break-after: avoid-page; +} + +emu-alg ol li:last-child { + break-before: avoid; + break-after: initial; /* it's okay to break after the last item in a list, even if it's also the first item in the list */ +} + +emu-normative-optional emu-clause[id] { + margin-top: 0; +} + +emu-normative-optional emu-alg > ol { + margin-bottom: 0; +} + +emu-note { + gap: initial; + justify-content: space-between; +} + +emu-note .note { + font-size: 9pt; + min-width: 4.5em; +} + emu-note p, emu-table td p { text-align: left; @@ -31,23 +288,206 @@ emu-table td p { overflow: hidden; } +emu-nt, emu-t { + display: initial; +} + +emu-production.inline { + text-align: left; +} + +emu-production.inline emu-nt { + display: inline; +} + +emu-intro { + page: intro; +} + +emu-intro, emu-clause, emu-annex { + margin-top: 4ex; +} + +emu-clause p:first-of-type { + margin-bottom: 0; + orphans: 3; +} + +emu-clause > p:first-of-type { + break-after: avoid-page; +} + +emu-clause p:last-child { + break-after: auto; + margin-bottom: 0; +} + +emu-clause > p:only-of-type { + break-after: auto; +} + +emu-clause > p:first-of-type + emu-alg { + break-before: avoid; +} + +emu-intro emu-intro, emu-clause emu-clause, emu-annex emu-annex { + margin-top: 3.5ex; +} + +emu-intro emu-intro emu-intro, +emu-clause emu-clause emu-clause, +emu-annex emu-annex emu-annex, +emu-intro emu-intro emu-intro emu-intro, +emu-clause emu-clause emu-clause emu-clause, +emu-annex emu-annex emu-annex emu-annex, +emu-intro emu-intro emu-intro emu-intro emu-intro, +emu-clause emu-clause emu-clause emu-clause emu-clause, +emu-annex emu-annex emu-annex emu-annex emu-annex { + margin-top: 3.2ex; +} + +emu-intro h1, emu-clause h1 , emu-annex h1 { + break-after: avoid; + font-size: 12pt; + -prince-bookmark-level: 1; + -prince-bookmark-label: content(); +} + +emu-clause emu-clause h1, emu-annex emu-annex h1 { + -prince-bookmark-level: 2; + -prince-bookmark-state: closed; +} + +emu-clause emu-clause h1, emu-annex emu-annex h1, +emu-intro h2, emu-clause h2, emu-annex h2 { + font-size: 11pt; +} + +emu-clause emu-clause emu-clause h1, emu-annex emu-annex emu-annex h1 { + -prince-bookmark-level: 3; +} + +emu-clause emu-clause emu-clause emu-clause h1, emu-annex emu-annex emu-annex emu-annex h1 { + -prince-bookmark-level: 4; +} + +emu-clause emu-clause emu-clause emu-clause emu-clause h1, emu-annex emu-annex emu-annex emu-annex emu-annex h1 { + -prince-bookmark-level: 5; +} + +emu-clause emu-clause emu-clause emu-clause emu-clause emu-clause h1, emu-annex emu-annex emu-annex emu-annex emu-annex emu-annex h1 { + -prince-bookmark-level: 6; +} + +emu-clause emu-clause emu-clause h1, emu-annex emu-annex emu-annex h1, +emu-clause emu-clause h2, emu-annex emu-annex h2, +emu-clause emu-clause emu-clause emu-clause h1, emu-annex emu-annex emu-annex emu-annex h1, +emu-clause emu-clause emu-clause h2, emu-annex emu-annex emu-annex h2, +emu-clause emu-clause emu-clause emu-clause emu-clause h1, emu-annex emu-annex emu-annex emu-annex emu-annex h1, +emu-clause emu-clause emu-clause emu-clause h2, emu-annex emu-annex emu-annex emu-annex h2, +emu-clause emu-clause emu-clause emu-clause emu-clause emu-clause h1, emu-annex emu-annex emu-annex emu-annex emu-annex emu-annex h1, +emu-clause emu-clause emu-clause emu-clause emu-clause h2, emu-annex emu-annex emu-annex emu-annex emu-annex h2 { + font-size: 10pt; +} + +emu-clause ol, emu-clause ul, emu-clause dl, emu-annex ol, emu-annex ul, emu-annex dl { + margin-left: 0; + padding-left: 1.75em; +} + +emu-clause ol ol, emu-clause ul ul { + padding-left: 2em; +} + +emu-grammar { + display: block; +} + +emu-grammar:has(emu-production.inline) { + display: inline-block; +} + +h1 + emu-grammar { + margin-top: 1ex; +} + +p + emu-grammar { + break-before: avoid; +} + emu-table td, emu-table th { overflow-wrap: break-word; } -emu-table table { - table-layout: auto; - width: 100%; +caption, table > figcaption { + caption-side: top; + color: #555555; + font-weight: bold; + margin-bottom: 1rem; + text-align: center; +} + +caption { + -prince-caption-page: first; +} + +/* do not break inside of small tables */ +table:not(:has(tr:nth-of-type(5))) { + break-inside: avoid-page; +} + +table > figcaption { + display: table-caption; + -prince-caption-page: following; +} + +table > figcaption::after { + content: ' (continued)'; + font-style: italic; + font-weight: normal; +} + +th[rowspan] { + vertical-align: bottom; +} + +td[rowspan] { + vertical-align: middle; +} + +emu-table thead { + display: table-header-group; +} + +emu-table tfoot { + display: table-footer-group; } emu-figure img { + margin-top: 1ex; max-width: 100%; height: auto; } #spec-container { - max-width: none; + max-width: initial; +} + +#spec-container > emu-annex { + margin-top: 0; +} + +#toc > h2 { + -prince-bookmark-level: 1; + -prince-bookmark-label: content(); +} + +#toc > h2::after { + content: 'page'; + float: right; + font-size: 10pt; + text-align: right; } #toc a, @@ -55,27 +495,31 @@ emu-figure img { color: #000; } -#toc a[href] { - background: #fff; - padding-right: 0.5em; -} #toc a[href]::after { - content: /* leader(dotted) */ target-counter(attr(href), page); - float: right; - padding-left: 0.5em; - background: #fff; + content: leader(dotted) target-counter(attr(href), page); } -/* NOTE: hacks because Paged.js doesn't support leader() in content directives */ -#toc ol { - overflow-x: hidden; + +#toc > ol.toc { + margin-top: 0; } -#toc ol li:before { - float: left; - width: 0; - white-space: nowrap; - content: '. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ' - '. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ' - '. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .'; + +ol.toc { + font-weight: bold; + margin-left: 0; + padding-left: 0; +} + +ol.toc ol.toc { + padding-left: 0; +} + +ol.toc li { + text-indent: 35pt hanging; +} + +ol.toc .secnum { + display: inline-block; + min-width: 3.25em; } /* skip the Introduction since it's before the first emu-clause (and therefore doesn't have a proper page number) */ @@ -84,119 +528,123 @@ emu-figure img { } #toc > ol > li { - margin-top: 1ex; + margin-top: 0.75ex; } #toc, #spec-container > emu-intro, #spec-container > emu-annex { break-before: recto; - break-after: always; + break-after: page; } -/* according to Ecma guidelines, we're actually not supposed to break before every clause (only the first), but Paged.js fails if we do that */ -/* so instead, just break before any of the clauses that have sub-clauses */ -#spec-container > emu-clause:has(emu-clause:not([example])) { - break-before: always; +a[data-print-href]::after { + content: ' <' attr(href) '>'; + color: initial; } -#spec-container > emu-clause:first-of-type { - break-before: recto; +.real-table { + max-width: 100%; + width: auto; } -emu-note, -emu-note p, -emu-table tr, -emu-table th, -emu-table td, -emu-alg li, -pre, -h1, -#metadata-block { - break-inside: avoid; +.annex-title { + text-align: center; } -emu-table thead, -h1, -figcaption, -emu-alg > ol > li:first-child { - break-after: avoid; +.copyright-notice { /* ecma mandated */ + font-style: italic; + border: 1px solid black; + padding: 1em; + page: copyright; + page-break-before: always; + page-break-after: always; } -emu-grammar + emu-alg, -figcaption + emu-table, -figcaption + span[id] + emu-table, -emu-alg > ol > li:last-child { - break-before: avoid; +.full-page-svg { + color: rgba(255, 255, 255, 0); } -a[data-print-href]::after { - content: ' <' attr(href) '>'; - color: initial; +.secnum { + font-family: Arial, Helvetica, sans-serif; } -emu-table thead { - display: table-header-group; -} -emu-table tfoot { - display: table-footer-group; +#front-cover { + page: front-cover; + position: relative; + width: 210mm; + height: 297mm; } -@page { - size: A4; +#front-cover h1 { + color: black; + display: block; + font-family: Verdana; + position: absolute; } -@page { - @top-center { - content: url(img/ecma-header.png); - } +h1.shortname { + top: 86mm; + font-weight: 400; + font-size: 21pt; + right: 31mm; + text-align: right; + margin-top: 0; } -@page :first { - @top-center { - content: none; - } + +h1.shortname a:link, h1.shortname a:visited, h1.shortname a:hover, h1.shortname a:active { + color: black; } -:root { - --page-number-style: decimal; +h1.shortname .status { + display: inline-block; + margin-right: 7em; + text-transform: capitalize; } -#toc { - page: toc; +h1.version { + font-size: 9.7pt; + font-weight: normal; + margin-top: 0; + text-align: right; + top: 96mm; + left: 139mm; + string-set: year attr(data-year); } -@page toc { - --page-number-style: lower-roman; + +#front-cover h1.title { + font-weight: bold; + font-size: 20pt; + line-height: 1.2; + top: 109mm; + right: 15mm; + width: 95mm; + text-align: left; } -emu-intro { - page: intro; + +#inside-cover { + page: inside-cover; } -@page intro { - --page-number-style: lower-roman; + +#inside-cover address { + color: black; + font-size: 12pt; + font-style: normal; + position: relative; + left: 72mm; + top: 82mm; } #toc { - counter-reset: page 1; -} -#spec-container > emu-clause:first-of-type { + page: toc; counter-reset: page 1; } -@page :left { - @bottom-left { - content: counter(page, var(--page-number-style)); - } -} -@page :right { - @bottom-right { - content: counter(page, var(--page-number-style)); - } +#toc h2 { + font-size: 12pt; + margin-bottom: 1.5ex; } -@page :first { - @bottom-left { - content: ''; - } - @bottom-right { - content: ''; - } +.annex-kind { + font-weight: normal; } diff --git a/img/ecma-header.svg b/img/ecma-header.svg new file mode 100644 index 00000000..5eaffa9d --- /dev/null +++ b/img/ecma-header.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/img/print-front-cover.svg b/img/print-front-cover.svg new file mode 100644 index 00000000..aa0ae357 --- /dev/null +++ b/img/print-front-cover.svg @@ -0,0 +1,10 @@ + + + diff --git a/img/print-inside-cover.svg b/img/print-inside-cover.svg new file mode 100644 index 00000000..c0f6f02d --- /dev/null +++ b/img/print-inside-cover.svg @@ -0,0 +1,59 @@ + + + diff --git a/js/print.js b/js/print.js new file mode 100644 index 00000000..237ddbcb --- /dev/null +++ b/js/print.js @@ -0,0 +1,75 @@ +/** + * Some notes: + * - Prince cant grok trailing commas, so prettier is disabled anywhere it tries to enforce wrapping with trailing comma + * - Prince doesn't support template strings yet + * - Set Prince.trackboxes to true for advanced debugging, see https://www.princexml.com/doc/cookbook/#how-and-where-is-my-box + * */ + +/* eslint-disable no-undef */ +'use strict'; + +// Prince.trackBoxes = true; + +const specContainer = document.getElementById('spec-container'); +const shortname = specContainer.querySelector('h1.shortname'); +const version = specContainer.querySelector('h1.version'); + +rearrangeTables(); + +PDF.pageLayout = 'two-column-right'; +PDF.pageMode = 'show-bookmarks'; +PDF.duplex = 'duplex-flip-long-edge'; +PDF.title = document.title; +PDF.author = 'Ecma International'; +PDF.subject = shortname.innerHTML + ', ' + version.innerHTML; + +/** + * Sets up table captions and figcaptions for tables, which provides for + * continuation table captions. + * */ +function rearrangeTables() { + const tables = Array.from(document.getElementsByTagName('emu-table')); + + tables.forEach(emuTable => { + const figcaption = emuTable.getElementsByTagName('figcaption')[0]; + const tableCaptionText = figcaption.innerHTML; + const table = emuTable.getElementsByTagName('table')[0]; + const captionElement = document.createElement('caption'); + + captionElement.innerHTML = tableCaptionText; + + table.insertBefore(captionElement, table.getElementsByTagName('thead')[0]); + table.appendChild(figcaption); + }); +} + +/** + * @typedef {Object} PrinceBox + * @property {string} type + * @property {number} pageNum + * @property {number} x + * @property {number} y + * @property {number} w + * @property {number} h + * @property {number} baseline + * @property {number} marginTop + * @property {number} marginBottom + * @property {number} marginLeft + * @property {number} marginRight + * @property {number} paddingTop + * @property {number} paddingBottom + * @property {number} paddingLeft + * @property {number} paddingRight + * @property {number} borderTop + * @property {number} borderBottom + * @property {number} borderLeft + * @property {number} borderRight + * @property {string} floatPosition "TOP" or "BOTTOM" + * @property {PrinceBox[]} children + * @property {PrinceBox} parent + * @property {Element|null} element + * @property {string|null} pseudo + * @property {string} text + * @property {string} src + * @property {CSSStyleSheet} style + * */ diff --git a/spec/index.html b/spec/index.html index a1b8e995..b140bb32 100644 --- a/spec/index.html +++ b/spec/index.html @@ -75,7 +75,7 @@
normative: If present, annex is normative. Default is non-normative.
+back-matter: If present, annex is back matter (such as a colophon), which means it will not be assigned an annex letter and will appear without one in the table of contents and document. This attribute should only be used with non-normative annexes, and back matter annexes should not be followed by non-back-matter annexes.
id: Clause id. Must be unique.
aoid: Abstract operation ID. A unique name identifying this clause as an abstract operation. Algorithm steps will auto-link calls to this abstract operation to this clause. If left blank, the aoid will be set to the id of this clause.
diff --git a/src/Clause.ts b/src/Clause.ts index a7794f35..526c3342 100644 --- a/src/Clause.ts +++ b/src/Clause.ts @@ -56,6 +56,9 @@ export default class Clause extends Builder { /** @internal */ signature: Signature | null; /** @internal */ skipGlobalChecks: boolean; /** @internal */ skipReturnChecks: boolean; + isAnnex: boolean; + isBackMatter: boolean; + isNormative: boolean; constructor(spec: Spec, node: HTMLElement, parent: Clause, number: string) { super(spec, node); @@ -69,6 +72,9 @@ export default class Clause extends Builder { this.effects = []; this.skipGlobalChecks = false; this.skipReturnChecks = false; + this.isAnnex = node.nodeName === 'EMU-ANNEX'; + this.isBackMatter = this.isAnnex && node.hasAttribute('back-matter'); + this.isNormative = !this.isAnnex || node.hasAttribute('normative'); // namespace is either the entire spec or the parent clause's namespace. let parentNamespace = spec.namespace; @@ -402,6 +408,20 @@ export default class Clause extends Builder { clauseStack.pop(); } + getSecnumHTML() { + if (!this.number || this.isBackMatter) return ''; + if (this.isAnnex) { + const isInnerAnnex = this.node.parentElement?.nodeName === 'EMU-ANNEX'; + if (isInnerAnnex) { + return `${this.number} `; + } else { + return `Annex ${this.number} (${this.isNormative ? 'normative' : 'informative'}) `; + } + } else { + return `${this.number} `; + } + } + static elements = ['EMU-INTRO', 'EMU-CLAUSE', 'EMU-ANNEX']; static linkElements = Clause.elements; } diff --git a/src/H1.ts b/src/H1.ts index a47459d1..8117bdcb 100644 --- a/src/H1.ts +++ b/src/H1.ts @@ -20,11 +20,19 @@ export default class H1 extends Builder { parent.titleHTML = headerClone.innerHTML; parent.title = headerClone.textContent; if (parent.number) { - const numElem = spec.doc.createElement('span'); - numElem.setAttribute('class', 'secnum'); - numElem.textContent = parent.number; - node.insertBefore(spec.doc.createTextNode(' '), node.firstChild); - node.insertBefore(numElem, node.firstChild); + // we want to prepend some HTML but setting `innerHTML` on the node will blow away the existing children, + // which messes up other stuff which expects those to keep their identity + node.insertAdjacentHTML('afterbegin', parent.getSecnumHTML()); + + // const frag = spec.doc.createElement('div'); + // frag.innerHTML = parent.getSecnumHTML() + node.innerHTML; + // node.prepend(...frag.children); + // node.innerHTML = ; + // const numElem = spec.doc.createElement('span'); + // numElem.setAttribute('class', 'secnum'); + // numElem.textContent = parent.number; + // node.insertBefore(spec.doc.createTextNode(' '), node.firstChild); + // node.insertBefore(numElem, node.firstChild); } } } diff --git a/src/Spec.ts b/src/Spec.ts index 5b1f035a..18c92f6d 100644 --- a/src/Spec.ts +++ b/src/Spec.ts @@ -90,7 +90,7 @@ const FONT_FILES = new Map([ ['IBMPlexMono-BoldItalic', 'IBMPlexMono-BoldItalic-SlashedZero.woff2'], ]); -const IMG_FILES = new Set(['ecma-header.png']); +const IMG_FILES = new Set(['ecma-header.svg', 'print-front-cover.svg', 'print-inside-cover.svg']); interface VisitorMap { [k: string]: BuilderInterface; @@ -390,6 +390,12 @@ export default class Spec { throw new Error('--js-out and --css-out have been removed; use --assets-dir instead'); } + if (this.opts.oldToc) { + throw new Error( + '--old-toc has been removed; specify --printable to get a printable document', + ); + } + if ( this.opts.assets != null && this.opts.assets !== 'external' && @@ -398,6 +404,15 @@ export default class Spec { throw new Error(`--assets=${this.opts.assets} cannot be used --assets-dir"`); } + if (this.opts.printable) { + if (this.opts.title == null) { + throw new Error(`--printable requires a title to be set in the metadata"`); + } + if (this.opts.shortname == null) { + throw new Error(`--printable requires a shortname to be set in the metadata"`); + } + } + if (this.opts.multipage) { this.opts.outfile ??= ''; const type = this.opts.assets ?? 'external'; @@ -533,8 +548,10 @@ export default class Spec { this.log('Propagating effect annotations...'); this.propagateEffects(); - this.log('Annotating external links...'); - this.annotateExternalLinks(); + if (this.opts.printable) { + this.log('Annotating external links...'); + this.annotateExternalLinks(); + } this.log('Linking xrefs...'); this._xrefs.forEach(xref => xref.build()); this.log('Linking non-terminal references...'); @@ -574,20 +591,69 @@ export default class Spec { this.setCharset(); const wrapper = this.buildSpecWrapper(); + if (this.opts.printable) { + this.log('Building covers and applying other print tweaks...'); + const metadataEle = this.doc.querySelector('#metadata-block'); + if (metadataEle) { + this.doc.querySelector('emu-intro')!.appendChild(metadataEle); + } + const scopeEle = document.getElementById('scope') ?? document.getElementById('sec-scope'); + if (!scopeEle) { + throw new Error('--printable requires a scope'); + } + scopeEle.before(this.doc.querySelector('h1.title')!.cloneNode(true)); + + // front cover + const frontCover = document.createElement('div'); + + frontCover.classList.add('full-page-svg'); + frontCover.setAttribute('id', 'front-cover'); + + const shortNameNode = this.doc.querySelector('h1.shortname'); + if (shortNameNode != null) { + frontCover.appendChild(shortNameNode.cloneNode(true)); + } + const versionNode = this.doc.querySelector('h1.version'); + if (versionNode != null) { + frontCover.appendChild(versionNode.cloneNode(true)); + } + // we know title exists because we enforce it in the constructor when using --printable + frontCover.appendChild(this.doc.querySelector('title')!.cloneNode(true)); + wrapper.before(frontCover); + + // inside cover + const insideCover = document.createElement('div'); + + insideCover.classList.add('full-page-svg'); + insideCover.setAttribute('id', 'inside-cover'); + insideCover.innerHTML = 'Ecma International
Rue du Rhone 114 CH-1204 Geneva
Tel: +41 22 849 6000
Fax: +41 22 849 6001
Web: https://www.ecma-international.org
Ecma is the registered trademark of Ecma International.
m {
+ if (last) return false;
+ if (node.nodeName === 'EMU-CLAUSE' || node.nodeName === 'EMU-ANNEX') {
+ last = node as HTMLElement;
+ return false;
+ }
+ });
+
+ if (last && last.parentNode) {
+ last.parentNode.insertBefore(copyrightClause, last.nextSibling);
+ } else {
+ this.doc.body.appendChild(copyrightClause);
+ }
+ }
}
}
@@ -1395,7 +1459,7 @@ ${this.opts.multipage ? `Navigate to/from multipagemNavigate to/from multipagemNavigate to/from multipagem${shortname}` : shortname;
const shortnameHtml =
- status.charAt(0).toUpperCase() + status.slice(1) + ' ' + shortnameLinkHtml;
+ (this.opts.printable && status === 'standard'
+ ? ''
+ : `${status.charAt(0).toUpperCase() + status.slice(1)} `) +
+ shortnameLinkHtml;
if (!this._updateBySelector('h1.shortname', shortnameHtml)) {
const h1 = this.doc.createElement('h1');
@@ -1466,7 +1541,9 @@ ${this.opts.multipage ? `Navigate to/from multipagem n.getAttribute('property') === 'og:title')) {
- const title = this.opts.title ?? this.doc.querySelector('title')?.textContent;
+ const title = this.opts.title
+ ? utils.textContentFromHTML(this.doc, this.opts.title)
+ : this.doc.querySelector('title')?.textContent;
if (title) {
const meta = this.doc.createElement('meta');
meta.setAttribute('property', 'og:title');
@@ -1517,24 +1594,10 @@ ${this.opts.multipage ? `Navigate to/from multipagem {
- if (last) return false;
- if (node.nodeName === 'EMU-CLAUSE' || node.nodeName === 'EMU-ANNEX') {
- last = node as HTMLElement;
- return false;
- }
- });
-
copyrightClause = this.doc.createElement('emu-annex');
copyrightClause.setAttribute('id', 'sec-copyright-and-software-license');
-
- if (last && last.parentNode) {
- last.parentNode.insertBefore(copyrightClause, last.nextSibling);
- } else {
- this.doc.body.appendChild(copyrightClause);
- }
}
+ copyrightClause.setAttribute('back-matter', '');
copyrightClause.innerHTML = `
Copyright & Software License
@@ -1544,6 +1607,8 @@ ${this.opts.multipage ? `Navigate to/from multipagemSoftware License
${license}
`;
+
+ return copyrightClause;
}
private generateSDOMap() {
diff --git a/src/Toc.ts b/src/Toc.ts
index 8eaf1a4a..87535cff 100644
--- a/src/Toc.ts
+++ b/src/Toc.ts
@@ -16,7 +16,7 @@ export default class Toc {
const html = Toc.build(this.spec, { maxDepth });
const tocContainer = this.spec.doc.createElement('div');
tocContainer.setAttribute('id', 'toc');
- tocContainer.innerHTML = 'Table of Contents
' + html;
+ tocContainer.innerHTML = 'Contents
' + html;
const intro = this.spec.doc.querySelector('emu-intro, emu-clause, emu-annex');
if (intro && intro.parentNode) {
intro.parentNode.insertBefore(tocContainer, intro);
@@ -44,11 +44,7 @@ export default class Toc {
}
}
- html += '';
- if (sub.number) {
- html += '' + sub.number + ' ';
- }
- html += shorten(sub.titleHTML) + '';
+ html += `${sub.getSecnumHTML()}${shorten(sub.titleHTML)}`;
if (sub.subclauses.length > 0) html += Toc.build(sub, { maxDepth: maxDepth - 1, expandy });
html += '
';
});
diff --git a/src/args.ts b/src/args.ts
index c92fb5ab..f7aa0277 100644
--- a/src/args.ts
+++ b/src/args.ts
@@ -45,9 +45,9 @@ export const options = [
description: "Don't include the table of contents",
},
{
- name: 'old-toc',
+ name: 'printable',
type: Boolean,
- description: 'Use the old table of contents styling',
+ description: 'Make the output suitable for printing',
},
{
name: 'mark-effects',
@@ -104,4 +104,8 @@ export const options = [
name: 'js-out',
type: String,
},
+ {
+ name: 'old-toc',
+ type: Boolean,
+ },
] as const;
diff --git a/src/cli.ts b/src/cli.ts
index e33f3506..328bc183 100644
--- a/src/cli.ts
+++ b/src/cli.ts
@@ -24,7 +24,7 @@ function usage() {
},
{
header: 'Options',
- hide: ['files', 'js-out', 'css-out'],
+ hide: ['files', 'js-out', 'css-out', 'old-toc'],
optionList: options as unknown as commandLineUsage.OptionDefinition[],
},
]),
@@ -64,6 +64,10 @@ if (args.strict && args.watch) {
fail('Cannot use --strict with --watch');
}
+if (args['old-toc']) {
+ fail('--old-toc has been removed; specify --printable to get a printable document');
+}
+
if (args['js-out'] || args['css-out']) {
fail('--js-out and --css-out have been removed; specify --assets-dir instead');
}
@@ -112,8 +116,8 @@ const build = debounce(async function build() {
if (args['no-toc'] != null) {
opts.toc = !args['no-toc'];
}
- if (args['old-toc'] != null) {
- opts.oldToc = args['old-toc'];
+ if (args.printable != null) {
+ opts.printable = args.printable;
}
if (args.assets != null) {
diff --git a/src/ecmarkup.ts b/src/ecmarkup.ts
index 5ee57920..34aae168 100644
--- a/src/ecmarkup.ts
+++ b/src/ecmarkup.ts
@@ -37,6 +37,7 @@ export interface Options {
contributors?: string;
toc?: boolean;
oldToc?: boolean;
+ printable?: boolean;
markEffects?: boolean;
lintSpec?: boolean;
cssOut?: never;
diff --git a/src/header-parser.ts b/src/header-parser.ts
index 66dadbfd..32197708 100644
--- a/src/header-parser.ts
+++ b/src/header-parser.ts
@@ -688,7 +688,7 @@ export function formatPreamble(
? 'It is defined piecewise over the following productions:'
: 'It performs the following steps when called:';
const getRelevantElement = (el: Element): Element =>
- el.tagName === 'INS' || el.tagName === 'DEL' ? el.firstElementChild ?? el : el;
+ el.tagName === 'INS' || el.tagName === 'DEL' ? (el.firstElementChild ?? el) : el;
let next = dl.nextElementSibling;
while (next != null && getRelevantElement(next)?.tagName === 'EMU-NOTE') {
next = next.nextElementSibling;
diff --git a/src/type-logic.ts b/src/type-logic.ts
index cd96d7bc..f86ad3e6 100644
--- a/src/type-logic.ts
+++ b/src/type-logic.ts
@@ -376,7 +376,9 @@ export function typeFromExpr(
// however we mostly use `never` to mean user error, so use unknown instead
// this should only ever happen after `Return`
{ kind: 'unknown' }
- : callType.of.find(k => k.kind === 'normal completion')?.of ?? { kind: 'unknown' };
+ : (callType.of.find(k => k.kind === 'normal completion')?.of ?? {
+ kind: 'unknown',
+ });
return normal;
}
}
diff --git a/src/utils.ts b/src/utils.ts
index 72d23330..9902b4d5 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -82,6 +82,13 @@ export function htmlToDom(html: string) {
return new jsdom.JSDOM(html, { includeNodeLocations: true, virtualConsole });
}
+/** @internal */
+export function textContentFromHTML(doc: Document, html: string) {
+ const ele = doc.createElement('span');
+ ele.innerHTML = html;
+ return ele.textContent!;
+}
+
/** @internal */
export function domWalkBackward(root: Node, cb: (node: Element) => boolean | undefined) {
const childNodes = root.childNodes;
diff --git a/test/baselines/generated-reference/assets-inline.html b/test/baselines/generated-reference/assets-inline.html
index 4f72c8ee..9e8897af 100644
--- a/test/baselines/generated-reference/assets-inline.html
+++ b/test/baselines/generated-reference/assets-inline.html
@@ -1709,7 +1709,7 @@
font-size: 18px;
line-height: 1.5;
font-family:
- IBM Plex Serif,
+ 'IBM Plex Serif',
serif;
font-variant-numeric: slashed-zero;
padding: 0;
@@ -1728,6 +1728,8 @@
padding-bottom: 1em;
}
+h1.shortname { display: none; }
+
body.oldtoc {
margin: 0 auto;
}
@@ -1768,7 +1770,7 @@
vertical-align: middle;
text-transform: uppercase;
font-family:
- IBM Plex Sans,
+ 'IBM Plex Sans',
sans-serif;
font-weight: 900;
font-size: x-small;
@@ -1793,8 +1795,8 @@
code {
font-weight: bold;
font-family:
- Comic Code,
- IBM Plex Mono,
+ 'Comic Code',
+ 'IBM Plex Mono',
monospace;
white-space: pre;
}
@@ -1865,7 +1867,7 @@
emu-const {
font-family:
- IBM Plex Sans,
+ 'IBM Plex Sans',
sans-serif;
font-variant: small-caps;
text-transform: uppercase;
@@ -2067,7 +2069,7 @@
emu-t {
display: inline-block;
font-family:
- IBM Plex Mono,
+ 'IBM Plex Mono',
monospace;
font-weight: bold;
white-space: nowrap;
@@ -2104,7 +2106,7 @@
emu-opt {
margin-right: 1ex;
font-family:
- IBM Plex Mono,
+ 'IBM Plex Mono',
monospace;
}
@@ -2120,7 +2122,7 @@
emu-gprose {
font-size: 0.9em;
font-family:
- IBM Plex Sans,
+ 'IBM Plex Sans',
sans-serif;
}
@@ -2389,6 +2391,10 @@
background: #fff;
}
+td[colspan]:not([colspan="1"]), th[colspan]:not([colspan="1"]) {
+ text-align: center;
+}
+
/* Note: the left content edges of table.lightweight-table >tbody >tr >td
and div.display line up. */
table.lightweight-table {
@@ -2534,7 +2540,7 @@
height: 18px;
font-size: 12px;
margin: 0 5px 0 10px;
- font-family: IBM Plex Sans;
+ font-family: 'IBM Plex Sans', sans-serif;
}
#menu-pins .unpin-all:hover {
background: #ddd;
@@ -2559,7 +2565,7 @@
align-self: center;
}
-#menu-pins-list > li:before,
+#menu-pins-list > li::before,
#menu-pins-list > li > .unpin {
flex-shrink: 0;
flex-grow: 0;
@@ -2569,7 +2575,7 @@
background: none;
border: none;
}
-#menu-pins-list > li:before,
+#menu-pins-list > li::before,
#menu-pins-list > li > .unpin:hover {
background: #ccc;
}
@@ -2583,7 +2589,7 @@
color: #bb1212;
}
-#menu-pins-list > li:before {
+#menu-pins-list > li::before {
content: counter(pins-counter);
counter-increment: pins-counter;
font-size: 16px;
@@ -2761,7 +2767,7 @@
overflow-y: auto;
}
-li.menu-search-result-clause:before {
+li.menu-search-result-clause::before {
content: 'clause';
width: 40px;
display: inline-block;
@@ -2770,7 +2776,7 @@
color: #666;
font-size: 75%;
}
-li.menu-search-result-op:before {
+li.menu-search-result-op::before {
content: 'op';
width: 40px;
display: inline-block;
@@ -2780,7 +2786,7 @@
font-size: 75%;
}
-li.menu-search-result-prod:before {
+li.menu-search-result-prod::before {
content: 'prod';
width: 40px;
display: inline-block;
@@ -2790,7 +2796,7 @@
font-size: 75%;
}
-li.menu-search-result-term:before {
+li.menu-search-result-term::before {
content: 'term';
width: 40px;
display: inline-block;
@@ -2820,10 +2826,10 @@
white-space: nowrap;
}
-#menu-trace-list li .secnum:after {
+#menu-trace-list li .secnum::after {
content: ' ';
}
-#menu-trace-list li:before {
+#menu-trace-list li::before {
content: counter(item) ' ';
background-color: #222;
counter-increment: item;
@@ -2910,8 +2916,8 @@
text-decoration: underline;
}
-.toolbox:after,
-.toolbox:before {
+.toolbox::after,
+.toolbox::before {
top: 100%;
left: 15px;
border: solid transparent;
@@ -2922,13 +2928,13 @@
pointer-events: none;
}
-.toolbox:after {
+.toolbox::after {
border-color: rgba(0, 0, 0, 0);
border-top-color: #ddd;
border-width: 10px;
margin-left: -10px;
}
-.toolbox:before {
+.toolbox::before {
border-color: rgba(204, 204, 204, 0);
border-top-color: #aaa;
border-width: 12px;
@@ -2967,7 +2973,7 @@
display: flex;
}
-#references-pane-close:after {
+#references-pane-close::after {
content: '\2716';
float: right;
cursor: pointer;
@@ -2982,10 +2988,18 @@
padding-right: 5px;
}
+emu-normative-optional::before {
+ display: block;
+ color: #884400;
+ content: "NORMATIVE OPTIONAL";
+}
+
+emu-normative-optional,
[normative-optional],
[deprecated],
[legacy] {
border-left: 5px solid #ff6600;
+ display: block;
padding: 0.5em;
background: #ffeedd;
}
@@ -3039,16 +3053,236 @@
background-color: #eee;
box-shadow: inset 0 -1px 0 #ccc;
}
+
+#metadata-block {
+ margin: 4em 0;
+ padding: 10px;
+ border: 1px solid #ee8421;
+}
+
+#metadata-block h1 {
+ font-size: 1.5em;
+ margin-top: 0;
+}
+#metadata-block > ul {
+ list-style-type: none;
+ margin: 0; padding: 0;
+}
+
+#ecma-logo {
+ width: 500px;
+}
+}
- Toggle shortcuts help
?
- Toggle "can call user code" annotations
u
@@ -3283,13 +3734,13 @@
+
Intro
This is a section.
-
- A Copyright & Software License
+
+ Copyright & Software License
Copyright Notice
© 1997 Ecma
diff --git a/test/baselines/generated-reference/boilerplate-address.html b/test/baselines/generated-reference/boilerplate-address.html
index 2c0a250e..30361537 100644
--- a/test/baselines/generated-reference/boilerplate-address.html
+++ b/test/baselines/generated-reference/boilerplate-address.html
@@ -9,8 +9,8 @@
Jump to nth pin1-9
test title!
-
- A Copyright & Software License
+
+ Copyright & Software License
Tet Corporation
2 Hammarskjöld Plaza
New York City, New York
diff --git a/test/baselines/generated-reference/boilerplate-all.html b/test/baselines/generated-reference/boilerplate-all.html
index 8addee3e..95e17f5a 100644
--- a/test/baselines/generated-reference/boilerplate-all.html
+++ b/test/baselines/generated-reference/boilerplate-all.html
@@ -9,8 +9,8 @@
Jump to nth pin1-9
test title!
-
- A Copyright & Software License
+
+ Copyright & Software License
Tet Corporation
2 Hammarskjöld Plaza
New York City, New York
diff --git a/test/baselines/generated-reference/boilerplate-copyright.html b/test/baselines/generated-reference/boilerplate-copyright.html
index c7fe4767..131ae6ac 100644
--- a/test/baselines/generated-reference/boilerplate-copyright.html
+++ b/test/baselines/generated-reference/boilerplate-copyright.html
@@ -9,8 +9,8 @@
Jump to nth pin1-9
test title!
-
- A Copyright & Software License
+
+ Copyright & Software License
Ecma International
Rue du Rhone 114
CH-1204 Geneva
diff --git a/test/baselines/generated-reference/boilerplate-license.html b/test/baselines/generated-reference/boilerplate-license.html
index b47ffb0f..8c09b220 100644
--- a/test/baselines/generated-reference/boilerplate-license.html
+++ b/test/baselines/generated-reference/boilerplate-license.html
@@ -9,8 +9,8 @@
Jump to nth pin1-9
test title!
-
- A Copyright & Software License
+
+ Copyright & Software License
Ecma International
Rue du Rhone 114
CH-1204 Geneva
diff --git a/test/baselines/generated-reference/clauses.html b/test/baselines/generated-reference/clauses.html
index 3cf2fa80..15058e57 100644
--- a/test/baselines/generated-reference/clauses.html
+++ b/test/baselines/generated-reference/clauses.html
@@ -1,14 +1,6 @@
-
-
- - Toggle shortcuts help
?
- - Toggle "can call user code" annotations
u
-
- - Jump to search box
/
- - Toggle pinning of the current clause
p
- - Jump to nth pin
1-9
-
-Table of Contents
+Test Doc Test Doc Ecma International
Rue du Rhone 114 CH-1204 Geneva
Tel: +41 22 849 6000
Fax: +41 22 849 6001
Web: https://www.ecma-international.org
Ecma is the registered trademark of Ecma International.
Test Doc
+Contents
Intro
Sub Intro
@@ -60,7 +52,7 @@ 7.6.2.1 Increasing multi-step explicit numbers
- A Annex
+ Annex A (informative) Annex
A.1 Sub-annex
diff --git a/test/baselines/generated-reference/copyright.html b/test/baselines/generated-reference/copyright.html
index 934ecd7e..9db23f97 100644
--- a/test/baselines/generated-reference/copyright.html
+++ b/test/baselines/generated-reference/copyright.html
@@ -10,8 +10,8 @@
Draft 1 / September 26, 2014
test title!
1 Test Clause
-
- A Copyright & Software License
+
+ Copyright & Software License
Ecma International
Rue du Rhone 114
CH-1204 Geneva
diff --git a/test/baselines/generated-reference/namespaces.html b/test/baselines/generated-reference/namespaces.html
index d55e1256..adc8da41 100644
--- a/test/baselines/generated-reference/namespaces.html
+++ b/test/baselines/generated-reference/namespaces.html
@@ -58,7 +58,7 @@ 1.1.1 SomeAlg
- A Annex
+ Annex A (informative) Annex
Foo ::
bar
@@ -85,7 +85,7 @@ A.2 Annex 1.2
- B Annex 2
+ Annex B (informative) Annex 2
B.1 SomeAlg
diff --git a/test/baselines/generated-reference/proposal-copyright.html b/test/baselines/generated-reference/proposal-copyright.html
index 19a5d0c4..94cf8c08 100644
--- a/test/baselines/generated-reference/proposal-copyright.html
+++ b/test/baselines/generated-reference/proposal-copyright.html
@@ -9,8 +9,8 @@
Jump to nth pin1-9
Stage 0 Draft / September 26, 2014
test title!
-
- A Copyright & Software License
+
+ Copyright & Software License
Copyright Notice
© 2014 Brian Terlson, Ecma International
diff --git a/test/baselines/generated-reference/shortname.html b/test/baselines/generated-reference/shortname.html
index 7e842d50..f5f177c9 100644
--- a/test/baselines/generated-reference/shortname.html
+++ b/test/baselines/generated-reference/shortname.html
@@ -7,7 +7,7 @@
Jump to search box/
Toggle pinning of the current clausep
Jump to nth pin1-9
- Draft ECMA-000
Draft 1 / September 26, 2015
test title!
+Draft ECMA-000
Draft 1 / September 26, 2015
test title!
Some body content
\ No newline at end of file
diff --git a/test/baselines/generated-reference/test.html b/test/baselines/generated-reference/test.html
index 46a8bd42..6672afb7 100644
--- a/test/baselines/generated-reference/test.html
+++ b/test/baselines/generated-reference/test.html
@@ -15,7 +15,7 @@
Draft 1 / September 26, 2015
Ecmarkup Test Document
+ Draft 1 / September 26, 2015
Ecmarkup Test Document
Intro
@@ -161,6 +161,6 @@ 1.3.1 Import 3
- A Annex
+ Annex A (informative) Annex
\ No newline at end of file
diff --git a/test/baselines/sources/clauses.html b/test/baselines/sources/clauses.html
index 96594410..dba843c7 100644
--- a/test/baselines/sources/clauses.html
+++ b/test/baselines/sources/clauses.html
@@ -1,5 +1,7 @@
-oldToc: true
+printable: true
+title: Test Doc
+shortname: Test
copyright: false
assets: none