-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Markup: PDF generation #600
base: main
Are you sure you want to change the base?
Conversation
03215d3
to
0cf9b9a
Compare
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; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😭
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uwu what's this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a whole lot of cascading
See gesa@c6b6b9c#comments for the most important detail of this PR. |
@gesa Have you tested both with and without |
@michaelficarra I have, I’ve generated web versions of ecma402, ecma262 (multipage), and temporal. |
eca8422
to
6f8014b
Compare
@syg , @michaelficarra : following up to get this merged when y’all have a chance |
css/elements.css
Outdated
#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; | ||
} | ||
|
||
.unicode-property-table { | ||
table-layout: fixed; | ||
width: 100%; | ||
font-size: 80%; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we were going to move this into ecma262
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait why? That’s not specific to 262.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unicode-property-table
class only exists on a table in ecma262: https://github.com/tc39/ecma262/blob/815aa8a4d68ce24bec81ba6789c37d55bc87b54a/table-binary-unicode-properties.html#L3. And the metadata-block
div is defined in spec.html
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
metadata-block
does appear in 402. I thought unicode-property-table did too, but I was mistaken. I’ll make that edit.
js/print.js
Outdated
return insideCover; | ||
} | ||
|
||
function generateEcmaCopyrightPage() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we generating another copyright page? Don't we already have one in the document?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The document has the original copyright but not the "alternative copyright”. Would extremely love to be proven wrong on this though, it’s quite possible I’m missing something with copyright minutae.
js/print.js
Outdated
function improveToc() { | ||
const tocContainer = document.getElementById('toc'); | ||
const toc = tocContainer.querySelector('.toc'); | ||
|
||
tocContainer.firstChild.textContent = 'Contents'; | ||
rebuildOl(toc); | ||
} | ||
|
||
/** | ||
* Loops through Table of Contents list items and produces markup optimized for | ||
* a PDF ToC | ||
* */ | ||
function rebuildOl(ol) { | ||
Array.from(ol.querySelectorAll(':scope li')).forEach(li => { | ||
rebuildLi(li); | ||
}); | ||
} | ||
|
||
/** | ||
* Gathers information about a given toc item | ||
* */ | ||
function rebuildLi(li) { | ||
const sublevel = li.querySelector('ol'); | ||
|
||
if (sublevel) { | ||
rebuildOl(sublevel); | ||
} | ||
|
||
const anchor = li.firstChild; | ||
const clauseID = anchor.getAttribute('href').slice(1); | ||
|
||
if (li.querySelector('.secnum') === null) { | ||
return; | ||
} | ||
|
||
const clauseNumber = anchor.firstChild.innerHTML; | ||
const clauseTitle = anchor.getAttribute('title'); | ||
|
||
li.insertBefore(renderTocLink(clauseID, clauseNumber, clauseTitle), anchor); | ||
li.removeChild(anchor); | ||
} | ||
|
||
/** | ||
* Generates link elements for table of contents items | ||
* */ | ||
function renderTocLink(clauseID, clauseNumber, clauseTitle) { | ||
const nonAnnexSections = [ | ||
'sec-copyright-and-software-license', | ||
'sec-colophon', | ||
'sec-bibliography', | ||
]; | ||
const link = document.createElement('a'); | ||
link.setAttribute('href', '#' + clauseID); | ||
link.setAttribute('title', clauseTitle); | ||
|
||
if (nonAnnexSections.includes(clauseID)) { | ||
link.innerHTML = '<span class="secnum">' + clauseTitle + '</span>'; | ||
|
||
return link; | ||
} | ||
|
||
if (/^[A-Z]$/.test(clauseNumber)) { | ||
const annexType = document.getElementById(clauseID).hasAttribute('normative') | ||
? 'normative' | ||
: 'informative'; | ||
link.innerHTML = | ||
'<span class="secnum">Annex ' + | ||
clauseNumber + | ||
' <span class="unbold">(' + | ||
annexType + | ||
')</span></span> ' + | ||
clauseTitle; | ||
|
||
return link; | ||
} | ||
|
||
if (/^[A-Z]\./.test(clauseNumber)) { | ||
link.innerHTML = '<span class="secnum">Annex ' + clauseNumber + '</span> ' + clauseTitle; | ||
return link; | ||
} | ||
|
||
link.innerHTML = '<span class="secnum">' + clauseNumber + '</span> ' + clauseTitle; | ||
return link; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure we could've done all of this with print styles and an :after
selector.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which part? This function exists to gather information on sections that the links themselves don’t have (and CSS wouldn’t have access to, I don’t think?)
js/print.js
Outdated
/** | ||
* The emu-imports element interferes with a ton of css specificity so we just | ||
* take everything out and plop it directly into the DOM | ||
* */ | ||
function removeEmuImports() { | ||
const emuImports = Array.from(specContainer.getElementsByTagName('emu-import')); | ||
|
||
emuImports.forEach(importedMarkup => { | ||
while (importedMarkup.hasChildNodes()) { | ||
importedMarkup.parentNode.insertBefore(importedMarkup.childNodes[0], importedMarkup); | ||
} | ||
importedMarkup.parentNode.removeChild(importedMarkup); | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be fine to just not emit these in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d prefer to either leave that in your capable hands, or tackle this myself in a separate PR. Most importantly, after all the time, effort, and ecma money I dumped into producing a quality document, I want to merge what worked.
js/print.js
Outdated
/** | ||
* Gets rid of elements we don't need in the print version | ||
* */ | ||
function removeUnusedSections() { | ||
const ecmaLogo = document.getElementById('ecma-logo'); | ||
|
||
if (ecmaLogo) specContainer.removeChild(ecmaLogo.parentNode); | ||
|
||
document.getElementsByTagName('body')[0].removeChild(document.getElementById('shortcuts-help')); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surely this can be done with print CSS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
of course it can. getting the scripts to output what i need is a finicky thing though and I try to feed it the simplest, cleanest markup i can.
js/print.js
Outdated
/** | ||
* A little content rearranging specifically relevant to 262 | ||
* */ | ||
function ecma262fixes() { | ||
const toc = document.getElementById('toc'); | ||
|
||
// eslint-disable-next-line prettier/prettier | ||
specContainer.insertBefore(document.getElementById('sec-bibliography'), document.getElementById('sec-colophon')); | ||
Array.from(toc.getElementsByTagName('a')).forEach(anchor => { | ||
if (anchor.getAttribute('href') === '#sec-colophon') { | ||
toc.getElementsByTagName('ol')[0].appendChild(anchor.parentNode); | ||
} | ||
}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be fine to just rearrange these in the 262 spec document directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d like very much to address that in a separate PR as well.
Tried to keep the css together but it doesn't feel super logically grouped so I wound up rearranging everything. Sorry future git-blamer. Units of measurements are all over the place, here's what defines them: - mm for page-related units - pt for text-related units - em for horizontal units - ex for vertical units Highly specific rules come from a loyalty to the Ecma specification template first, previous years' standards second. There should be no changes that impact screen rendering; changes to the primary stylesheet come from inline styles that existed in both ECMA-262 and ECMA-402. - Remove print css from Spec file - Remove styles from inline assets test - Add publishing instructions - Small tweaks to allow ecmarkup to generate print-friendly PDFs beyond just 262 & 402 - Use font-face to make sure all the characters are rendered as we wish, including 0 with slash, double-stroke F, and infinity - Dynamically generate PDF covers based on frontmatter (TODO: Ecma-endorsed proposal cover?) - Make sure year is being properly inserted into footers
// 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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dead comments
// 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); |
.full-page-svg { | ||
color: rgba(255, 255, 255, 0); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gesa Kevin and I couldn't figure out what this class is used for. Why have transparent white text on the front cover and inner cover? And what's with the class name?
Tried to keep the css together but it doesn't feel super logically grouped so I wound up rearranging everything. Sorry future git-blamer. Units of measurements are all over the place, here's what defines them:
Highly specific rules come from a loyalty to the Ecma specification template first, previous years' standards second.
There should be no changes that impact screen rendering. Any changes to the primary stylesheet come from inline styles that existed in both ECMA-262 and ECMA-402.
The cover SVGs aren't really used by ecmarkup directly, but are rather to be viewed as source files for the two specifications.