Skip to content
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

resolves #207 create a browser-compatible version of the Document converter #228

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules/
/test/output/*.pdf
/test/fixtures/*.html
/test/output/visual-comparison-workdir/
/dist/
11 changes: 5 additions & 6 deletions lib/document/document-converter.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ class DocumentPDFConverter {
this.repeatTableElementsContent = fs.readFileSync(`${__dirname}/repeating-table-elements.js`, 'utf8')
this.pagedContent = fs.readFileSync(require.resolve('@ggrossetie/pagedjs/dist/paged.polyfill.js'), 'utf8')
this.pagedRendering = fs.readFileSync(`${__dirname}/paged-rendering.js`, 'utf8')
const stylesDirectoryPath = ospath.resolve(`${__dirname}/../../css`)
this.asciidoctorStyleContent = fs.readFileSync(`${stylesDirectoryPath}/asciidoctor.css`, 'utf8')
this.documentStyleContent = fs.readFileSync(`${stylesDirectoryPath}/document.css`, 'utf8')
this.titleDocumentStyleContent = fs.readFileSync(`${stylesDirectoryPath}/features/title-document-numbering.css`, 'utf8')
this.titlePageStyleContent = fs.readFileSync(`${stylesDirectoryPath}/features/title-page.css`, 'utf8')
this.bookStyleContent = fs.readFileSync(`${stylesDirectoryPath}/features/book.css`, 'utf8')
this.asciidoctorStyleContent = fs.readFileSync(`${__dirname}/../../css/asciidoctor.css`, 'utf8')
this.documentStyleContent = fs.readFileSync(`${__dirname}/../../css/document.css`, 'utf8')
this.titleDocumentStyleContent = fs.readFileSync(`${__dirname}/../../css/features/title-document-numbering.css`, 'utf8')
this.titlePageStyleContent = fs.readFileSync(`${__dirname}/../../css/features/title-page.css`, 'utf8')
this.bookStyleContent = fs.readFileSync(`${__dirname}/../../css/features/book.css`, 'utf8')
}

convert (node, transform, opts) {
Expand Down
93 changes: 48 additions & 45 deletions lib/document/paged-rendering.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,63 @@
/* global Paged, PagedPolyfill */
window.AsciidoctorPDF = window.AsciidoctorPDF || {}
window.AsciidoctorPDF.status = 'rendering'
class PagedReadyHandler extends Paged.Handler {
afterRendered (pages) {
window.AsciidoctorPDF.status = 'ready'
}
;(function() {
window.AsciidoctorPDF = window.AsciidoctorPDF || {}
window.AsciidoctorPDF.status = 'rendering';

// BEGIN: workaround to prevent duplicated content at end/beginning of page
// https://gitlab.pagedmedia.org/tools/pagedjs/issues/126
constructor (chunker, polisher, caller) {
super(chunker, polisher, caller)
this.carriageReturn = String.fromCharCode(10)
}
class PagedReadyHandler extends Paged.Handler {
afterRendered (_) {
window.AsciidoctorPDF.status = 'ready'
}

checkNode (node) {
if (!node) return
if (node.nodeType !== 3) return
if (node.textContent === this.carriageReturn) {
node.remove()
// BEGIN: workaround to prevent duplicated content at end/beginning of page
// https://gitlab.pagedmedia.org/tools/pagedjs/issues/126
constructor (chunker, polisher, caller) {
super(chunker, polisher, caller)
this.carriageReturn = String.fromCharCode(10)
}
}

afterParsed (parsed) {
const template = document.querySelector('template').content
const breakAfterAvoidElements = template.querySelectorAll('[data-break-after="avoid"], [data-break-before="avoid"]')
for (const el of breakAfterAvoidElements) {
this.checkNode(el.previousSibling)
this.checkNode(el.nextSibling)
checkNode (node) {
if (!node) return
if (node.nodeType !== 3) return
if (node.textContent === this.carriageReturn) {
node.remove()
}
}
}
// END: workaround to prevent duplicated content at end/beginning of page
}

Paged.registerHandlers(PagedReadyHandler)
afterParsed (_) {
const template = document.querySelector('template').content
const breakAfterAvoidElements = template.querySelectorAll('[data-break-after="avoid"], [data-break-before="avoid"]')
for (const el of breakAfterAvoidElements) {
this.checkNode(el.previousSibling)
this.checkNode(el.nextSibling)
}
}
// END: workaround to prevent duplicated content at end/beginning of page
}

window.PagedConfig = window.PagedConfig || {}
Paged.registerHandlers(PagedReadyHandler)

window.PagedConfig.auto = false
window.PagedConfig = window.PagedConfig || {}
window.PagedConfig.auto = false

// same logic as pagedjs, but waiting for 'complete' instead of 'interactive'
const ready = new Promise(function (resolve, reject) {
if (document.readyState === 'complete') {
resolve(document.readyState)
return
}

document.onreadystatechange = function () {
const ready = new Promise(function (resolve, reject) {
if (document.readyState === 'complete') {
resolve(document.readyState)
return
}
}
})

ready.then(async function () {
const done = await PagedPolyfill.preview(window.PagedConfig.content, window.PagedConfig.stylesheets, window.PagedConfig.renderTo)
if (window.PagedConfig.after) {
await window.PagedConfig.after(done)
}
})
document.onreadystatechange = function () {
if (document.readyState === 'complete') {
resolve(document.readyState)
}
}
})

ready.then(async function () {
const done = await PagedPolyfill.preview(window.PagedConfig.content, window.PagedConfig.stylesheets, window.PagedConfig.renderTo)
if (window.PagedConfig.after) {
await window.PagedConfig.after(done)
}
})
})()

74 changes: 38 additions & 36 deletions lib/document/repeating-table-elements.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,50 @@
/* global Paged */
class RepeatingTableElements extends Paged.Handler {
constructor (chunker, polisher, caller) { // eslint-disable-line no-useless-constructor
super(chunker, polisher, caller)
}
;(function () {
class RepeatingTableElements extends Paged.Handler {
constructor (chunker, polisher, caller) { // eslint-disable-line no-useless-constructor
super(chunker, polisher, caller)
}

afterPageLayout (pageElement, page, breakToken, chunker) {
// Find all split table elements
const tables = pageElement.querySelectorAll('table[data-split-from]')
afterPageLayout (pageElement, page, breakToken, chunker) {
// Find all split table elements
const tables = pageElement.querySelectorAll('table[data-split-from]')

tables.forEach((table) => {
// Get the reference UUID of the node
const ref = table.dataset.ref
// Find the node in the original source
const sourceTable = chunker.source.querySelector("[data-ref='" + ref + "']")
// Repeat the <thead> element (if exists)
this.repeatElement(sourceTable, table, 'thead')
// Repeat the <colgroup> elements (if at least one exists)
this.repeatElements(sourceTable, table, 'colgroup')
// Repeat the <caption> element (if exists)
this.repeatElement(sourceTable, table, 'caption')
})
}

repeatElement (sourceTable, table, querySelector) {
const element = sourceTable.querySelector(querySelector)
if (element) {
// Clone the element
const clonedElement = element.cloneNode(true)
// Insert the element at the start of the split table
table.insertBefore(clonedElement, table.firstChild)
tables.forEach((table) => {
// Get the reference UUID of the node
const ref = table.dataset.ref
// Find the node in the original source
const sourceTable = chunker.source.querySelector("[data-ref='" + ref + "']")
// Repeat the <thead> element (if exists)
this.repeatElement(sourceTable, table, 'thead')
// Repeat the <colgroup> elements (if at least one exists)
this.repeatElements(sourceTable, table, 'colgroup')
// Repeat the <caption> element (if exists)
this.repeatElement(sourceTable, table, 'caption')
})
}
}

repeatElements(sourceTable, table, querySelector) {
const elements = sourceTable.querySelectorAll(querySelector)
if (elements) {
elements.forEach((element) => {
repeatElement (sourceTable, table, querySelector) {
const element = sourceTable.querySelector(querySelector)
if (element) {
// Clone the element
const clonedElement = element.cloneNode(true)
// Insert the element at the start of the split table
table.insertBefore(clonedElement, table.firstChild)
})
}
}

repeatElements (sourceTable, table, querySelector) {
const elements = sourceTable.querySelectorAll(querySelector)
if (elements) {
elements.forEach((element) => {
// Clone the element
const clonedElement = element.cloneNode(true)
// Insert the element at the start of the split table
table.insertBefore(clonedElement, table.firstChild)
})
}
}
}
}

Paged.registerHandlers(RepeatingTableElements)
Paged.registerHandlers(RepeatingTableElements)
})()
6 changes: 3 additions & 3 deletions lib/document/stem.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const fileUrl = require('file-url')
const mathjaxFileUrl = fileUrl(require.resolve('mathjax/es5/tex-chtml-full.js'))
const fs = require('fs')
const mathjaxContent = fs.readFileSync(require.resolve('mathjax/es5/tex-chtml-full.js'), 'utf8')

module.exports = {
content: (node) => {
Expand Down Expand Up @@ -61,7 +61,7 @@ module.exports = {
window.PagedConfig.before = () => mathJaxReadyPromise
})()
</script>
<script type="text/javascript" src="${mathjaxFileUrl}"></script>`
<script data-type="mathjax">${mathjaxContent}</script>`
}
return ''
}
Expand Down
Loading