Oryginalny Markdown
Zmieniony Markdown

Diff Markdown: porównaj dwa pliki Markdown online

Wklej dwa dokumenty Markdown i zobacz, co się zmieniło wiersz po wierszu. Działa na plikach README, notach wydania, MDX i dokumentach z frontmatter. Diff działa w Twojej przeglądarce.

Czym jest narzędzie diff Markdown?

Bezpłatne narzędzie działające w przeglądarce, służące do porównywania dwóch dokumentów Markdown na poziomie tekstu źródłowego. Wklej stary README.md po lewej, zaktualizowany po prawej, a każdy zmieniony nagłówek, element listy, link, blok kodu i komórka tabeli zostanie podświetlony. Nic nie opuszcza Twojego urządzenia.

Diff działa znak po znaku. Markdown to czysty tekst, więc to właściwa prymitywa: widzisz dosłowną zmianę w źródle dokumentu, a nie domysł, jak zinterpretowałby ją renderer.

Jeśli używasz już naszego diffa tekstu do ogólnej prozy, strona Markdown to ten sam silnik z opisami nakierowanymi na sytuacje, które naprawdę zdarzają się przy pisaniu dokumentacji. Do porównywania bloków YAML frontmatter na początku plików Jekyll, Hugo czy MkDocs lepiej radzi sobie strona YAML, która właściwie obsługuje strukturę wrażliwą na wcięcia. Ścisłe dane strukturalne z wyszukiwaniem po kluczu/wartości należą do diffa JSON.

Jak diff naprawdę działa

Diff działa na poziomie znaków. Po surowym diffie przebieg czyszczenia semantycznego przesuwa zaznaczenia tak, by trafiały na całe słowa, elementy list i cele linków, zamiast przecinać w połowie wstawkę `code span` ani odrywać początkowych ## od nagłówka. Wstawienia kolorują się na zielono po prawej, usunięcia na czerwono po lewej.

To diff tekstu źródłowego, nie wyrenderowanego wyjścia. To właściwa prymitywa do pracy z Markdown i waży więcej, niż się wydaje. Dwa dokumenty, które renderują się do identycznego HTML, mogą mieć bardzo różne źródła: **pogrubione** kontra __pogrubione__, punktatory * kontra -, wcięcie czterema spacjami kontra tabulator w zagnieżdżonej liście. Renderer spłaszcza to wszystko do tego samego wyjścia i tracisz sygnał. Kiedy chcesz wiedzieć, czy współtwórca naprawdę poprawił tylko literówkę, odpowiedzi udziela diff źródła.

Markdown to także rodzina dialektów. Oryginalna specyfikacja Johna Grubera (zob. daringfireball.net) była celowo luźna, a z czasem CommonMark, GitHub Flavored Markdown, Pandoc i MultiMarkdown ciągnęły każdy w innym kierunku. Tabele istnieją w GFM i Pandocu, ale nie w CommonMarku. Przekreślenie z ~~ i listy zadań z - [ ] to rozszerzenia GFM. Narzędzie diff nie dba o dialekt; pokazuje surowy tekst. Smak ma znaczenie wtedy, gdy zaczynasz pytać, czy akapit nadal poprawnie się renderuje pod nowym motywem dokumentacji, a to pytanie do renderera, nie do diffa.

Jak porównać Markdown w trzech krokach

Dwa panele tekstowe, jeden diff. Bez rejestracji, bez wgrywania, bez podróży do serwera.

  1. 1

    Wklej lub wczytaj swój Markdown

    Wklej starą wersję po lewej, nową po prawej. Albo kliknij Wczytaj w którymkolwiek panelu, by otworzyć plik .md, .markdown lub .mdx. Przycisk Przykład wypełnia obie strony małym README, więc widzisz diff w działaniu, zanim wkleisz własną treść.

  2. 2

    Ujednolić końce wierszy w razie potrzeby

    Plik edytowany w Windows zwykle ma końce wierszy CRLF; plik z serwera Linux ma LF. Diff znakowy traktuje je jako różne, co może pomalować każdy wiersz jako zmieniony. Jeśli diff wygląda podejrzanie pełen czerwieni i zieleni, najpierw ujednolić oba pliki do tego samego końca wiersza w edytorze. VS Code pokazuje aktywny koniec wiersza w pasku stanu na dole.

  3. 3

    Czytaj diff

    Usunięcia pojawiają się na czerwono po lewej, wstawienia na zielono po prawej. Oba panele przewijają się synchronicznie. Bloki frontmatter, ogrodzenia kodu, wiersze tabel i elementy list to dla silnika diffa zwykły tekst, więc zmiany w nich wychodzą na wierzch tak samo jak zmiany w treści. Liczniki zmian w nagłówkach każdego panelu dają szybkie pojęcie, jak ciężka była edycja.

Kiedy diff Markdown jest właściwym narzędziem

Przegląd zmian w README między gałęziami PR

Chcesz szybko zobaczyć, co zmieniło się w README.md w gałęzi PR względem main, ale nie chcesz otwierać GitHuba, przewijać przez wyrenderowany podgląd i klikać "Display the source diff" trzy menu w głąb. Zamiast tego wklej oba surowe pliki w to narzędzie. Nagłówki, ogrodzenia kodu i cele linków wychodzą czysto. Przydatne, gdy PR dotyka również stu plików źródłowych i zmiana w dokumentacji ginie w szumie.

Porównanie not wydania V1 i V2 przed publikacją

Noty wydania przechodzą przez kilka edycji, zanim trafią do publikacji. Szkice są przeorganizowywane, punkty łączone, numery wersji się przesuwają. Diff poprzednio opublikowanego RELEASE_NOTES.md z nowym szkicem łapie zaginione wpisy i przypadkowe duplikaty, na czym wyrenderowany podgląd radzi sobie słabo, bo oko ślizga się po podobnie wyglądających wierszach. Diff ułatwia też sprawdzenie, czy sekcja ## Breaking changes rzeczywiście urosła między wydaniami.

Diff eksportu z CMS-a względem repozytorium źródłowego

Twój zespół pisze dokumentację w Markdownie w repozytorium Git, ale publiczna strona jest generowana przez CMS lub generator statyczny taki jak MkDocs, Hugo czy Docusaurus. Czasem opublikowana strona odbiega od źródła: ktoś edytował stronę na żywo przez UI CMS-a i zapomniał wypchnąć zmiany, albo krok CI przepisał plik. Wyeksportuj opublikowaną stronę jako Markdown, wrzuć ją w jeden panel, .md z repo w drugi, a rozjazd masz przed oczami w sekundach.

Szkic wpisu na blog kontra zmiany redaktora

Wysłałeś wpis na blog do redaktora w Markdownie. Redaktor odesłał wersję z poprawkami. Diff między nimi pochłania uwagi znacznie szybciej niż czytanie akapit po akapicie, zwłaszcza gdy redaktor przestawił sekcje albo przepisał wstęp. Działa równie dobrze przy treściach pisanych przez ghostwritera, gdy autor musi potwierdzić, które ustawienia głosu przetrwały redakcję.

Audyt migracji z Markdowna do MDX

Migracja strony Docusaurus lub Astro z .md do .mdx brzmi jak operacja bez zmian, dopóki nie zauważysz, że niektóre importy się przesunęły, komponenty JSX zastąpiły dawne tabele Markdowna, a kilka ogrodzeń kodu jest teraz opakowanych we własne komponenty. Zrób diff starego page.md z nowym page.mdx plik po pliku i decyzje migracyjne stają się weryfikowalne. Ten sam przepływ w drugą stronę, jeśli zdecydujesz, że MDX był pomyłką, i chcesz wrócić do czystego Markdowna.

Markdown w pigułce

Krótka ściąga do przypadków granicznych składni, które to narzędzie najczęściej ujawnia. Kolumna dialektu mówi, które smaki naprawdę wspierają daną funkcję, bo to stamtąd biorą się niespodzianki między rendererami.

TopicWhat this tool does
Rozjazd między smakamiMarkdown to rodzina. CommonMark jest faktyczną podstawą. GFM dodaje tabele, listy zadań, przekreślenie i autolinki. Pandoc i MultiMarkdown dorzucają przypisy, listy definicji i więcej. To samo źródło może się między nimi renderować bardzo różnie.
TabeleTabele rozdzielane pionowymi kreskami istnieją w GFM i Pandocu. Nie są częścią CommonMarka ani oryginalnego Markdowna. Jeśli renderer wypisuje surowe znaki | zamiast komórek, parser jest ścisły CommonMark i potrzebujesz zgodnego z GFM.
Przekreślenie~~tekst~~ to rozszerzenie GFM. Oryginalny Markdown i CommonMark go nie wspierają. Pandoc wspiera z włączonym rozszerzeniem strikeout. Jeśli Twój tekst renderuje się z dosłownymi tyldami, renderer nie zna GFM.
Listy zadań- [ ] todo i - [x] zrobione to rozszerzenie GFM. CommonMark renderuje je jako zwykłe punktatory z dosłownymi nawiasami. GitHub, GitLab i większość nowoczesnych witryn dokumentacyjnych je wspierają; standardowe procesory Markdowna zwykle nie.
Bloki kodu: ogrodzone vs wcięciaBloki kodu w ogrodzeniu (potrójne backticki lub tyldy, opcjonalnie z tagiem języka) to CommonMark i są wspierane wszędzie. Oryginalna specyfikacja miała tylko bloki kodu z wcięciem czterema spacjami; nadal działają, ale nie potrafią nieść podpowiedzi języka. Mieszanie obu w jednym pliku jest legalne, ale niechlujne.
Twarde łamania wierszaTrzy opcje: zakończ wiersz dwiema spacjami na końcu, zakończ ukośnikiem wstecznym \ (CommonMark i GFM, nie oryginalny) albo wstaw pusty wiersz dla podziału akapitu. Spacje końcowe są niewidoczne w większości edytorów, dlatego twarde łamania często przeżywają diff, którego nikt nie zauważa.
FrontmatterYAML między ogrodzeniami ---, TOML między +++ lub JSON między { } na samej górze pliku. Nie należy w ogóle do specyfikacji Markdowna, ale jest wszechobecny w Jekyllu, Hugo, MkDocs, Docusaurusie i Astro. Renderery usuwają go przed parsowaniem treści.
HTML w liniiCommonMark dopuszcza surowe znaczniki HTML wewnątrz Markdowna. GFM też, ale przy renderowaniu na github.com stosuje sanitizator HTML. Niektóre generatory statyczne sanityzują, inne przepuszczają HTML, kilka go ucieka. Diffy stron z osadzonymi blokami <div> lub <iframe> są częste przy audytach migracji.

Diff Markdown: najczęstsze pytania

Czy to pokazuje podgląd wyrenderowanego wyjścia?

Nie. Narzędzie robi diff tekstu źródłowego Markdowna, nie HTML-a, który stworzyłby renderer. To celowe. Dwa dokumenty mogą wyrenderować się do identycznego HTML-a i wciąż mieć źródła z istotnymi różnicami, na przykład punktatory pisane * kontra - albo pogrubienie pisane ** kontra __. Diff na poziomie źródła zachowuje ten sygnał. Jeśli chcesz zobaczyć, jak dokument się renderuje, wklej go do swojego zwykłego podglądu: interfejsu webowego GitHuba, VS Code lub generatora statycznego.

Czym to się różni od porównywania wyrenderowanego HTML-a?

Diff wyrenderowanego HTML-a mówi, co zobaczą czytelnicy. Diff źródła mówi, co naprawdę zmieniło się w pliku. Odpowiadają na różne pytania. Dla Markdowna diff źródła jest niemal zawsze bardziej użyteczny, bo wiernie pokazuje edycje autora: poziom nagłówka zmienił się z ## na ###, blok kodu w ogrodzeniu zmienił tag języka, link względny stał się bezwzględny. Jeśli chcesz porównania na poziomie HTML, przepuść oba pliki przez swój renderer i potem zrób diff wyjścia.

A co z niejednoznacznością CommonMark vs GitHub Flavored Markdown?

Sam diff nie parsuje Markdowna, więc dialekt jest mu obojętny. Tabele, listy zadań, przekreślenie i autolinki wyglądają jak zwykły tekst. Smak ma znaczenie, gdy pytasz, czy dokument nadal renderuje się poprawnie. CommonMark jest najbliższy specyfikacji bazowej, a GitHub Flavored Markdown to CommonMark plus tabele, listy zadań, przekreślenie i autolinki. Wybierz to, co wspiera Twój docelowy renderer.

Jak radzi sobie z frontmatter YAML lub TOML?

Frontmatter to po prostu tekst na górze pliku, ujęty w --- dla YAML lub +++ dla TOML. Generatory statyczne jak Hugo, Jekyll i MkDocs używają go jako metadanych strony. Diff traktuje ten blok jak zwykły tekst, więc zmiany w title:, date: czy tags: pojawiają się jak każdy inny wiersz. Jeśli Twój frontmatter jest duży i wrażliwy na wcięcia, nasza strona diff YAML lepiej obsłuży ten blok osobno.

Czy działa dla MDX lub JSX wewnątrz Markdowna?

Tak. MDX to Markdown z osadzonymi komponentami JSX, a JSX z punktu widzenia diffa to po prostu dodatkowy tekst. Możesz wkleić plik .mdx w którykolwiek panel, a diff wyciągnie zmiany w importach, propsach komponentów i otaczającym Markdownie tak samo jak przy .md. Jedyne, czego narzędzie nie zrobi, to walidacja, czy Twój JSX się kompiluje; to zadanie kompilatora MDX. Do samego przeglądu kodu fragmentów JSX wklej je do naszego diffa tekstu.

Jak obsługiwane są końce wierszy (CRLF kontra LF)?

Końce wierszy to znaki, więc plik zapisany w stylu Windows z CRLF i plik zapisany w stylu Unix z LF będą się różnić w każdym wierszu. Jeśli Twoje panele wyglądają na pełne fantomowych zmian, to niemal zawsze przyczyna. Rozwiązaniem jest ujednolicenie obu plików do tego samego końca wiersza w edytorze przed wklejeniem; w VS Code aktywny koniec wiersza widać w pasku stanu na dole i przełącza się go jednym kliknięciem. Ustawienie Gita core.autocrlf również może wprowadzać zaskakujące różnice CRLF między maszynami.

Prywatność i jak to działa

Twój Markdown nigdy nie opuszcza przeglądarki. Edytor, diff i formater działają na Twojej maszynie. Brak analityki na Twoim wejściu, brak logów, brak podróży do serwera. Tło dotyczące samego formatu znajdziesz w Wikipedii, najnowszą specyfikację CommonMark na spec.commonmark.org/0.31.2, a smak GitHuba na github.github.com/gfm.