Giter VIP home page Giter VIP logo

pdf's Introduction

pdf's People

Contributors

ashok-khanna avatar dorianmariecom avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pdf's Issues

Alignment of dots in ToC is irregular

Small nitpick: The horizontal alignment of the dots in the Table of Content is off. Not sure if there is a way to fix this in CSS, and many people won't notice anyway. Still a great repo. Thanks!

Screenshot 2021-04-05 at 12 18 33

Website pdf.math.dev doesn't work

In the console we can find some issues

Uncaught (in promise) DOMException: Failed to execute 'querySelectorAll' on 'DocumentFragment': '</pre></code>
<h3>Page Breaks</h3>
<p>By default' is not a valid selector.
    at Breaks.processBreaks (https://pdf.math.dev/paged.polyfill.js:28816:27)
    at Breaks.afterParsed (https://pdf.math.dev/paged.polyfill.js:28810:9)
    at https://pdf.math.dev/paged.polyfill.js:364:26
    at Array.forEach (<anonymous>)
    at Hook.trigger (https://pdf.math.dev/paged.polyfill.js:363:15)
    at Chunker.flow (https://pdf.math.dev/paged.polyfill.js:2583:33)
    at async Previewer.preview (https://pdf.math.dev/paged.polyfill.js:31035:15)
    at async https://pdf.math.dev/paged.polyfill.js:31096:11

Blank pages before table of contents if the TOC is longer than 1 page

Introduction

Hi, I hope you are doing well. I tried to use your code using MacOS Sonoma

I have this HTML:

HTML
<html>
  <head>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href="https://fonts.googleapis.com/css2?family=Nunito:wght@100;300;400;500;700&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" type="text/css" href="../style.css" />
    <script src="../toc.js"></script>
    <script src="../paged.polyfill.js"></script>

    <script>
      class handlers extends Paged.Handler { constructor(chunker, polisher,
      caller) { super(chunker, polisher, caller); } beforeParsed(content) {
      createToc({ content: content, tocElement: "#toc", titleElements:
      ["h2:not(.cover-header)", "h3:not(.cover-header)"], }); } }
      Paged.registerHandlers(handlers);
    </script>
  </head>

  <body>
    <!-- 1.0 Cover Page -->
    <div class="cover-page">
      <h1>Standard Operation Procedures</h1>
      <h3 class="cover-header no-counter">Hosted PBX</h3>
      <h3 class="cover-header no-counter">{{time}}</h3>
      <img src="../0.svg" />
      <img src="../1.png" />
    </div>

    <!-- 2.0 Table of Contents -->
    <div class="table-of-contents">
      <h1 class="toc-header" id="toc-start">Table of Contents</h1>
      <ol id="toc">
        <!-- toc.js will automatically insert TOC here -->
      </ol>
    </div>

    ...rest
  </body>
</html>

The script for generating TOC:

Script
/**
 * Create a table of contents (TOC) based on the title elements within a specified content.
 *
 * @param {Object} config - Configuration object for the function.
 * @param {Element} config.content - The root element where the TOC will be generated from.
 * @param {string} config.tocElement - A CSS selector that specifies the element where the TOC will be appended.
 * @param {Array} config.titleElements - An array of CSS selectors indicating title elements.
 */
function createToc(config) {
  // Destructure the configuration object for easier access
  const { content, tocElement, titleElements } = config;

  // Locate the container where the TOC will be appended
  let tocElementDiv = content.querySelector(tocElement);

  // Create a new unordered list to house the TOC
  let tocUl = document.createElement("ul");
  tocUl.id = "list-toc-generated"; // Give it an ID for potential styling or scripting
  tocElementDiv.appendChild(tocUl); // Append the list to the container

  // Counter to generate unique IDs for title elements (if needed)
  let tocElementNbr = 0;

  // Loop over each title element selector
  for (var i = 0; i < titleElements.length; i++) {
    // Calculate the title hierarchy based on its position in the titleElements array
    let titleHierarchy = i + 1;

    // Select all elements in the content that match the current title selector
    let titleElement = content.querySelectorAll(titleElements[i]);

    titleElement.forEach(function (element) {
      // Add a generic class and data attribute to indicate its hierarchy
      element.classList.add("title-element");
      element.setAttribute("data-title-level", titleHierarchy);

      // If the element doesn't have an ID, create one
      tocElementNbr++;
      idElement = element.id;
      if (idElement == "") {
        element.id = "title-element-" + tocElementNbr;
      }
    });
  }

  // Select all title elements we previously modified
  let tocElements = content.querySelectorAll(".title-element");

  // Loop over each title element to create corresponding TOC list items
  for (var i = 0; i < tocElements.length; i++) {
    let tocElement = tocElements[i];

    // Create a new list item for the TOC
    let tocNewLi = document.createElement("li");

    // Add generic and hierarchy-specific classes
    tocNewLi.classList.add("toc-element");
    tocNewLi.classList.add(
      "toc-element-level-" + tocElement.dataset.titleLevel,
    );

    // Copy over other classes from the original title element (excluding the generic title-element class)
    let classTocElement = tocElement.classList;
    for (var n = 0; n < classTocElement.length; n++) {
      if (classTocElement[n] != "title-element") {
        tocNewLi.classList.add(classTocElement[n]);
      }
    }

    // Set the inner content of the list item to be a link to the original title element
    tocNewLi.innerHTML =
      '<a href="#' + tocElement.id + '">' + tocElement.innerHTML + "</a>";

    // Append the new list item to the TOC list
    tocUl.appendChild(tocNewLi);
  }
}

The CSS:

CSS
/* - * - * - * - * - * - * - * - * - * - */
/* 1.0 CSS to make A4 print preview as default web view */

@media screen {
  .pagedjs_pages {
    display: flex;
    width: calc(var(--pagedjs-width));
    flex: 0;
    flex-wrap: wrap;
    margin: 0 auto;
    justify-content: center;
  }

  .pagedjs_page {
    margin: 10mm;
    border: solid 1px gray;
  }
}

/* - * - * - * - * - * - * - * - * - * - */
/* 2.0 General Formatting */
html {
  font-family: "Nunito", sans-serif;
  height: auto;
}
h1 {
  border-bottom: 1px solid black;
  margin-bottom: 2rem;
  padding-bottom: 1rem;
}
h2 {
  border-bottom: 0.1875rem solid black;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
}
p {
  text-align: justify;
  line-height: 1.4rem;
}
a {
  color: #347dbd;
}
a:hover {
  color: #fc814a;
}
mark {
  color: purple;
  background-color: inherit;
}
light-mark {
  color: purple;
}
img {
  max-width: calc(100% - 3rem);
}
.img-75mm {
  height: 75mm;
}

center {
  border: 0.5px solid gray;
  padding: 1.5rem;
}

pre {
  background-color: #f0f0f0;
  font-family: "Custom Mono", monospace;
  padding: 1rem;
  font-size: smaller;
  white-space: pre-wrap;
}
code {
  margin-bottom: 1.5rem;
  display: block;
}
figure {
  margin-block-start: 2rem;
  margin-block-end: 2rem;
  margin-inline-start: 0rem;
  margin-inline-end: 0rem;
}
figcaption {
  caption-side: top;
  padding-bottom: 0.75rem;
  border-bottom: 0.5px solid gray;
  margin-bottom: 1.5rem;
  color: gray;
  font-weight: bold;
}

/* - * - * - * - * - * - * - * - * - * - */
/* 3.1 Page Size */
@page {
  size: A4;
}

/* 3.2 Page Breaks */
.page-break {
  break-after: page;
}
h2:not(.no-break) {
  break-before: page;
  margin-block-start: 0rem;
  margin-block-end: 1.66rem;
}
h2.no-break:not(.top) {
  margin-block-start: 3rem;
  margin-block-end: 1.66rem;
}
h2.top {
  margin-block-start: 0rem;
  margin-block-end: 1.66rem;
}

h3:not(.top) {
  margin-block-start: 2.49rem;
  margin-block-end: 0.83rem;
}
h3.top {
  margin-block-start: 1.66rem;
  margin-block-end: 0.83rem;
}

/* 3.3 Page Numbers */
@page {
  @bottom-right {
    content: counter(page);
  }
}

/* We use the counter-reset class to prevent the page
numbers starting from the cover page, but rather
from the next page (table of contents) */
.counter-reset {
  counter-reset: page 1;
}

/* - * - * - * - * - * - * - * - * - * - */
/* 5.1 Table of Contents */
.table-of-contents {
  page: table-of-contents;
}
@page table-of-contents {
  @top-right {
    content: none;
  }
  @bottom-left {
    content: none;
  }
}

/* Additional CSS: Advanced Styling for TOC */
.toc-header {
  margin-bottom: 1rem;
  border-bottom: 0.375rem solid black;
}
.table-of-contents a,
.table-of-contents a:hover {
  font-family: "Nunito", sans-serif;
}

ol,
ul {
  padding-inline-start: 0px;
}

ol,
ul a {
  text-decoration: none;
}

.toc-element-level-1 a,
.toc-element-level-2 a {
  color: black;
}

/* set the style for the list numbering to none */
#list-toc-generated {
  list-style: none;
}

#list-toc-generated .toc-element a::after {
  content: target-counter(attr(href), page);
  float: right;
}

#list-toc-generated .toc-element-level-1 {
  border-bottom: 0.0625rem solid black;
  margin-top: 2rem;
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  font-weight: bold;
}

/* counters */

#list-toc-generated {
  counter-reset: counterTocLevel1;
}

#list-toc-generated .toc-element-level-1 {
  counter-increment: counterTocLevel1;
  counter-reset: counterTocLevel2;
}

#list-toc-generated .toc-element-level-1::before {
  content: counter(counterTocLevel1) ". ";
  padding-right: 5px;
}

#list-toc-generated .toc-element-level-2 {
  counter-increment: counterTocLevel2;
  margin-bottom: 0.5rem;
}

#list-toc-generated .toc-element-level-2::before {
  content: counter(counterTocLevel1) "." counter(counterTocLevel2) " ";
  padding-right: 5px;
}

/* hack for leaders */

#list-toc-generated {
  overflow-x: hidden;
}

/* fake leading */
#list-toc-generated .toc-element-level-2::after {
  content: ".............................................."
    ".............................................."
    ".............................................." "........";
  float: left;
  width: 0;
  padding-left: 5px;
  letter-spacing: 2px;
}

#list-toc-generated .toc-element {
  display: flex;
}

#list-toc-generated .toc-element a::after {
  position: absolute;
  right: 0;
  background-color: white;
  padding-left: 6px;
}

#list-toc-generated .toc-element a {
  right: 0;
}

The Problem

Everything went well if I generate a table of contents worth 1 page:
image

But if there is more than 1 page, I got two blank pages then the full TOC:
image

As you can see, the 3.15 is missing. It is on page 64. You can see that there are number 64 in page 4, which means it renders the page number but not the link.

Any ideas what went wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.