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

Add printable design using Paged.js #62

Open
wants to merge 42 commits into
base: master
Choose a base branch
from

Conversation

vihuna
Copy link
Contributor

@vihuna vihuna commented Oct 4, 2023

Add "printable" design using Paged.js (WIP)

@vercel
Copy link

vercel bot commented Oct 4, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
latex-css ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 7, 2024 9:30pm

@vihuna
Copy link
Contributor Author

vihuna commented Oct 4, 2023

Guidelines (I'm following)

  • Focused in document printing (PDF file secondary goal)
  • Compatibility with non-printable LaTeX.css: The same HTML file used with print.css printable version should work with default style.css
  • No unnecessary javascript: CSS first. I think Javascript should only be used if there is no other choice (fix some element impossible to fix without javascript, address some particular element design because Paged.js pagination …).
  • Separated HTML and CSS files from default style.css and index.html
  • Three CSS files: Two different files for A4-paper and US-letter @page rule, and the third one for the common styles.

Some drawbacks

  • There is a noticeable delay in the paged.js document processing
  • Broken elements during pagination: Sometimes some elements gets broken when they are split in the pagination process. Other times it seems Paged.js eats them. Pagination process seems quite complex and you must take care the final document composition is correct.
  • Bad link behavior: When you introduce in the browser address bar some URL to a label in the document, e.g., [...]print.html#Table-section, the window "reloads" because Paged.js document processing, and does not go to the labeled item. Can this be considered a bug?

Conflicts/Errors

(in the process of loading a document using Paged.js.)

It's very easy, if you are not careful, to get random rendering issues when you load\reload the paginated document.
In order to work properly, Paged.js must be the last Script that manipulates DOM and CSSOM to load.

So you must be careful that all your scripts that modify the DOM and CSSOM have finalized before Paged.js starts to process the document. From Paged.js documentation:

"As soon as your browser has loaded everything your HTML needs to be shown on screen (including images, font files, etc.), the script will start paginating the content and pages will appear on your screen."

So the solution for scripts is to load them before Paged.js; but there are also some other problematic elements: those that can be lazy loaded.

  • fonts: I haven't noticed problems in local fonts loading. As it says in previous quote, Paged.js waits until fonts are loaded. And from the loadFonts() function code

    https://gitlab.coko.foundation/pagedjs/pagedjs/-/blob/main/src/chunker/chunker.js?ref_type=heads#L541-557

    it seems that verifies when the fonts are loaded (as far as I know, browser assigns the status "ready" when "no further font loads are needed", having chosen the font according to font-display CSS settings).

    So it seems there is no problem using font-face to load the fonts. But if you use web-fonts with @import and the fonts are not found, throws a "Failed to load resource" error, and Paged.js displays a blank document (it doesn't use the fallback font?).

  • images: If you lazy-load an image, sometimes the [pagedjs]-document ends just in the last page before the image. I don't know if "is assumed" you don't have to use lazy loading or it is a bug. From the documentation and having taken a brief look at some functions of the code,

    https://gitlab.coko.foundation/pagedjs/pagedjs/-/blob/main/src/chunker/layout.js?ref_type=heads#L351-367,

    it seems, again, that Paged.js is designed so that awaits until the image is loaded (although somewhat tricky, they use complete property to determine if the image has finished loading). So the issue seems more complex, probably involves the way all three modules work together¿?. There is an open issue (without response) about this:

    https://gitlab.coko.foundation/pagedjs/pagedjs/-/issues/411

    Anyway, sometimes there are elements or fragment of elements that disappear from final document, so there are other things to worry about.

In conclusion, I think it's recommended not to use web-fonts and do not lazy-load images.

Some tasks to consider

  • US letter page size CSS style
  • Add table of contents
  • Use particular MathJax and Prism components to verify loading
  • Demonstration end sign: remove the overflow to the margin
  • Adjusts scrollable elements and overflow
  • Remove scrolls when printing
  • Remove scroll overflow section
  • Remove some other non-useful sections for printable version
  • Disable dark color scheme when printing
  • "Mechanism" (i.e. classes) to force-avoid unwanted breaks
  • Remove margin-top from first paragraph of each page
  • More document font sizes: 10pt, 12pt
  • Links in PDF file (don't work in Firefox 102.15esr)
  • Replace remote images with local ones
  • Reduce max-with for images
  • Place each footnote in its own page?
  • Add headers?

Other considerations

  • File obtained:
    LaTeX.css — Make your website look like a LaTeX document.pdf
    (one figure element is broken and the image is missing)
  • Next task I'm going to address is fix the ToC.
  • I have used A4-11pt LaTeX default document dimesions (the margin notes are two narrow for my taste).
  • I assume this is going to take some time.
  • Lets discuss all the details/errors/considerations.

PR Tasks

  • Fix ToC section numeration

  • Add page numbers

  • Add page numbers to ToC

  • Move footnotes to the page they belong (CSS Paged Media footnotes)

  • Fix side-notes:

    • Adjust side notes to margin size (by default)
    • Move inner/outer margin to footnote
    • Avoid main text early page break issue
  • Update default margins, sidenote width

  • (doc) Page Size and Margins Customization

  • CSS utility classes

    • Toc Page numbers
    • Document font size: 10pt, 11pt, 12pt
    • Line height: single, one and half, double
    • Document inner outer side-notes.
    • Page breaks:
      • Add classes to manually force/avoid breaks
      • Avoid/force automatically some page breaks
    • (doc) CSS utility classes section for paged layout
  • Theme/Printing issues:

    • Theme Colors/Dark Theme
      • Printing contrast: black fonts, white background
        (Remember to verify the backgrounds added to do the trick in ToC)
      • Fix Dark Theme Issues (if possible, otherwise, remove/disable it)
      • (doc) Update (remove) Dark Theme section
    • Fix line-height to 1.5 in default style
    • Wrap text inside literal code (avoid scrolls)
    • (doc) Remove "Scroll Overflow" section
    • Remove math demonstration end sign overflow
    • (doc) Update sidenotes section for paged layout
  • Revise Paged.js loading method (again)

  • Update Vitejs config

  • (doc) Add "Issues and Recommendations" section:

    • Web Browser
    • Loading Paged.js
    • @import method is not supported
    • Lazy loading methods not supported (loading attribute automatically removed)
    • Printing/Dark-Mode
    • Page breaks

(updated: wrong PDF attachment)

ToC differences with default LaTeX.css, to mimic LaTeX default styles:

- No padding for root ToC list.
- First-level ToC sections in boldface style.
@vihuna
Copy link
Contributor Author

vihuna commented Oct 14, 2023

About line-height calculations (to fix the error)

I made a mistake with the value of the line height (I forget to transform \linespread value to HTML).

To explain the upcoming change (so that there is no doubt), I'm going to comment how line height is determined both in LaTeX and HTML (as far as I understand).

In LaTeX, the line height is mainly determined by \baselineskip (among other variables, it's not so simple). E.g., by default in 10pt LaTeX article, \baselineskip = 12.

Approximately, the [defined-by-me]-ratio \baselinescriptfactor := (\baselineskip) / (\fontsize) is always around 1.2.

So "approximately^2" the method how line height is determined in LaTeX is:

LineHeight = (\baselineskipfactor) * (\linespread) * (\fontsize)

So,

  • 1.5 * (\fontsize) factor for LineHeight corresponds to \linespread = 1.5 / 1.2 = 1.25;
  • 2 * (\fontsize) factor for LineHeight corresponds to \linespread = 2 / 1.2 = 1.666.

(I usually use 1.3 and 1.6 resp)

And the more natural way how line height is determined in HTML is (supposed line-height is used with a unit-less value):

LineHeight = line-height * font-size

So, assuming that the same units are used, equating both expressions for LineHeight, the following relation can be established:

(\baselineskip) * (\linespread) = line-height

So, obviously (it's actually the same as above):

  • \linespread = 1.25 iff line-height = 1.5,
  • \linespread = 1.666 iff line-height = 2.

- New CSS class `toc-page-numbers`
- Display ToC page numbers in `print.html` document
@vihuna
Copy link
Contributor Author

vihuna commented Oct 16, 2023

Finally, this is my proposal for the ToC (with page numbers). This is how it looks (left:Firefox, right:Brave, line-height still unfixed):
ToC-firefox-brave

The ToC must be manually written as for LaTeX.css without pagination.

I have tried several options (the nested lists have been a headache), but I think this is the best compromise between "LaTeX resemblance" and "javascript usage".

It has been "necessary" to add (using javascript) a container for the dotted-line, but the rest of the original ToC HTML code remains unchanged.

Main Disavantages:

  • It hasn't be possible without javascript.
  • Complex CSS design (with some necessary tricks).
  • The ToC must strictly follow a fixed HTML layout (otherwise the rendering may be broken).
  • It looks like LaTeX ToC style, but some important differences (if you are familiar with LaTeX) still remains.

ToC layout differences

  • How LaTeX align Toc entries:
9.9  |Toc Entry: Lorem ipsum dolor

     |9.9.1   |ToC Entry: Lorem ipsum dolor
      [...]
     |9.9.9   |ToC Entry: Lorem ipsum dolor
     |9.9.10  |ToC Entry: Lorem ipsum dolor sit amet, consectetur
              |adipiscing elit
  • How LaTeX.css aligns Toc entries:
9.9  |Toc Entry: Lorem ipsum dolor

    |9.9.1  |ToC Entry: Lorem ipsum dolor
     [...]
    |9.9.9  |ToC Entry: Lorem ipsum dolor
    |9.9.10  |ToC Entry: Lorem ipsum dolor sit amet, consectetur
    |adipiscing elit
  • How LateX.css "printable" aligns Toc entries:
9.9  |Toc Entry: Lorem ipsum dolor

    |9.9.1  |ToC Entry: Lorem ipsum dolor
     [...]
    |9.9.9  |ToC Entry: Lorem ipsum dolor
    |9.9.10  |ToC Entry: Lorem ipsum dolor sit amet, consectetur
             |adipiscing elit

I think the only way to automatically mimic LaTeX style (if desired) is by using more javascript for size calculations (maybe it could be manually achieved with a set of custom CSS classes).

@vihuna
Copy link
Contributor Author

vihuna commented Nov 1, 2023

List issues

As it has been commented before, for ToC design I have tried to keep balance between "javascript code used" and "LaTeX features achieved".

I would like to show some errors that may happen to lists while the document is been split (most of them for Chrome-based browsers). I thought this behavior was expected, and it was supposed you must use break-* CSS rules, but there is an open issue in Paged.js repo with a more detailed explanation.

Some more of this situations can be added: it not only occurs with marker, but also may happen with before or after pseudo-elements; and with figures and tables too. Some images (Firefox on left, Brave on the right):
firefox-brave ToC-error-1

firefox-brave-ToC-error-2

table-caption-break

I will add later some classes for break-* CSS rules, no only for break-inside: avoid like in the linked issue, but also break-before and break-after, to deal with these breaks. Focusing in the ToC layout, its clear we need also the two last properties, because of the nested lists. This classes must be added manually when one of this breaks occurs. I have tested them and it seems they work properly; also Paged.js documentation says these three properties are supported.

Other possibility it would have been to use javascript to process all lists, transform them into one-level nesting lists, while the nesting level is represented through CSS classes. So a simpler list is obtained, with a more easy CSS customization (I suppose). It also be easier to use break-inside automatically, and to avoid break-before/break-after.

One more challenging error while splitting, occurs with default marker lists and only in Firefox: it doesn't respect start list attribute if counter-reset property (automatically added by Paged.js) is used at the same time.

firefox-brave-lists-error

For the moment, this particular Firefox error must also be manually fixed by the user: you must add value="<counter>" [at least] to the first li element after the page break, and <counter> must be the position of the element inside the list.

@vincentdoerig
Copy link
Owner

Thank you so much for this PR @vihuna!

I've had a look at your code and comments and I'm impressed with the work you've done here. Here are my thoughts:

  • Your guidelines you are following are good and I agree with them
    • Since the printable version is our main objective, I I would force the background color of the document to true white and the main text to black since to create the most contrast possible.
  • The delay is fine since it is only for the first time the page is loaded and not too long anyway
  • I was able to reproduce the section anchor reload issue. My fix for this would be to add
if (location.hash) {
  setTimeout(() => {
    window.scrollTo(0, 0);
  }, 0);
}

to latex-css-print.js and after loading the script, scroll the element with the id of the hash into view. It's a little bit choppy but better than the double reload and not scrolling into view at all.

after: () => {
  if (location.hash) {
    const hash = location.hash;
    const element = document.querySelector(hash);
    if (element) {
      element.scrollIntoView();
    }
  }
  return ...
}
  • For the fonts loading it is fine if it "only" works with font-face. We can add a note to the docs that the @import method is not supported.
  • The Prism and MathJax detection is smart!
  • Removing the loading attribute to eagerly load the images is good. This would only cause troubles on slow connections or document with a lot of images but I think that is fine for now.
  • I agree that the margin notes are two narrow. Feel free to make them wider but keep do make sure that you keep a minimum ~6-10mm margin to be sure that they don't get cut off when printing.
  • Thanks for the insights on the line-height calculations, I'm no typography expert but I think that looks good.
  • Building the Table of Contents with JavaScript is fine. I was sure that this would be inevitable at some point. Not being exactly up to LaTeX standards is also okay, we can always improve it later.
  • Adding the break-* classes would be good! It's not optimal that these have to be added manually but I see that doing it automatically would be quite difficult.
  • The Firefox marker issue is a bit annoying but unless you have a better idea, I think it's fine to leave it as is with a note in the docs

Going forward, I think that adjusting overflows would be the most important thing to do. Especially the scrolling code blocks require some text-wrapping. I would also force light mode by removing the latex-dark and latex-dark-auto classes if present. US letter page size would be nice to have but fine to leave out for now. Links in the PDF file seem to work in Chrome but indeed not in Firefox, do you think that this can be fixed? If not, we might have to consider supporting the printing feature in "Chrome only".

More document font sizes would be nice, but I think that adding a "wider" version that fits more text on a page would also be quite useful (side notes will pose a challenge though -> maybe remove them entirely?).

I would agree that removing the margin-top from the first paragraph (or heading) of each page would be good to keep the page layout consistent.

I think that there is a lot that could be done (footnotes on its associated page, headers, etc.). I'm currently not in the position to do much work on this myself but I'm happy to review your work, comment it and merge it once it's ready. It just might take a while until I get to it. Again, thank you so much for your work on this!

@vihuna
Copy link
Contributor Author

vihuna commented Nov 22, 2023

Since the printable version is our main objective, I I would force the background color of the document to true white and the main text to black since to create the most contrast possible.

I agree.

I was able to reproduce the section anchor reload issue. My fix for this would be to add ...

I think is a very good solution, I have tested an it works. Thanks for this great improvement.

For the fonts loading it is fine if it "only" works with font-face. We can add a note to the docs that the @import method is not supported.

It's also needed for the ToC links: if not removed, the pages after the Image are not rendered and some of the ToC links will not work (Paged.js does not finish to render the document until the image is loaded).

Adding the break-* classes would be good! It's not optimal that these have to be added manually but I see that doing it automatically would be quite difficult.

I agree, specifically with complex lists.

The Firefox marker issue is a bit annoying but unless you have a better idea, I think it's fine to leave it as is with a note in the docs

It should be possible to do automatically with javascript the manual solution that I remarked previously. I would like to do it only for Firefox (and without user-agent identification), so a specific "firefox" option must be provided (in some way ...).

Going forward, I think that adjusting overflows would be the most important thing to do. Especially the scrolling code blocks require some text-wrapping

Me too. I want to finish two issues I was working on (I comment them later). I understand that you are referring to "automatic text-wrapping" with CSS (tell me if I'm wrong, I also prefer this way). I just want to note that LaTeX does not wrap text inside verbatim environment, you must use the listings package and use the appropriate option for this.

US letter page size would be nice to have but fine to leave out for now

Well, it's almost finished. Different page designs will be implemented through CSS named pages. My idea was to change the default @page margin dimensions with a more reasonable values, and six named pages corresponding to the default {a4paper, letterpaper} x {10pt, 11pt, 12pt}. I wrote a python script (latex-page-sizes.py.txt) to calculate the dimensions. Still not revised, but I upload it, so you will know where this values come from.

I paused this because I was undecided about merge all print-*.css files, the default ANSI letter would be another named page.

Links in the PDF file seem to work in Chrome but indeed not in Firefox, do you think that this can be fixed?

Unfortunately I think this is not possible. In PDF format, "internal hyperlinks" are not a special type of hyperlinks (special URL): internal links are made using "Link Annotation" objects, and external links using "URI Action" objects (screenshot with unpacked PDF, left Firefox, right Brave):

pdf-firefox-brave

It seems Firefox-pdf always use the "URI Action" for all type of links (as a way to avoid confusion, this links can be removed before printing to pdf).

Firefox external links work correctly. Also, WebKitGTK removes all links. I almost haven't tested WebKit (epiphany in Linux), it should be equivalent to Safari (I will try to test Safari printing on Windows).

If not, we might have to consider supporting the printing feature in "Chrome only"

I understand the advantages, and I see no problem for personal local usage (this user has already written the document using LaTeX.css). But it seems a more delicate question for a document on a public web host, that you want to allow printing (perhaps users doesn't know about LaTeX.css, they are not warned about it before arriving, using their favourite web browsers ...).

Without any doubt, Chrome-based browsers are the recommended ones, and we must highlight it this way in the documentation (just as Paged.js does).

This point should be discussed further.

More document font sizes would be nice, but I think that adding a "wider" version that fits more text on a page would also be quite useful (side notes will pose a challenge though -> maybe remove them entirely?).

I'm beginning to understand that you would like [if possible] an "out of the box" working (i.e., almost without user supervision). I think at this moment is far from possible, but some steps in this direction can be taken. The problem, and the reason because I choose the "all manual" way: I think it's more simple for the users to see the need for a page break at certain line/position in the document, instead of dealing with a page-break (introduced previously by LaTeX.css, not working properly for some reason, and users probably don't know how LaTeX.css inserts this breaks) that they must override and insert their custom one. Also, if you oversaturate the document with forced page-breaks and page-break-avoids, Paged.js may not work properly.

Even LaTeX, by default, relies on the user judgment to verify if text in verbatim environment and sidenotes fits on the page.

About the sidenotes, it's a feature I really like; and unfortunately, there are also other problematic elements. Let's give the sidenotes a chance for the moment, and we can decide about them later.

I need to think more about all this.

I'm currently not in the position to do much work on this myself but I'm happy to review your work ...

I understand, thanks, I appreciate your support and your work on LaTeX.css.

@vihuna
Copy link
Contributor Author

vihuna commented Nov 22, 2023

I have been working lately on three points:

  • Testing even more the page breaks (specially with side notes). I want to test as much different error cases as possible, so that decisions can be made when necessary. I also have been playing with Paged.js Handlers and the way to manually adjust the page breaks.

  • Trying to Fix the side notes issues with page breaks. I wanted to avoid using Paged.js handlers for the moment, but it has not been possible. The best way to show this issue is with a screenshot:

    sidenotes-issue

    When the page break occurs just after or inside a "long" sidenote, Paged.js assumes that no more text can be added to this page, so it is going to leave a blank space in the main text area.

    I was working in a more complex solution (with no success), finally I prefer to do a trick: I set the sidenotes height to 0 display: none; for sidenotes before the Paged.js chunker processes the pages; and I set the height to auto display: block; again, before Paged.js renders the pages.

        class sideNoteHandler extends Paged.Handler {
          constructor(chunker, polisher, caller) {
            super(chunker, polisher, caller);
          }
          beforeParsed(content) {
            addCssStyle('\
              .sidenote {\
                // height: 0;\
                display: none;\
              }');
          }
          afterRendered(pages) {
            addCssStyle('\
              .sidenote {\
                // height: auto;\
                display: block;\
              }');
          }
        }
        Paged.registerHandlers(sideNoteHandler);

    This is the result:

    sidenotes-issue-fix

    This way, the LaTeX default behavior with sidenotes is replicated: sidenotes do not automatically flow to the next page, the user must check that the sidenote fits in its page.

    I want also to note that there is a [more elaborated, original] "margin notes" example in Paged.js repository.

    Also, if Paged.js "page breaks" work properly with multiple columns (e.g., using flexbox), a more sophisticated method could be implemented in the future, extracting the text of the sidenotes from the main text flow.
    Updated (29/11/2023) This is still not supported: https://gitlab.coko.foundation/pagedjs/pagedjs/-/issues/332#about-flex-and-grid

  • Changing the way LatexCss works: at this moment, configuration must be done through LaTexCss, and all custom config provided by the user in the HTML file will be overwritten. I don't like this behaviour or the resposibility to adapt the script to any particular user setup case. Users should be able to do it by themselves, if they want to (e.g., to use what I'm going to call the "fallback loading method").

(EDIT: it seems more effective to use display: none; instead of height: 0;)

@vihuna
Copy link
Contributor Author

vihuna commented Nov 22, 2023

More Pagedjs-Firefox issues (this doesn't affect the document rendering)

Firefox users can get some errors with Pagedjs if they also use MathJax:

Pagedjs-MathJax-errors
(Sorry for the language, it says: "Not valid markup: wrong number of children in <msub/> tag")

This is due to the "assistive MathML" feature used by MathJax. You can disable it in MathJax options:

MathJax = {
  options: {
    menuOptions: {
      settings: {
        assistiveMml: false,
      }
    }
  }
}

Use a more flexible way to load Paged.js config:

- Make `onloadPromises` not public: it can no longer be used to add
additional user promises. Paged.js custom config must be done outside
LatexCss.

- Make LatexCss startup promise public, so the users can use it in their
custom Paged.js settings.

- Do not overwrite user config for Paged.js if it has been already
  provided.

- `MathJax.startup` and `Prism.highlight` are now used to verify if
MathJax and Prism are loaded, to avoid false positives.

- Add log messages if Prism, MathJax, `removeImgLoading` and
`toc-page-numbers` are detected.

- Add fallback method example to Paged.js loading section
Do not force to use `id="top"` with `body`.
Remove the functions wrapping the promises `removeImageLoadingPromise`
and `addTocNumbersPromise` (not necessary anymore).
`let` -> `const` for variables that are not going to be re-assigned
The US letter page size will be implemented using CSS named pages.

- Merged files: `print.css` + `print-A4.css` -> `style-paged.css`

- Renamed files:
  - `print.html` -> `index-paged.html`
  - `latex-css-print.js` -> `latexcss-paged.js`

- Modified the doc and code comments to reflect these changes in file
  names.
@vihuna
Copy link
Contributor Author

vihuna commented Nov 29, 2023

Before changes in a98dd41, Paged.js settings provided by users were overwritten by LatexCss. And Paged.js configuration had to be done through LatexCss; so there were more limitations, if you want to keep it simple.

After the changes, user settings for Pagedjs are respected, and LatexCss.js provides a startup Promise (which includes MathJax and Prism promises, if they are used, among others), so responsibility lies with the users, if they want to change default Pagedjs + LatexCss settings.

In 965364d the CSS "paged" files have been merged. CSS and JS files have been renamed , and the doc and code comments have been updated to reflect these changes in the file names. Sorry for this quite disruptive changes.

@vihuna
Copy link
Contributor Author

vihuna commented Feb 5, 2024

I have already made some decisions and I have a more specific idea about the tasks in this PR (a task list has been added). Some comments:

  • Following the indications (and this make me sad), only Blink-based browsers will be really supported for the moment. Different fixes (or improvements) for other engines can be added later.

  • Also following indications about sidenotes, there will be only sidenotes in exactly one of the margins. Managing side notes it's not an easy task. For example, because sidenotes are floating elements, there will be a forced vertical gap (the height of the first of them) between the left and the right side notes. This is not really an issue for LaTeX.css "continuous layout" but it's important for "paged layout", where the side notes should fit into its own page. Also, by default, sidenotes are not going to be displayed.

    To keep compatibility with default "continuous layout", sidenotes from one of the margins will be transformed to footnotes. Also, a more different markers should be used, to avoid confusing sidenotes with footnotes.

  • Named pages and variables inside @page. Because browsers's CSS Paged Media implementation is still incomplete, different page sizes can't be used in the same document. An open issue from Pagedjs repo related to named pages size can be found here:

    https://gitlab.coko.foundation/pagedjs/pagedjs/-/issues/218#note_77988

    from where I highlight this comment:

    «It seems that the only size used is the @page one.»

    This is because the first page size to be applied is from base.js @page rule (US letter, if I remember); if you want to specify another page size, applying other named page @page other {···} is not going to work and you must overwrite specifically the @page rule.

    Also from Paged.js docs:

    «Warning: the browser can only understand one page size for your document. If you need to create a document with different page sizes, you will need to create two separate HTML files and generate two PDFs.»

    So to summarize: named pages doesn't work for different page sizes inside the same document, and they only can be used to apply different margin layouts.

    Also because a deficient browsers implementation, it seems variables don't work inside @page rule:

    https://stackoverflow.com/a/44738574

    All that things make the use of CSS Page Media implementation quite restrictive. And, if the user wants to personalize the size of the margins, the custom CSS code to be added will be also more confusing. So, I have decided to not use CSS named pages.

  • It seems Paged.js has some problems with hyphenation while paginating the document: (the piece or word rev- is missing)

    hyphenation-paged

    There is an issue in Paged.js repo:
    https://gitlab.coko.foundation/pagedjs/pagedjs/-/issues/266

    So hyphenation has been disabled.

  • @media print and dark-mode. Because the way it works, Paged.js takes the content inside @media print and adds it after all other user CSS (also after @media screen), but without the media query; from Paged.js doc:

    «Paged.js tricked the browser to show you the styles from the CSS for print, in a screen context, because we preview those pages, on a screen».

    So the question is: if the CSS file does not already conform to CSS specification (because the pagedjs-ignore), why not simplify all the Paged.js CSS loading by removing the @media print query from the beginning? This way will be more easy to manage, for example, the dark-mode options, isn't it?

    For the moment, because is preventing some content shifting, I have decided not to remove the @media print rule; i.e., before Paged.js is loaded, the CSS inside @media print is NOT applied for screen display. And style-paged.css depends on base.js CSS code, loaded by Paged.js.

    To summarize it: if @media print is not used, that CSS code is loaded before Paged.js processing, and because it depends on CSS code from base.js is not displayed as expected. Then Paged.js is loaded, applies CSS code in base.js and the page is displayed as planned, causing more content shifting. By preserving the code inside @media print some of that content shifting can be avoided.

    Because this CSS dependency (and also because some other breaking changes like those described here and introduced in v0.4.1), I think specific version of Paged.js should be loaded.

    So, because @media print will continue to be used, Paged.js has limited support for media queries, and because it seems also contrary to Paged.js design (remember the previous quote from docs), I have decided that latex-dark and latex-dark-auto classes are not going to be supported in paged LaTeX.css.

  • Other. I have already checked that Paged.js takes care to not indent the first paragraph in a page, if it follows from a split paragraph, when the class indent-pars is used (it uses text-indent: unset; for a split paragraph).

- Use vite to build `latexcss-paged.js` script: used library mode to
bundle the source files and built as an iife function
- Evaluate `LatexCss` promises when Paged.js runs `PagedConfig.before`
- Add `style-paged.css` to the package build
- Add package command `preview`, in the root path
- Use `latex.now.sh` domain in code examples
- Improve instructions of «Loading» section
- Remove `defer` attribute in code examples
Copy link

vercel bot commented Feb 11, 2024

Deployment failed with the following error:

The provided GitHub repository does not contain the requested branch or commit reference. Please ensure the repository is not empty.

@vihuna
Copy link
Contributor Author

vihuna commented Feb 11, 2024

Not much to say about the vite build config, the javascript modules are compiled in library mode, as an iife function. I have also added a "vite preview" command to config, in the base path.

It has not been changed any of the Promises, only the way they are loaded (maybe that change goes unnoticed). Before these changes, the startup promises were evaluated when the old file latexcss-paged.js was loaded. Now, if I'm not wrong, they are evaluated after Pagedjs has started and the DOM is already read.

This is quite important for Mathjax and Prism detection, for example. Before these changes, Mathjax and Prism scripts had to be executed before latexcss-paged.js or they will not be detected (it was not completely detailed in the docs, I think). With that changes in the scheme to load the promises, the only limitation is that Paged.js must start after all the other scripts have already been executed. Above all, the configuration provided by latexcss-paged.js must be executed before Paged.js starts (Paged.js is going to read the configuration before the HTML reading is complete, and evaluates the promises after that):

https://gitlab.coko.foundation/pagedjs/pagedjs/-/blob/main/src/polyfill/polyfill.js?ref_type=heads#L19-L35

That means that a configuration like this will work properly

<script src="latexcss-paged.js"></script>
<script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>
<script id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

but you must be lucky with this other ones:

<script id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
<script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>
<script src="latexcss-paged.js"></script>
<script defer src="latexcss-paged.js"></script>
<script defer src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>
<script defer id="MathJax-script" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

At this moment, I don't know the best solution to avoid that limitation (load Paged.js dynamically?, import it [the Previewer] as a module? ...), so the loading method will stay like this.

@vihuna
Copy link
Contributor Author

vihuna commented Feb 11, 2024

I have never used Vercel, but I suppose that it does some trick with the repo URL for the deployment of PR branches, what fails after you change package.json.
Let me know @vincentdoerig, if there is a way to solve this issue with Vercel, or it's better to continue in a new fresh PR.
Edit: or is it possible (because I did not find anything about this Vercel error) that I messed up the git history?
Edit2: Watching the reflog it seems I make a rebase instead of merge ¿? from a local feature branch. Anyway it seems Vercel has not complained again and there is no problem now.

Non-paged document footnotes are processed into CSS Paged Media
footnotes to keep compatibility with non-paged LaTeX.css articles.
Transform the sidenotes from one or both margins into Paged Media
footnotes, depending on the the sidenotes style choosen:
`sidenotes-inner`, `sidenotes-outer` or none of them.
@vihuna
Copy link
Contributor Author

vihuna commented Feb 17, 2024

Some comments about CSS Paged Media footnotes implementation:

  • To be honest, I don't like this "low-level DOM manipulation" used to process the footnotes (needed to transform footnotes to CSS Paged Media footnotes, and specifically the cleanFootnoteText function); but it's necessary to keep the compatibility with LaTeX.css "continuous layout", until a stricter rule is imposed to write the footnotes. Also, I suppose a lot of improvements can be done (from regexp's, to footnote mark detection method,...), but this is my suggestion, at this moment.

  • Sometimes, when the footnote mark from some footnote it's close to the bottom of the page, it seems Paged.js does not correctly calculate the necessary space. This issue should be fixed manually forcing a page break before the footnote mark.

@vincentdoerig
Copy link
Owner

I appreciate the continuous effort and dedication you've shown, along with your patience on this PR. While I will not address each point individually, please know that I appreciate all the reasoned comments you've provided.

(Nov 23) I'm beginning to understand that you would like [if possible] an "out of the box" working (i.e., almost without user supervision). I think at this moment is far from possible, but some steps in this direction can be taken. The problem, and the reason because I choose the "all manual" way: I think it's more simple for the users to see the need for a page break at certain line/position in the document, instead of dealing with a page-break (introduced previously by LaTeX.css, not working properly for some reason, and users probably don't know how LaTeX.css inserts this breaks) that they must override and insert their custom one. Also, if you oversaturate the document with forced page-breaks and page-break-avoids, Paged.js may not work properly.

You are right, I appreciate your input and agree that creating a "plug-n-play" solution would go beyond the scope of this project. "All manual" should indeed be the way to go and we should mention this in the documentation that while it is almost straight-forward, it does require some work from the developer and should only be used on dynamic content with caution.

I was working in a more complex solution (with no success), finally I prefer to do a trick: I set the sidenotes height to 0 display: none; for sidenotes before the Paged.js chunker processes the pages; and I set the height to auto display: block; again, before Paged.js renders the pages.

Smart!


(Feb 24) Following the indications (and this make me sad), only Blink-based browsers will be really supported for the moment. Different fixes (or improvements) for other engines can be added later.

This is indeed unfortunate. Let's hope that these bugs get fixed and we will hopefully be able to support more browser engines in the future!

Also following indications about sidenotes, there will be only sidenotes in exactly one of the margins. Managing side notes it's not an easy task. For example, because sidenotes are floating elements, there will be a forced vertical gap (the height of the first of them) between the left and the right side notes. This is not really an issue for LaTeX.css "continuous layout" but it's important for "paged layout", where the side notes should fit into its own page. Also, by default, sidenotes are not going to be displayed.

Understood. From a print perspective this limitation isn't too bad since it's usually better to keep things consistent on one side (except maybe for two-sided books but don't get me started with that haha). What was your reasoning for sidenotes not being displayed by default?
Regarding the naming of sidenotes-{inner, outer}, I know this is because of the page terminology, but don't you think it would be less confusing to use left/right respectively instead if we don't support two-page layouts anyways (or keep both and use as alias)?

To keep compatibility with default "continuous layout", sidenotes from one of the margins will be transformed to footnotes. Also, a more different markers should be used, to avoid confusing sidenotes with footnotes.

This is a fair tradeoff but we should not make it too confusing. Creating (regular) sidenotes with a symbol instead of a number is not possible anymore, am I seeing this right?

I think specific version of Paged.js should be loaded.

I agree that this makes a lot of sense. (Versioning in the project in general is also something that has been on my mind for a while now...)

So, because @media print will continue to be used, Paged.js has limited support for media queries, and because it seems also contrary to Paged.js design (remember the previous quote from docs), I have decided that latex-dark and latex-dark-auto classes are not going to be supported in paged LaTeX.css.

I appreciate you exploring the feasibility. I am totally fine with it "only" working in light mode.

That means that a configuration like this will work properly [...] At this moment, I don't know the best solution to avoid that limitation (load Paged.js dynamically?, import it [the Previewer] as a module? ...), so the loading method will stay like this.

The documentation you wrote seems to make it clear enough, no?

I have never used Vercel, but I suppose that it does some trick with the repo URL for the deployment of PR branches, what fails after you change package.json.

I also don't know what that was about, but as you mentioned it seems to be working again.

To be honest, I don't like this "low-level DOM manipulation" used to process the footnotes (needed to transform footnotes to CSS Paged Media footnotes [...] I suppose a lot of improvements can be done (from regexp's, to footnote mark detection method,...), but this is my suggestion, at this moment.

Seems to work great with the few examples I have tried:).

Sometimes, when the footnote mark from some footnote it's close to the bottom of the page, it seems Paged.js does not correctly calculate the necessary space. This issue should be fixed manually forcing a page break before the footnote mark.

Since we both agree that this is not supposed to be an automatic solution, I believe it's acceptable to let the developer handle it.


I'm still having some issues with page breaks (??). In your current version (32f1090), I am only seeing 13 out of the 14 total pages on Chrome (120.0.6099.234). I think it has to do with the indentation of parts of the pre block .
This is the last page I currently see:
image
This issue appears to be extremely weird and specific. Interestingly, if I remove a single line (except for the final curly bracket or the last three dots), it reveals all 14 pages. Alternatively, removing the indentation of the @page { block also seems to address the problem. Furthermore, simply adding an extra line appears to resolve it, as well...
image
I came to the conclusion that prism is messing with the code blocks (if I remove the prism script, all 14 pages render correctly). When keeping prism, the offending CSS code seems to be style-paged.css L248 where deleting the overflow: visible; property seems to fix the issue at the cost of putting the entire block (and any other code block spanning more than one page) on the following page:
image
This however completely brakes blocks of code that span more than one full page (they disappear completely with leaving a blank page). My conclusion is that we need to figure out what prism does to the code blocks (I tried a few things and made adjustments to the white space, but it didn't lead to any progress)...
Let me know if you have a guess what the root issue could be (or if you even have this error!?).


Regarding the documentation, here are my two cents to what we need:

  • Add a section about the printable design to the main page
    • I think we need to work a bit on the "marketing" of this feature. "Printable design" might not be the best word for it, maybe something like "Design for print", "LaTeX.css to PDF" or "Print-friendly documents"? All suggestions, happy to hear yours.
    • Similar to the "Language Support", it would make sense to link to the separate "paged" documentation page
  • Instead of having the documentation inside /index-paged, I would create one page with the documentation only and one example page (basically a stripped-down version of index-paged with only the relevant subsections). We might also consider adding a toggle for selecting between print layout and continuous layout, though this is not too important.
    • Add a banner on top of the paged site for non-Blink browsers that some content may not be displayed correctly (and exporting to pdf will break things like navigation)

Feel free to implement things differently or we can discuss them here. I'd be happy to review again (and it shouldn't take this long anymore). Thank you!

@vihuna
Copy link
Contributor Author

vihuna commented Feb 20, 2024

Thanks, I appreciate all your comments and indications. I will read and comment them carefully later.

I'm only going to comment now the "last page missing" issue. I THINK (because I'm not able to reproduce it,
this is what I get whit any version of Chromium, more about this later) that what happens is a combination of issues that I was already aware (I don't know if they are interrelated). Sorry for not commenting about this earlier, but at some point I decided go ahead so this PR can be finished some day.

Prism+Paged.js combination results in loos of some new line characters ("\n"), when Paged.js breaks the code block while pagination (with the rest of the document displayed correctly until the last page). I was aware about this issue while working on d2d2336 (this is one of the "individual issues" that took me the longest). In my opinion, Paged.js is responsible of this behaviour, because I verified that all newlines were there after the Prism processing, but I don't know how exactly happens. I have this link from Paged.js repo in my notes:

https://gitlab.coko.foundation/pagedjs/pagedjs/-/blob/main/src/modules/filters/whitespace.js?ref_type=heads#L47

Of course, Prism makes the HTML code more complicated, so makes Paged.js more likely to fail. I also have annotated this link from Prism repo (about "deleted newlines"):

PrismJS/prism#1764

And I was "playing" with this code to patch this issue (I also have annotated that Prism removes the <br />):

    const preEl = document.getElementById("pre-id");
    preEl.innerHTML = preEl.innerHTML.replaceAll(/\n/g, "--newline--");


    Prism.hooks.add('after-highlight', function (env)
      {
        env.element.innerHTML = env.element.innerHTML.replaceAll(/--newline--/g, '<br />');
        env.code = env.element.textContent;
      });

As I already have said before, I decided to leave this issue for later.

Sometimes, Paged.js miscalculates the remaining space in the current page while paginating, so there is some overflowing content not displayed. Apparently, Paged.js has eaten some lines, but it's all there. I have not thought anything about that.

And sometimes happens that Paged.js ends the document rendering prematurely, at the bottom of some page. In fact, it's similar to the previous case, where now Paged.js does not beak the pages anymore: the rest of the document is there, but it doesn't fit the page. I have verified that Paged.js fails to calculate the breakToken so remains undefined and it believes it has reached the end of the document. I was thinking about using Paged.js Handlers to try to make "another complementary check" and change the breakToken if required, but I didn't go so far.

The only solution at this moment for this errors is a manual break-<before/after>: always; (still not committed the "break classes"), before the problematic HTML element (or inside, after splitting it). I will comment further about the breaks in next days. I'll try also to reproduce the error you report.

Finally, the point I'm most interested in: why I don't have this error? Yes, I'm working with an older Chromium version (117.0.5938.149), but I have also tested the latest available in Debian (121.0.6167.160-1~deb12u1) with the same result. I think this is because the "still non-fixed" relative units and also the font used for the preformatted text (I was awaiting until you had some time to comment about this). We should provide a Monospace font, verify the computed fonts, and throw a warning (popup?) if finally uses a fallback font, because the document will not be rendered like the author designed it, in this case. Tell me how we are going to do this (remote web font, or add another font to the repo ... and I just remembered that is style.min.css ~ 3MB because of fonts).

And this also brings to my mind that there is some symbols (end-of-proof, e.g.) not provided by LaTeX.css fonts. I was planning some time ago a PR to add MathML support (because since 10-01-2023 Chrome has MathML-Core support), adding also all the needed symbol fonts.

@vihuna
Copy link
Contributor Author

vihuna commented Feb 23, 2024

«Last page missing» issue updates:

I have been testing the page breaks inside pre elements. And the issue you commented can be reproduced easily.

I have finally come to the conclusion that the "problem" is effectively originated from the CSS code overflow: visible;, as you had shown in your previous comment. This is probably the trigger that finally makes Paged.js fail, but I don't know how this error is internally generated (as I will immediately comment, I get also the same wrong size with Paged.js handlers ¿?). The problem does not happen without this CSS rule, because this way Paged.js does not split the code blocks.

It seems the problem for the pre element comes immediately after the layout is applied. I turns out that el.getBoundingClientRect().height and el.offsetHeight give different values for the same element, and the first of them has the same height as the pagedjs_page area (the paged without the margins). It has some sense (not much) that this happens because of the overflow CSS property and these dimension properties/methods can differ depending on the scroll design, but I can't determine the specific issue: if I take the same HTML code (after been parsed by Prism), paste it to the HTML file, and make the same calculations (outside Paged.js), the values are quite similar. Can this, at this point, be considered a Paged.js bug? But it's also possible that Page.js gets finally confused because the so many spans that Prism adds inside code fragments, or both of them (I'm not able to get the same error with raw code fragments).

What appears to happen next is the same process as when some indivisible element does not fit the page: Paged.js would be trying to assign a breakToken element, finalizing gratefully ("using their own words") after several failed attempts (the breakToken remains undefined).

I have also some doubts, while Paged.js is immersed in this process: the overflow hook is triggered several times, but at the same time the actual returned overflow remains undefined. Is this normal? (if there is not breakToken defined => there is no overflow defined?).

And, after all this, I have more questions: why are there no similar problems with the MathJax processed lines? (also with a lot of span elements). With respect to CSS, what also avoids the issue with code blocks is to change the white-space property to normal (but changing the \n with <br /> elements, so it's very difficult to be sure that this CSS changes cause the fix, because a simple change of one brace with a square bracket also fixes the error, for example). And also works with white-space: pre-line, so we can say the problem arises from the conjunction Paged.js + complex-HTML + CSS-white-spaces.

This is finally not very explanatory, but I think it's enough to "blame" Paged.js for the issue. We have some options to deal with it:

  • Remove the overflow: visible. This way we kill two birds with one stone: the "last page missing" error is fixed, and also the other one with the blank lines removed; but at the cost of losing the automatic code fragments splitting (the "white lines removed" issue happens when a pre element is split). The user is responsible for making the needed manual splits if the code fragment does not fit in the page.

  • Keep the overflow: visible as default, and the user is in charge of doing the needed splits if some error happens. A CSS class can also be provided to avoid the default behaviour for code fragments.

  • Keep the overflow: visible and try to fix it automatically if there is any clue that some problem is happening, and finally the developer is in charge of doing the splits if the automatic method fails. In this case we must find some malfunction sign: for example I have already verified that the disparity between el.getBoundingClientRect().height and el.offsetHeight is NOT a sufficient condition to get the error.

Update(24-03-2024):
I have been doing more tests with this issue (and also the page breaks inside the ToC, it has taken me longer than I expected, this things drain my energy).

I'm now pretty sure Paged.js is causing this error, but I don't know the internal Paged.js issues (I don't want to comment more about this, but as final result, Paged.js fails to add the breakToken). I have made some attempt to solve this issue: it's like when you smack an old CRT to get it working. Of course there is always the manual "CSS page break" solution. What worries me most right now are the differences we get when we visualize the document. I hope this will be fixed when all relative units be replaced.

About unit testing: I'm familiar with jest+jsdom, but it's probably not very useful to test this issues with page breaks. Maybe e2e testing could be more useful¿? Until something is done about tests, some of this "manual examples" could be added to the repo.

- `break-before-avoid`, `break-inside-avoid`, `break-after-avoid` to
  avoid breaks,
- `break-before-page`, `break-after-page` to force breaks.
So it does not try to remove later what it doesn't exists
@vihuna
Copy link
Contributor Author

vihuna commented Mar 24, 2024

What was your reasoning for sidenotes not being displayed by default?

Because hyphenation was disabled, I increased "a little" the sidenotes width. So if you are not going to use any sidenote you'll probably want to decrease the margin width. The margins for no sidenotes are more natural. We can try to find a more balanced solution.

Regarding the naming of sidenotes-{inner, outer}, I know this is because of the page terminology, but don't you think it would be less confusing to use left/right respectively instead if we don't support two-page layouts anyways (or keep both and use as alias)?

OK, I also didn't like it while I was writing it, it's confusing , I didn't want to close the door to some possible features.

This is a fair tradeoff but we should not make it too confusing. Creating (regular) sidenotes with a symbol instead of a number is not possible anymore, am I seeing this right?

There are two (or three) questions here, I'm not sure if it's clear.

  • Answering your question: in the source document you can still use any symbol, but when the footnotes are transformed to CSS Paged footnotes, all footnotes are numbered. I suppose is possible to add a new feature for some special symbol-footnotes (let me know if this is important to you).
  • Because all footnotes are numbered after the processing, you can have a "1" mark for a footnote, and "1" for a sidenote in the same page, so you can not distinguish them. It will be convenient to use other counter style (roman, ...).
  • The sidenotes on the unused margin are transformed to footnotes to avoid losing document content. I think it's more confusing if you see the notes disappear.

The documentation you wrote seems to make it clear enough, no?

I'm not sure it's clear enough. I must check again the loading method (after the "module" changes) and its documentation.

Regarding the documentation:

"Printable design" might not be the best word

Sure. I already was aware about this, I changed it for "paged layout" in commit 965364d. I Like both "LaTeX.css to PDF" and "Print-friendly documents".

We might also consider adding a toggle for selecting between print layout and continuous layout, though this is not too important.

This will be cool, but could have some work.

Add a banner on top of the paged site for non-Blink browsers that some content may not be displayed correctly (and exporting to pdf will break things like navigation)

I thought also about this. The easiest method is to add an alert after Paged.js has finished. There shouldn't be also any problem if we add a dialog before pagedjs_pages.

- Add top warning banner for non-Blink based browsers
- The banner is added after Paged.js processing
- Use a base font size in absolute units
- Add Libertinus Mono and Latin Modern Mono for code snippets
- Switch off assistive MathML
- Replace unsupported symbols:
  - U+2003 (EM SPACE) -> U+00A0 (NO-BREAK SPACE)
  - U+21A9 (LEFTWARDS ARROW WITH HOOK) -> U+005E (CIRCUMFLEX ACCENT)
  - U+25FE (BLACK MEDIUM SMALL SQUARE) -> `q.e.d` or U+2016 (DOUBLE
    VERTICAL LINE)
Adjust some document font sizes for CSS styles `.font-size-10`
and `.font-size-12`.
@vihuna
Copy link
Contributor Author

vihuna commented Apr 8, 2024

Banner and consistent rendering

To allow consistent rendering across different platforms/environments, I have added the Mono fonts for Latin Modern and Libertinus. I have used the same versions of the fonts: v2.004 (2009) for Latin Modern and v7.020 (2020) for Libertinus. Some notes about Latin Modern (only otf format available):

-> From "otf" to "ttf"

Command:

 fontforge -lang=ff -c 'Open($1); Generate($2); Close();' LMMono-regular.otf LMMono-regular.ttf

Output:

Copyright (c) 2000-2023. See AUTHORS for Contributors.
 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
 with many parts BSD <http://fontforge.org/license.html>. Please read LICENSE.
 Version: 20230101
 Based on sources from 2023-01-18 18:05 UTC-ML-D-GDK3.
PythonUI_Init()
copyUIMethodsToBaseTable()
Program root: /usr
Warning: Mac and Windows entries in the 'name' table differ for the
  Family string in the language English (US)
  Mac String: Latin Modern Mono
  Windows String: LM Mono 10
Warning: Mac and Windows entries in the 'name' table differ for the
  Styles (SubFamily) string in the language English (US)
  Mac String: 10 Regular
  Windows String: Regular
Warning: Mac and Windows entries in the 'name' table differ for the
  Fullname string in the language English (US)
  Mac String: Latin Modern Mono 10 Regular
  Windows String: LMMono10-Regular
The glyph named Delta is mapped to U+0394.
  But its name indicates it should be mapped to U+2206.
The glyph named Omega is mapped to U+03A9.
  But its name indicates it should be mapped to U+2126.
The glyph named dotlessj is mapped to U+F6BE.
  But its name indicates it should be mapped to U+0237.

-> From "otf" to "woff2"

Command:

woff2_compress LMMono-regular.otf

Output:

Processing LMMono-regular.otf => LMMono-regular.woff2
Compressed 64483 to 39838.

-> From "otf" to "woff"

Command:

sfnt2woff LMMono-regular.otf

Output:
[empty]

About the banner, finally I have realized (too late and by accident) that adding the banner after Paged.js has finalized (just like I have done it) is not a great idea: some elements can delay the rendering (like lazy loading fonts) and the banner appears after some seconds. Also some simple web browsers don't support some javascript functions used in Paged.js and you can get a blank page without any warning. Adding the banner before Paged.js will be a better option, if possible. Despite this, I decided to commit this changes, although I didn't finished the banner completely (I was going to allow multiple banners in the same modal box, and close all together), to be able to move forward.

@vihuna
Copy link
Contributor Author

vihuna commented Apr 8, 2024

I have been doing some tests for the "consistent rendering" across different platforms/OS/DE, and I must say that it seems an utopia.

  • First the most serious for me: using the same OS+DE I get quite different results from Chome 117 and Chrome 120 !!
  • With different browsers with the same Blink version engine I get the same results in Windows and also the same results in Linux, but those from Linux are different from the Window ones.
  • I'm going to attach two files using the revision bf7c2e6, one from Linux and the other from Windows, both using the same Brave version (Brave-1.64.116, Chrome:123.0.6312.105). On page 10 Paged.js decides to make breaks at different points:
    Debian11-Brave-1.64.116 (123.0.6312.105).pdf
    windows-brave-1.64.116 (123.0.6312.105).pdf

I have tried to solve similar issues in EPUB documents with poor results (from reader internal font-smooth options, to CSS font-kerning, text-rendering ...).

For the moment, these results recommend to limit the use of Paged.js to local/personal environments but not to use it in a public web server. Tell me your opinion.

@vihuna
Copy link
Contributor Author

vihuna commented Apr 10, 2024

Making a recap about the state of this PR

Mi initial idea was: if Paged.js is quite solid with a LaTeX.css document, with this new feature you could (hit two birds with the same stone):

  • at developer/author level: print your LaTeX.css documents and serve your documents in a fancy "paged" presentation;
  • at user level: easy print documents served by a developer.

And, also important, implementing all this new feature "in/using the web browser".

I also wanted to show all problems that I was finding along the way while exploring the possibilities, and I've tried to be cautious about the expectations (someone will say that I am always very pessimistic).

But Paged.js is sincerely too much unstable, specially for technical/complex documents like those using LaTeX.css (with quite a few LaTeX+MathJax formulas, code blocks ...); and because the inconsistency across platforms, you have zero confidence that your document is going to be displayed correctly in a third-party browser. (I was hoping that since it was the same application, Chrome, those font-rendering inconsistencies would be quite unusual, or, better said, would rarely affect pagination).
And on the other hand, I don't think Paged.js is going to solve all these problems in the short term.

So, probably, "you are only going to use this feature at a developer/author level, to print the document to PDF". Well, I think there are quite better options to do this task (via conversion to LaTeX first), taking into account all that Paged.js issues I have found.

So to be honest (and realistic), at this point I'm not convinced with this PR, and the "exploration days" end here: I already know enough about limitations across platforms and Paged.js instability; and things like "font-kerning consistency" are a red line for me (I have suffered similar issues in the past, and I decided: "never again"). I have explored all the possibilities, and honestly, I don't like any of them.

So, @vincentdoerig,if you still want to merge it, I can finalize the remaining most essential tasks. But I repeat my point of view: if "you are only going to use this feature to print the document to a PDF file", there are much better options to explore (even if you have to install some package in your OS).

Sorry if this is a disappointment for you, but I need to be honest (regardless of the time spent on this PR); tell me your thoughts @vincentdoerig.

@vincentdoerig
Copy link
Owner

Thanks a lot for all your contributions and devotion to this PR @vihuna. I truly appreciate your thorough exploration and the various approaches you took to tackle the task of making the document printable.

Ultimately, I will leave the decision of whether to close the PR up to you. I understand the significant effort you have invested in this PR, and it is disappointing that we have not achieved a fully functional product. Nevertheless, I believe this experience has been valuable for you (and it certainly has been for me too!).

Should you wish for me to review anything, I am more than happy to do so, but please feel no obligation, and I completely understand if you prefer to bring this to a close once and for all:).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants