:sparkles: PWA :sparkles:
Twarz autora bloga

Piotr Kowalski

Organizator WarsawJS Trener YouTuber

Jak zbudować plik PDF na podstawie pliku tekstowego w formacie Markdown?

Chciałbym w tym artykule przedstawić Ci w jaki sposób przetworzyć plik w formacie Markdown do formatu PDF. Wykorzystamy do tego paczkę w npm markdown-pdf, która wykona za nas “czarną robotę”.

Co jest “Markdown”?

Markdown to sposób formatowania pliku tekstowego. Każdy tekst, czy to notatka, czy książka, jest w jakiś sposób “sformatowana” (ułożona).

Oficjalne logo. Zródło: https://pl.wikipedia.org/wiki/Markdown

Można zdefiniować kilka typów wyróżnień tekstu:

  • nagłówek
  • paragraf
  • link
  • pogrubiony tekst
  • kod źródłowy
  • itd.

Za pomocą składni Markdown-a zdefiniowanie powyższych (jak i innych) wyróżnień jest bardzo proste i intuicyjne. Przykład:

  • ## To jest nagłówek - nagłówek
  • Dowolny ciąg literek - paragraf
  • [tekst](http://example.org/) - link
  • to jest **pogrubiony** tekst - pogrubiony tekst
  • Definicja zmiennej "a": `let a = 2` - kod źródłowy (tryb: inline)

Obecnie jest to najpopularniejszy format do tworzenia dokumentacji tekstowej. Rozszerzenie plików w formacie Markdown to *.md. Więcej o składni możesz przeczytać tutaj.

Zalety

Przedstawię kilka zalet tego formatu:

  1. Notatki lub też inne dokumenty są szybciej przeze wytwarzane w sposób nadający się do prezentacji innym osobom, ze względu na zachowanie formatowania.
  2. Tworzenie artykułów nie jest uciążliwe. Przykładem niech będzie ten post, który stworzony jest w formacie Markdown. Pisanie w HTMLu wymuszało na mnie pisanie znaczników, które często były przeze mnie modyfikowane. Tym samym zabierało mi to czas, który mogłem poświęcić na części merytorycznej.

Wady

Nie znam żadnych wad. Dla mnie jest to format idealny :sparkles:

Krok po kroku

A teraz postaram się pokazać Ci co po kolei należy zrobić, aby móc szybko budować pliki PDF.

1. Instalacja narzędzia markdown-pdf

Zainstaluj narzędzie w projekcie, w którym chcesz budować pliki PDF na podstawie plików w formacie Markdown. Możesz to zrobić za pomocą polecenia:

Copy + paste

npm install --save-dev markdown-pdf

Chyba, że chcesz wykorzystywać narzędzie bez powiązania z konkretnym projektem, wtedy należy zainstalować narzędzie globalnie:

Copy + paste

npm install -g markdown-pdf

2. Stworzenie skryptu

// build.js
let markdownpdf = require('markdown-pdf');

const INPUT = 'path/to/file.md';
const OUTPUT = 'path/to/file.pdf';

markdownpdf()
    .concat.from.paths([INPUT])
    .to(OUTPUT, () => {
        console.log('Created', OUTPUT);
    });

3. Stworzenie pliku file.md

Teraz wystarczy stworzyć plik w formacie Markdown, aby móc go przekonwertować do PDF. Jeśli w projekcie istnieje plik README.md, to wystarczy zaktualizować ścieżkę do tego pliku w powyższym skrypcie.

4. Zbudowanie pliku PDF

Jeśli ścieżka do plików jest ustawiona poprawnie, to wystarczy wydać polecenie:

Copy + paste

node build.js

Co to jest “CLI”?

CLI, czyli Command Line Interface - jest to interfejs aplikacji, dzięki któremu możliwe jest uruchomienie programu za pomocą polecenia w konsoli.

Wbudowany CLI

Opisywane narzędzie posiada już wbudowany interfejs CLI.
Więcej informacji na ten temat znajdziesz w dokumentacji.

Własne CLI

Co jeśli chciałbyś sam stworzyć plik, który będzie działał nieco inaczej niż wbudowany CLI? Zbudujmy coś takiego!

Zbieramy wymagania

Chcielibyśmy napisać skrypt w taki sposób, aby móc mu przekazywać następujące parametry:

  • INPUT - ścieżka do pliku wejściowy w formacie Markdown
  • OUTPUT - ścieżka do pliku wyjściowego w formacie PDF

po to aby, móc uruchamiać skrypt budujący w następujący sposób:

Copy + paste

node build.js INPUT OUTPUT

Skrypt budujący

// build.js
let markdownpdf = require('markdown-pdf');

const INPUT = process.argv[2]; // ex. README.md
const OUTPUT = process.argv[3]; // ex. file.pdf

markdownpdf()
    .concat.from.paths([INPUT])
    .to(OUTPUT, () => {
        console.log('Created', OUTPUT);
    });

Customowe style - zmiana domyślnego wyglądu

Aby móc dodać swoją definicję wyglądu do wygenerowanego dokumentu PDF wystarczy zdefiniować odpowiednią właściwość w opcjach, według przykładu:

const OPTIONS = {
    cssPath: 'path/to/file.css'
};

markdownpdf(OPTIONS)
    ...

Jak wykorzystać CSS do ulepszenia wyglądu pliku PDF?

Poniżej lista selektorów, które ja proponuję wykorzystać, aby nadpisać domyślny wygląd wygenerowanego pliku PDF:

  • body - wygląd całego dokumentu, np. zmiana domyślnego fontu
  • h1, h2, h3, h4, h5, h6 - nagłówki.
  • a[href] - linki
  • strong - pogrubiony tekst
  • blockquote - cytowanie
  • code - kod źródłowy (jednolinijkowy)
  • pre code - kod źródłowy (wielolinijkowy)

Podczas wygenerowania dokumentu z osadzonym linkiem będziesz w stanie dostrzec, że linki są “podwojone”. Aby poradzić sobie z tym problem rekomenduję dodać do customowych styli następujący blok kodu:

a[href]:after {
    content: ""
}


Wskazówka #1: Zmiana domyślnego fontu

Jeśli chcesz w wygenerowanym dokumencie użyć innego niż domyślny font, proponuję wykorzystać funkcję @import (w CSS-ach):

@import url('https://fonts.googleapis.com/css?family=Lato');

Teraz w pliku ze stylami można śmiało używać:

font-family: "Lato", serif;


Wskazówka #2: Ustawienie pliku wykonywalnego

Obecnie skrypt jest uruchamiany następująco:

Copy + paste

node build.js INPUT OUTPUT

Co jeśli chcielibyśmy, uruchamiać skrypt w ten sposób:

Copy + paste

./build.js INPUT OUTPUT

Wystarczy wykonać 2 rzeczy:

  1. W pierwszej linijce pliku build.js dodać preambułę #/usr/bin/env node.

    UWAGA: Przed tą linijką nie może być innych znaków.

    Linijka ta, wymusza na powłoce (np. bash) wykorzystanie narzędzia node do uruchomienia pliku.

  2. Dodać uprawnienia do pliku chmod +x build.js.