Markdown z Textile miażdżą Twojego HTML-a

Nie lubisz odrywać rąk od klawiatury. To spowalnia każdą pracę, która polega na pisaniu. Czy to kolejny tekst na bloga, czy kolejna porcja kodu – nieważne. Masz skupić się na pisaniu i niczym kompilator[1] przetłumaczyć kod źródłowy (w tym przypadku Twoje myśli) z jednego języka na drugi (polski, angielski, C++ lub nawet Prolog – wybierz sobie).

Edytor w WordPressie (oczywiście nie mówię o WYSIWYG) może i jest fajny, ale niewystarczający. Zupełnie nie wiem, dlaczego tag strong jest oznaczony w nim jako pogrubienie, a em jako kursywa – jest to błąd semantyczny (Riddle o tym pisał). Nie posiada on też m. in. przycisków do wstawiania tagów h2 czy h3, które przecież często widzi się na blogach. Można go co prawda dopakować wtyczkami takimi jak AddQuicktag, ale nadal będziesz musiał przechodzić ‘koszmar’ w postaci wstawiania tagów HTML. Dlatego wymyślono alternatywne języki znaczników (z ang. markup languages).

Markup powah

Markdown, Textile czy BBCode to jedne z popularniejszych języków. Zdecydowana większość (o ile nie wszystkie) silników for posiada wbudowaną obsługę BBCode – są to te wszystkie znaczniki typu [b] czy [url]. Na forach stosowane są tylko przez poweruserów, reszta jest zbyt leniwa, żeby z nich korzystać. Jego zaletą jest to, że łatwo go przyswoić osobom, które wcześniej miały kontakt z HTML-em. Wadą jest to, że nadal musimy wklepać równie dużą ilość znaków. Dla przykładu:

<b>Pogrubienie w HTML-u</b>
[b]Pogrubienie w BBCode[/b]

Tutaj i tutaj po siedem znaków. Nie uważajcie mnie za jakiegoś purystę “znacznikowego”, po prostu im mniej znaków, tym lepiej.

O wiele lepiej od BBCode prezentuje się Markdown i Textile. Ten drugi jest znany pewnie użytkownikom Joggera[2]. Markdown jest mniej znany, ale moim zdaniem jest nieco lepszy. Oba jednak są lepszym wyjściem niż wklepywanie surowego HTML-a. Dlaczego?

<a href="http://google.pl/">Link w HTML-u</a>
[Link w Markdown](http://google.pl/)

Piętnaście znaków versus cztery. Robi różnicę, prawda? Jeszcze jeden przykład:

<blockquote>Cytat blokowy w HTML-u.</blockquote>

> Cytat blokowy w Markdown!
<ul>
<li>lista wypunktowana</li>
<li>w HTML-u</li>
</ul>
- lista wypunktowana
- w Markdown

Taa, Markdown z Textile miażdżą HTML-a niczym III Rzesza wraz z… Odpuśćmy to porównanie.

Dobrze, oba języki wyglądają nieźle. Ale bez odpowiedniego preprocesora, który przetłumaczy Markdown czy Textile na HTML nic nie zrobimy.

Ruby powah

Pogrzebałem trochę na userscripts.org i oficjalnym repozytorium dla wordpressowych wtyczek, ale wtyczki po prostu nie były kompatybilne z nowszymi wersjami WP, a skrypty w JS… Cóż, nie, to też nie było to.

Pomyślałem wtedy “Uczysz się Ruby, napisz swojego gema”[3]. Nie sprawdzając, czy istnieje już coś takiego, przystąpiłem do realizacji własnych założeń. Po prostu w ramach nauki.

Wiedziałem o istnieniu dwóch, całkiem fajnych preprocesorów napisanych w Ruby: RedCloth dla Textile oraz BlueCloth dla Markdown. Żeby powiększyć ilość opcji programu, dodałem trzeci, znaleziony na GitHubie bb-ruby dla… Tak, BBCode.

ClothMark

I tak powstał ClothMark. Wzbogaca on Twoją konsolę/terminal o jedną, milutką komendę: clothmark.

Jak zainstalować to cacko?

Userzy Linuksa i Maka sobie poradzą, zawsze trzeba jednak pomóc użytkownikom Windowsa.

  • Najpierw instalujesz inne przydatne narzędzie, które zwie się RubyInstaller. Jeśli podczas instalacji wyskoczy jakiekolwiek pytanie o instalację RubyGems – zainstaluj, bo to też będzie Tobie potrzebne.
  • Jeśli jesteś dumnym użytkownikiem Linuksa lub Maka i nadal jesteś matołem[4], który nie wie, jak instalować rzeczy w jego systemie – przeczytaj instrukcję z oficjalnej strony.
  • Załóżmy, że już uporałeś się z instalacją Ruby. Teraz wchodzisz do swojej konsoli/terminalu i wklepujesz następujące komendy (dodaj sudo przed drugą komendą, jeśli używasz Uniksa):
gem sources -a http://gems.github.com
gem install ravicious-clothmark

To już koniec, pod Windowsem powinieneś zobaczyć podobne informacje, jak na screenie:

Instalacja ClothMark

Jak używać tego cacka?

Proste. Wchodzisz do katalogu z Twoim plikiem, którego treść napisana jest w Markdown i wklepujesz następującą komendę:

clothmark nowy_post_w_markdown.txt

I tyle. Twój plik zostanie zapisany pod nazwą nowy_post_w_markdown.html.

Ale… Nie chcesz Markdown? Jednak wolisz Textile lub BBCode? Proszę bardzo:

clothmark textile_rulez --markup textile
clothmark bbcode_rox --markup bbcode

Później już tylko wklejasz źródło wygenerowanego pliku do, na przykład, wordpressowego edytora i gotowe.

Właśnie, wpis możesz napisać w Twoim ulubionym edytorze i po prostu zapisać go jako osobny plik. Ja ten wpis popełniłem w WriteMonkey.

O reszcie opcji przeczytasz w readme. Ja chciałbym pokazać jedną, która może być przydatna.

Otóż domyślnie wygenerowany plik nie jest ostylowany. Jest po prostu tym, co napisałeś w Markdown/Textile/BBCode, ale w HTML-u. Jeśli chciałbyś dodać styl CSS i dodatkowy kod HTML, to dodaj do komendy parametr -ah lub --additional-html, wtedy plik powinien wyglądać lepiej.

Wiem, że kilka rzeczy wymaga pewnej poprawy, przede wszystkim mój angielski i przechwytywanie wyjątku, kiedy plik wejściowy nie istnieje, więc zgłaszajcie wszystkie znalezione błędy (i ewentualne propozycje) ;-)

