patx/makeitpdf

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MakeItPDF</title>
<meta name="description" content="Combine PDFs, images, Word, Excel, Markdown, and CSV files into one PDF, entirely in your browser.">
<link rel="stylesheet" href="style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><rect width='32' height='32' rx='9' fill='%23f4402d'/><rect x='7.5' y='5' width='11' height='15' rx='2.4' fill='%23fff' opacity='.5'/><rect x='13.5' y='11' width='11' height='15' rx='2.4' fill='%23fff' stroke='%23f4402d' stroke-width='2.2'/></svg>">
</head>
<body>

<div class="progress" id="progress" aria-hidden="true"></div>

<main class="page">
  <div class="intro">
    <h1 class="logo">
      <!-- Two sheets becoming one. The front sheet is stroked in the accent so
           the gap between them reads even at favicon size. -->
      <svg class="logo__mark" viewBox="0 0 32 32" aria-hidden="true">
        <rect width="32" height="32" rx="9" fill="currentColor"/>
        <rect x="7.5" y="5" width="11" height="15" rx="2.4" fill="#fff" opacity=".5"/>
        <rect x="13.5" y="11" width="11" height="15" rx="2.4" fill="#fff"
              stroke="currentColor" stroke-width="2.2"/>
      </svg>
      <span class="logo__text">MakeIt<span class="logo__accent">PDF</span></span>
    </h1>
    <p class="intro__sub">Combine PDFs, images, Word, Excel, Markdown, and CSV
      files into one PDF. Nothing leaves your device.</p>
  </div>

  <noscript>
    <p class="alert">This tool builds the PDF in your browser, so it needs
      JavaScript switched on.</p>
  </noscript>

  <!-- The limits live here so app.js and the visible text can't drift apart. -->
  <form class="composer" id="composer" data-max-files="10" data-max-file-bytes="26214400">

    <input class="picker" id="picker" type="file" multiple
           accept=".pdf,.jpg,.jpeg,.png,.webp,.gif,.bmp,.tif,.tiff,.docx,.xlsx,.md,.markdown,.csv">

    <div class="dropzone" id="dropzone">
      <div class="format-spine" aria-hidden="true">
        <span>PDF</span><span>IMG</span><span>DOCX</span><span>XLSX</span><span>MD</span><span>CSV</span>
      </div>
      <label class="btn btn--accent btn--lg" for="picker">Select files</label>
      <p class="dropzone__hint">or drop them here</p>
      <p class="dropzone__formats" id="formats"></p>
    </div>

    <section class="tray" id="tray" hidden>
      <div class="tray__head">
        <h2 class="tray__count" id="tray-count">0 files</h2>
        <button class="link" id="clear" type="button">Clear all</button>
      </div>
      <ol class="grid" id="sheets"></ol>
    </section>

    <button class="btn btn--accent btn--block" id="build" type="submit" aria-live="polite" hidden>Convert to PDF</button>
  </form>

  <section class="done" id="done" hidden>
    <svg class="done__tick" viewBox="0 0 48 48" aria-hidden="true">
      <circle cx="24" cy="24" r="23" fill="none" stroke="currentColor" stroke-width="2"/>
      <path d="M15 24.5l6.5 6.5L33 18" fill="none" stroke="currentColor"
            stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
    </svg>
    <h2 class="done__title">Your PDF is ready</h2>
    <p class="done__meta" id="done-meta"></p>
    <p class="done__notes" id="done-notes" hidden></p>
    <a class="btn btn--accent btn--lg" id="download" download>Download PDF</a>
    <button class="link" id="restart" type="button">Convert more files</button>
  </section>

  <p class="footnote">Your files are never uploaded. The PDF is built on this
    device and stays here.</p>
</main>

<template id="sheet-template">
  <li class="card" draggable="true">
    <span class="card__frame">
      <img class="card__img" alt="">
      <span class="card__paper" aria-hidden="true"><span class="card__type"></span></span>
      <span class="card__num"></span>
      <button class="card__remove" type="button">
        <svg viewBox="0 0 16 16" aria-hidden="true">
          <path d="M4.5 4.5l7 7M11.5 4.5l-7 7" stroke="currentColor"
                stroke-width="1.75" stroke-linecap="round" fill="none"/>
        </svg>
        <span class="visually-hidden">Remove</span>
      </button>
      <span class="card__move">
        <button class="card__arrow card__arrow--up" type="button">
          <svg viewBox="0 0 16 16" aria-hidden="true"><path d="M10 3.5L5.5 8l4.5 4.5"
               stroke="currentColor" stroke-width="1.75" stroke-linecap="round"
               stroke-linejoin="round" fill="none"/></svg>
          <span class="visually-hidden">Move earlier</span>
        </button>
        <button class="card__arrow card__arrow--down" type="button">
          <svg viewBox="0 0 16 16" aria-hidden="true"><path d="M6 3.5L10.5 8 6 12.5"
               stroke="currentColor" stroke-width="1.75" stroke-linecap="round"
               stroke-linejoin="round" fill="none"/></svg>
          <span class="visually-hidden">Move later</span>
        </button>
      </span>
    </span>
    <span class="card__name"></span>
    <span class="card__meta"></span>
  </li>
</template>

<script src="vendor/pdfkit.standalone.js"></script>
<script src="vendor/blob-stream.js"></script>
<script src="vendor/pdf-lib.min.js"></script>
<script src="vendor/bidi.min.js"></script>
<script src="vendor/markdown-it.min.js"></script>
<!-- pako must load before UTIF so deflate-compressed TIFFs work. -->
<script src="vendor/pako_inflate.min.js"></script>
<script src="vendor/UTIF.js"></script>
<script src="pages.js"></script>
<script src="documents.js"></script>
<script src="pdf-builder.js"></script>
<script src="app.js"></script>
</body>
</html>