Closed ThomasPrioul closed 4 years ago
That's a really good question! The short answer is that for now we do not provide an easy way to do that but I have a few ideas :wink:
The first one is that it should be possible to delegate to a "built-in" converter. The second one is that we should create an higher-level API to override specific components. For instance, the Table Of Contents or the title page.
The footer content is defined via CSS using @page
:
To be honest, I'm not really sure how we can define a complex layout in the footer... maybe Paged.js has a feature to do that... I need to check.
I tried copying all the contents of the /lib folder to my document directory and then edit from there, but I'm having some trouble with npm and the resolving of all the dependencies.
We are reading some assets from the css
directory and from the node_modules
.
Forking the project does work, except I'm limited to using the alpha3 (with all my f***ing corporate PC problems) and I think it's not very practical and surely I'm missing something.
Unfortunately, that's probably your best bet for now :disappointed:
To be honest, I'm not really sure how we can define a complex layout in the footer... maybe Paged.js has a feature to do that... I need to check.
I found this : https://www.w3.org/TR/css-gcpm-3/#running-syntax And also read this article : https://www.pagedmedia.org/paged-media-approaches-part-1-of-2/
See the 4th drawing there.
It appears that if you declare the header content in CSS with element(
It kinda works:
However paged.js is giving some headache. It seems like it's adding styles to the global stylesheet through some javascript event, so its stylesheets always have priority over mine, as they always end up in the end of the style tag. Here is what it always ends up in the stylesheet:
.pagedjs_page .pagedjs_margin-bottom-center {
}
.pagedjs_page .pagedjs_margin-bottom-center>.pagedjs_margin-content>* {
display:table
}
.pagedjs_page .pagedjs_margin-bottom-center {
}
.pagedjs_page .pagedjs_margin-bottom-center>.pagedjs_margin-content>* {
display:block
}
The first two blocks is my attempt at moving the "customStyleContent" in the template further away like this:
module.exports = {
document: (node) => {
const cdnBaseUrl = `${assetUriScheme(node)}//cdnjs.cloudflare.com/ajax/libs`
const linkcss = node.isAttribute('linkcss')
const contentHTML = `<div id="content" class="content">
${node.getContent()}
</div>`
const syntaxHighlighter = node['$syntax_highlighter']()
return `<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="UTF-8">
<style>
${asciidoctorStyleContent}
${documentStyleContent}
${titlePageStyle(node)}
</style>
${stemContent.content(node)}
<script>
${pagedContent}
${repeatTableHeadersContent}
</script>
<style>
${customStyleContent(node)}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
${syntaxHighlighterHead(node, syntaxHighlighter, { linkcss: linkcss })}
</head>
<body class="article">
<table class="bottom-title-block">
<tbody>
<tr>
<td>Left content</td>
<td>Middle content</td>
<td>Right content</td>
</tr>
<tr>
<td>Left content</td>
<td>Middle content</td>
<td>
<p class="page-count">/</p>
</td>
</tr>
</tbody>
</table>
${titlePage(node)}
${contentHTML}
${footnotes(node)}
${syntaxHighlighterFooter(node, syntaxHighlighter, { cdn_base_url: cdnBaseUrl, linkcss: linkcss, self_closing_tag_slash: '/' })}
</body>`
}
}
And using a custom stylesheet in the CLI with -a stylesheet=my.css
The last two blocks which override mine seem to come from paged.js.
Here is my custom css:
@page {
margin: 1.5cm;
size: A4;
@bottom-center {
content: element(bottom-title-block);
}
}
@page :left {
@bottom-right {
all: revert
}
@bottom-left {
all: revert
}
}
@page :right {
@bottom-right {
all: revert
}
@bottom-left {
all: revert
}
}
@page :first {
@bottom-right {
all: revert
}
@bottom-left {
all: revert
}
}
.page-count::before {
content: counter(page);
}
.page-count::after {
content: counter(pages);
}
table.bottom-title-block {
table-layout: auto;
display: table;
width: 100%;
}
.bottom-title-block {
position: running(bottom-title-block);
}
// completely useless
.pagedjs_page .pagedjs_margin-bottom-center {
}
.pagedjs_page .pagedjs_margin-bottom-center>.pagedjs_margin-content>* {
display: table;
}
I found out that you can actually embed raw HTML markup inside an asciidoc document. https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/ at the section called passthrough. This is a good candidate for these complex headers/footers, and doesn't involve modifying the source code of this project. However it only works in the body of the document, not the title page. Just a bit of HTML and a stylesheet. You enclose the HTML with 4 plus signs in the asciidoc. You can also use attributes in there, which is pretty awesome.
[subs=attributes]
++++
<table class="bottom-title-block">
<col width="8*">
<col width="2*">
<tr>
<td>{description}</td>
<td>Top R</td>
</tr>
<tr>
<td>Bottom left</td>
<td>
<a class="page-count">/</a>
</td>
</tr>
</table>
++++
Also I fixed my earlier problem using the !important value in CSS, so it wins against paged.js styles over the priority.
.pagedjs_page .pagedjs_margin-bottom-center>.pagedjs_margin-content>* {
display: table !important;
}
Seems hackish to me, but it works.
Thanks for sharing @ThomasPrioul
I think we should definitely document how to use a complex layout in the footer using the running
and element
features.
However it only works in the body of the document, not the title page.
I don't understand the all: revert
in you CSS ?
What about using the following:
.title-page {
position: running(title-page); /* remove the default title page */
}
.my-custom-title-page {
position: running(my-custom-title-page);
}
@page :first {
content: element(my-custom-title-page);
}
Just a bit of HTML and a stylesheet. You enclose the HTML with 4 plus signs in the asciidoc. You can also use attributes in there, which is pretty awesome.
This passthrough should really be a temporary solution because now your document is tied to an HTML backend. But in the meantime, that's better than forking the whole project 🤷♂
Also I fixed my earlier problem using the !important value in CSS, so it wins against paged.js styles over the priority.
Paged.js has made some improvements recently. Maybe this default style can be disabled when the footer contains an element
? What do you think @julientaq ?
Also I fixed my earlier problem using the !important value in CSS, so it wins against paged.js styles over the priority.
Every time you see something like this with paged.js, please trigger me. It means that there is something wrong in the lib.
so, you need to have a footer that include quite some informations.
What you need to know is that paged.js polyfill your css properites, or, translate it, so the browser can work with that. We use grid to define the page and flex to define what's inside the margin-boxes. We never add a table in there ever, so this is a new interresting use case.
i would strongy go against table for layout purposes as you can achieve almost the same stuff using grid, with less pain, but that's just an aside
So, in that case, we need to see how to handle that in paged.js
@ThomasPrioul Would you mind sharing a small bit of that HTML so we can think how to get it right? I'll open an issue on https://gitlab.pagedmedia.org/tools/pagedjs right after
Thanks for finding that one :)
I think we should definitely document how to use a complex layout in the footer using the
running
andelement
features.
Yes I agree, once an appealing solution is found, it should be part of the examples.
I don't understand the
all: revert
in you CSS ?
If I omit them, your default styles add page numbers in the left/right column, which clashes with my own content which is using the middle column. Remember that your default template stacks up all the stylesheets, the default ones, the custom one + paged.js which generates styles. This ends up creating a massive amount of styles in the document.
Also it doesn't work in the title page, because I used the title-page attribute.
What about using the following:
.title-page { position: running(title-page); /* remove the default title page */ } .my-custom-title-page { position: running(my-custom-title-page); } @page :first { content: element(my-custom-title-page); }
That probably works yes, I'll check it later.
This passthrough should really be a temporary solution because now your document is tied to an HTML backend. But in the meantime, that's better than forking the whole project 🤷♂
I agree, although one can use #ifdefs in asciidoc IIRC, to remove it when compiling for other backends or making a conditional include just for this output backend. It could be an acceptable compromise. I'd prefer something that really works without necesseraly touching the asciidoc files like when using attributes like toc.
If I omit them, your default styles add page numbers in the left/right column, which clashes with my own content which is using the middle column.
Oh right, I forgot you're still using 1.0.0-alpha.3
. In the latest version, if you use a custom stylesheet then the built-in styles are not added anymore.
I agree, although one can use #ifdefs in asciidoc IIRC, to remove it when compiling for other backends or making a conditional include just for this output backend. It could be an acceptable compromise. I'd prefer something that really works without necesseraly touching the asciidoc files like when using attributes like toc.
Fair enough 😉
so, you need to have a footer that include quite some informations.
I'm actually trying to do a POC at work, that we can get rid of MS Word and all the problems that arise with it, and to promote Asciidoc instead. So I'm trying to mimic what our documents look like at work. I've started with one of the most used templates in A4 format: Title page:
Following pages footer:
You can see how much data this table is supposed to contain, and it's all document metadata that would be a breeze to use with Asciidoctor, I could pass them using attributes in the doc or directly from the CLI...
So far, these tables coming straight from hell are made with MS Word. I let you imagine all the problems related to people using different versions and how MS Word manages its stylesheets inside (a deep auto-generated mess).
So that's why I want to use tables, or grids or whatever most suitable in modern web development! I am not a web developer so I'm still struggling with some of the basics it seems.
What you need to know is that paged.js polyfill your css properites, or, translate it, so the browser can work with that. We use grid to define the page and flex to define what's inside the margin-boxes. We never add a table in there ever, so this is a new interresting use case. So, in that case, we need to see how to handle that in paged.js
Alright. Also I'm wondering how the margins are actually calculated with all of this. If I put a high footer content, I expect it to be placed in between the body of the document and the bottom margin. It seems here that with the default template the page numbers are inserted inside the "margin" boxes. I don't know if I'm making any sense. Here is a photo of the problem I'm trying to describe:
It could work, as long as the size of the bottom boxes resize accordingly on each page and is not of a predefined fixed size. I want the footer to always show correctly and not to bleed out, I want the body to move over to the next page sooner if that's necessary. But that seems not to really be the case right now. Maybe I'm just not using the right tool for the job. It seems the footnotes actually use the page area and not the margin boxes.
@ThomasPrioul Would you mind sharing a small bit of that HTML so we can think how to get it right? I'll open an issue on https://gitlab.pagedmedia.org/tools/pagedjs right after
Here are the relevants bits from the previous comments:
<table class="bottom-title-block">
<col width="8*">
<col width="2*">
<tr>
<td>{description}</td>
<td>Top R</td>
</tr>
<tr>
<td>Bottom left</td>
<td>
<a class="page-count">/</a>
</td>
</tr>
</table>
@page {
margin: 1.5cm;
size: A4;
@bottom-center {
content: element(bottom-title-block);
}
}
.page-count::before {
content: counter(page);
}
.page-count::after {
content: counter(pages);
}
table.bottom-title-block {
table-layout: auto;
display: table; /* This doesn't work because of the paged js styles */
width: 100%;
}
.bottom-title-block {
position: running(bottom-title-block);
}
/* This should not have to be used */
.pagedjs_page .pagedjs_margin-bottom-center {
}
.pagedjs_page .pagedjs_margin-bottom-center>.pagedjs_margin-content>* {
display: table !important; /* Used hack to make it work */
}
Thanks, i'll investigate 👍
@ThomasPrioul You can now override the default converter in the latest published version https://github.com/Mogztter/asciidoctor-pdf.js/releases/tag/v1.0.0-alpha.6
@ThomasPrioul You can now override the default converter in the latest published version https://github.com/Mogztter/asciidoctor-pdf.js/releases/tag/v1.0.0-alpha.6
@Mogztter Newb here sorry if this is a stupid question, but how do I override it? I searched everywhere but still didn't find or understand how to do it
Is it similar to the described in asciidoctor.js' documentation?
There are several options, so it depends on what you want to achieve and how you are calling asciidoctor-web-pdf
but you can take a look at: https://github.com/Mogztter/asciidoctor-web-pdf/blob/1ed0d7ec41cde2fbad4fda94b58a0024bcb4e0ba/test/document_convert_test.js#L15-L30
And how to I set it up? My project looks like this:
project-folder
├───images
├───output
├───sections
├───styles
├───generate-pdf.bat
├───master.adoc
└───output.html
edit: I was using the pre-compile binary but now switched to the npm install and installed the dependencies, but still don't understand how to require('../lib/document/document-converter')
Please join https://chat.asciidoctor.org or post your question using GitHub Discussion.
Issue tracker is reserved for bug.
Thanks!
I would like to customize the title page using a template.js file, to add complicated corporate document tables containing a lot of metadata. Also the following pages footers would endure the same treatment (embedding a small table in the footer).
My understanding is that to do this, you have to override the document node in templates.js module.exports, which contains a lot of pre-defined stuff going on in there. I saw this in the source code :
Which is then used in the document node:
Alongside other things which I would rather not want to touch to, especially if things evolve in this lib's code in the future, I'd just want to edit that specific part of the document generation.
I tried copying all the contents of the /lib folder to my document directory and then edit from there, but I'm having some trouble with npm and the resolving of all the dependencies. Forking the project does work, except I'm limited to using the alpha3 (with all my f***ing corporate PC problems) and I think it's not very practical and surely I'm missing something. My understanding of node, npm and other related things is shallow as I don't work on these technologies.
So my questions are: