Odkąd przemigrowałem z Wordpressa na Jekylla, to na mojej liście rzeczy do zrobienia był punkt dotyczący stworzenia skryptu, który pozwoliłby mi na tworzenie zalążków tekstów dzięki jednej komendy. Co prawda jest jekyll-compose, ale nie spełnia on moich wymagań. Jest zbyt ubogi w stosunku do tego co wygenerowane został w czasie migracji. Wniosek jest jeden. Trzeba stworzyć własne narzędzie. Tak najprościej byłoby wziąć wspomniany wyżej plugin i dopisać potrzebne rzeczy, ale…
Po pierwsze średnio znam rubiego. Po drugie to co chcę osiągnąć jest bliżej moich prywatnych wymagań, niż wymagań ogółu. Padło zatem na starego dobrego basha.
Szablon
Na początku stworzyłem szablon pliku, który będzie wzorcem do generowania:
Listing 1. Szablon
Flagi IDEN, TITLE, DATE i PERMALINK chcę zastąpić argumentami czy to wyliczonymi, czy pobranymi z linii poleceń. Całość zapisać w pliku, którego nazwa ma format DATE-TYTUL-KEBAB_CASEM.md. Przy czym tytuł w nazwie pliku oraz w PERMALINK musi zostać pozbawiony polskich znaków, znaków interpunkcyjnych i nawiasów. To oznacza trochę rzeźby, ale damy radę :)
Funkcje pomocnicze
Na początek potrzebujemy kilku funkcji pomocniczych, które zrobią nam robotę ze zmianą znaków w tytule oraz zamienią format daty z yyyy-mm-dd na yyyy/mm/dd. Zacznijmy od tej ostatniej.
Format daty
Tutaj sprawa jest bardzo prosta.
Listing 2. Zamiana formatu daty
Bierzemy dowolny tekst i zamieniamy wszystkie znaki - na znaki /.
Znaki interpunkcyjne i nawiasy
Tu sprawa robi się odrobinę bardziej zabawna, ale przez cały czas da się żyć:
Listing 3. Usunięcie znaków interpunkcyjnych i nawiasów
Generalnie polecenie tr uznaje jedynie niewielki podzbiór wyrażeń regularnych. Stąd taki dziwny zapis. Idziemy dalej.
Polskie znaki
I nie tylko polskie. Wszelkie litery spoza zakresu ASCII chcemy zamienić na ich odpowiedniki w ASCII.
Listing 4. Zamiana polskich znaków
Polecenie iconv zamieni nam ciąg w UTF-8 na ciąg w ASCII z użyciem transliteracji (TRANSLIT). TransliteracjaW, to proces zamiany znaków jednego alfabetu na inny. Najbardziej znaną transliteracją jest zamiana ; na ; (grecki znak zapytania) w kodzie javascript i patrzenie na frontasie dostają palpitacji :D
Kebab case
Kolejny krok to zamiana tytułu na zapisany dzięki kebab-case – wszystkie litery to małe litery, spacje zastępujemy -
Listing 5. Doner time
Tutaj samo tr nam nie wystarczy. O ile zamiana wielkich liter na małe jest prosta to już podmiana spacji może przysporzyć pewnych problemów. o ile przekażemy do funkcji ciąg znaków zaczynający się lub kończący spacją, to ta ostatnia spacja też zostanie zamieniona na -. dzięki sed nie tylko zmieniamy spacje na - ('s/ /-/g'), ale też usuwamy początkowy ('s/^-//') i końcowy ('s/-$//') znak - o ile trzeba.
Identyfikator
W sumie nie jest on potrzebny, ale w czasie migracji pozostał, więc i jego przeniesiemy.
Listing 6. Wyliczamy ID
Po pierwsze musimy popracować w kontekście opublikowanych artykułów (../_post). Tutaj mam jedno założenie – skrypt będzie siedział w katalogu _drafts. Następnie:
- szukamy wszystkich plików .md w opublikowanych plikach – find ../_posts/ -maxdepth 1 -type f -name "*.md"
- bierzemy pierwsze dwie linijki – -exec head -n 2 {} +
- odsiewamy linię z identyfikatorem – awk '/id: [0-9]/
- wypisujemy sam identyfikator – '{print $2}'
- sortujemy numerycznie – sort -n
- wybieramy ostatni wynik – tail -n 1
- dodajemy do niego 1 m_id=$((m_id + 1))
Z ciekawości wrzuciłem ten kod do AI i poprosiłem o optymalizację i średnio to wyszło. Dodał tylko sprawdzenia czy aby na pewno nie nadpisaliśmy m_id pustą wartością.
Budujemy adekwatny program
Czas przejść do adekwatnego programu. Będę potrzebował jeszcze jednej funkcji, która zbuduje mi tytuł w formacie przyjaznym przeglądarkom:
Listing 7. Tworzymy tytuł
Tu właśnie używamy większości funkcji pomocniczych, które stworzyliśmy wcześniej. Kolejny krok to wczytanie szablonu i podmiana odpowiednich elementów:
Listing 8. Generujemy zalążek z szablonu
Teraz jeszcze musimy pobrać argumenty i je obrobić. Będą dwa. Pierwszy to tytuł, a drugi, opcjonalny, to data dzienna publikacji. Domyślna data publikacji to dzisiaj.
Listing 9. Kompletny program
Pominąłem opcję set -u, która przerywa działanie skryptu, gdy zmienna nie jest zainicjowana. Jej ustawienie „psuje” przetwarzanie parametru tytułu o ile ten zawiera nawiasy. Głupie, ale działa. I to jest najważniejsze.