Przypisy:
  1. Pewnie wiecie, co to jest, ale wolę się upewnić. []
  2. Sam kiedyś krytykowałem Joggera za Textile, ale wtedy byłem mały i głupi. []
  3. gem to po prostu dodatkowa biblioteka lub program []
  4. Ironia, ironia! []
  • ’sudo’ dajemy tylko w Ubuntu ;) W innych repo już nie ma takiej potrzeby :)

  • No to ja chętnie sprawdzę jak to działa.
    Dzięki Bogu, mam Ubuntu, więc nie ma tu problemów z Ruby ani gemami.
    Jakbym wychwycił jakieś babole, to dam znać.

  • @ Custom:
    a co ma repozytorium do sudo? :D

  • Distro, nie repo xD Lamer ze mnie :D

  • @ Custom:
    Z Wikipedii:

    sudo (ang. superuser do) – program stosowany w systemach operacyjnych GNU/Linux, Unix i podobnych [...]

  • @ Ravicious:
    Tak ;) Znany jest przede wszystkim użytkownikom Ubuntu.

  • Niefajnie nazwaleś pliki lib/clothmark/module.rb i lib/clothmark/markups.rb. Najlepiej się trzymać jeden plik – jedna klasa/jeden modul. W module Clothmark piszesz metodę initialize i potem includujesz to w klasach BlueMark, RedMark, BBMark. Lepiej zrobić klasę nadrzędną Mark po której dziedziczą wyżej wymienione klasy. Wtedy również mógłbyś umieścić w klasie nadrzędnej metodę convert, a w podklasach zrobić tylko prywatną to_html(some_string).
    W initialize masz coś takiego: if (!output || output.empty?) zamiast tego możesz ‘if output.blank?’. Fajnie jakby te wszystkie klasy były w przestrzeni nazw jakiejś.
    To by było na tyle :-). Mam nadzieję, że nie masz mi tego za złe.
    Fajne to cacuszko.

  • Instalację w większości dystrybucji musimy wykonać na roocie, więc jeśli nie mamy sudo to i tak musimy najpierw su dać.

    Co do ClothMarka – fajniej by było, gdyby to była Web App :) . Takie tylko Ctrl+C i Ctrl+V (Wy, makowcy chyba macie Cmd zamiast Ctrl, nie?). Bez zabaw z plikami wejściowymi i wyjściowymi.

  • @ Seban:
    Dzięki za rady, właśnie o to chodzi, żeby uczyć się na błędach ;-)

    W module Clothmark piszesz metodę initialize i potem includujesz to w klasach BlueMark, RedMark, BBMark. Lepiej zrobić klasę nadrzędną Mark po której dziedziczą wyżej wymienione klasy. Wtedy również mógłbyś umieścić w klasie nadrzędnej metodę convert, a w podklasach zrobić tylko prywatną to_html(some_string).

    Tak, to był mój błąd, bo teraz gdybym chciał przechwycić ewentualny error, kiedy nie ma pliku, który program chce otworzyć, to musiałbym to zrobić w trzech miejscach.

    Ja myślałem raczej nad zrobieniem z ClothMark klasy, dodaniem atrybutu markup i w ClothMark#convert dać case @markup. To chyba lepszy sposób niż tworzenie trzech różnych klas dla jednej linijki, które będą je różniły.

    Moduł zastosowałem tylko w celu sprawdzenia, jak to działa. Z tym, że w moim przypadku moduł jest zupełnie niepotrzebny (o czym mówiłeś).

    W initialize masz coś takiego: if (!output || output.empty?) zamiast tego możesz ‘if output.blank?’.

    Heh, trochę się zapędziłeś, bo blank? przychodzi razem z ActiveSupport :P A przecież nie dam require na ActiveRecord dla jednej metody.

    Fajnie jakby te wszystkie klasy były w przestrzeni nazw jakiejś.

    Mógłbyś sprecyzować?

    glabek94 :

    Co do ClothMarka – fajniej by było, gdyby to była Web App :) . Takie tylko Ctrl+C i Ctrl+V (Wy, makowcy chyba macie Cmd zamiast Ctrl, nie?). Bez zabaw z plikami wejściowymi i wyjściowymi.

    To też można łatwo napisać, może kiedyś zrobię coś takiego, ale najpierw chciałbym przesiąść się na Ubuntu, żeby w końcu zrobić porządne testy dla aplikacji.

  • o co do tego blank? masz rację zapędziłem się trochę :).
    A o przestrzeń nazw chodziło mi o coś w stylu:
    module Clothmark
    class RedMark
    end

    class BlueMark
    end

    class BBMark
    end
    end

  • sudo nie ma nic wspolego z dystrybucja, to ze jest w ubunto z automatu nie znaczy ze jest tylko w ubuntu.

    E nie wazne w sumie szkoda tlumaczyc takie rzeczy

  • Gotar :

    sudo nie ma nic wspolego z dystrybucja, to ze jest w ubunto z automatu nie znaczy ze jest tylko w ubuntu.

    Nie zaprzeczam, aczkolwiek jest pewnie w większości popularnych dystrybucji. Jeśli jakaś nie ma tego polecenia, to jej user jest chyba na tyle mądry, że o tym wie ;-)

  • Naprawdę fajna stronka. Lubię czytać ją bo autor ma dobre podejście do tego typu spraw.

  • To ja tak może przyspamuję, ale w temacie, że właśnie napisałem (dobra, dobra, przerobiłem na potrzeby komciów na blogach) userscript, który umożliwia pisanie komentarzy w dowolnych textarea’ch w Markdown (po kliknięciu na zgrabny guziczek poniżej okienka skrypt tłumaczy to na HTML). Ten komentarz właśnie w tym języku napisałem, oraz, muszę przyznać, sprawdza się świetnie. Ma prostą składnię, ładnie się wszystko integruje, polecam przetestować chociaż… ;)

    PS: Żeby skrypt zadziałał, trzeba najpierw dodać listę stron, na których będzie odpalany. Ja dodałem po prostu http://*, oraz zdefiniowałem parę stron, na których nie ma się otwierać. Jak mnie to zacznie wkurzać, to po prostu dodam w samym skrypcie opcję, żeby przed uruchomieniem sprawdzał, czy ta strona jest oparta na WP, albo innym wspieranym silniku. Póki co jest jak jest.
    PPS: Testowany na razie tylko pod Fx 3.6, i na nim śmiga. Prawdopodobnie pójdzie też Pod Operą i Chrome, ale w tym przypadku będzie wymagać drobnych modyfikacji w samym kodzie (dot. stron, na których ma być odpalany). Nie mam pojęcia, jak się sprawa ma pod Safari, ale chyba jest to rozwiązane podobnie jak w Greasemonkey pod Fx. A jeśli nie, to liczę na to że sobie poradzicie, zdolne dzieciaki jesteście… ;)
    PPPS: Nie wiedzieć czemu nie chce mi działać na tym blogu. Trudno, kopiuję gdzie indziej i wkleję tu już wygenerowany tekst… ;)
    PPPPS: Wkleiłem do texstarei w 3600.pl, i zadziałało. Dziwne…