Bloki kodu w Markdown: kompleksowy przewodnik po składni, językach i przykładach
Kod w płotkach, znaczniki języków, różnice (diff) oraz nazwy plików.
Fenced code blocks (bloki kodu z atrybutami) zawierają wieloliniowy kod źródłowy w Markdown. Token po otwierającym znaku ograniczającym jest tagiem języka, a tylko renderujący decyduje, co ten tag podświetla.
Ten przewodnik jest częścią Narzędzia do dokumentacji w 2026: Markdown, LaTeX, PDF i przepływy pracy drukarskie.

GitHub wyszukuje tag języka za pomocą Linguist oraz słów kluczowych w languages.yml. Hugo 0.164 przekazuje ten sam tag do Chroma. Tag nieznany Chromie jest nadal blokiem kodu, wyświetlanym jako zwykły tekst. Nagłówki, tabele i inne typy bloków znajdują się w Ściągawce Markdown.
Przegląd bloków kodu w Markdown
W Markdown istnieje trzy sposoby oznaczania kodu. Kod inline (w tekście) to fragment (span) wewnątrz akapitu. Blok z wcięciem i blok z atrybutami (fenced block) to oba bloki wieloliniowe, a tylko ten z atrybutami może zawierać tag języka.
| Typ | Składnia | Podświetlanie | Uwagi |
|---|---|---|---|
| Kod inline | `kod` |
Nie | Jeden fragment wewnątrz zdania |
| Blok z wcięciem | 4 spacje lub 1 tabulator na każdej linii | Nie | Brak ciągu informacyjnego, więc brak tagu języka |
| Blok z atrybutami | ```język … ``` lub ~~~ |
Tak, gdy renderujący zna język |
Forma udokumentowana przez GitHuba |
Blok z wcięciem nie może zawierać informacji o języku. CommonMark traktuje linię wciętą o cztery spacje jako kod i nie daje podświetlaczowi nic do dopasowania, dlatego forma z atrybutami jest ta, której należy używać, gdy przykład ma być podświetlony kolorami.
Atrybut (fence) to linia zawierająca co najmniej trzy apostrofy (backticks) lub trzy tyldy, następnie kod, a po nim zamykająca linia z tym samym znakiem, o długości co najmniej równej otwierającej. Zamykająca linia nie ma ciągu informacyjnego. Aby wyświetlić atrybut z trzema apostrofami wewnątrz przykładu, otwieramy i zamykamy go czterema apostrofami. Dokumentacja GitHuba dotycząca bloków kodu wymaga pustej linii przed i po atrybucie, aby surowy plik był łatwiejszy w czytaniu; atrybut i tak zostanie rozpoznan bez tej pustej linii.
Gdy poniższy kod źródłowy jest zapisany jako Markdown:
```python
def hello():
print("Hello, world!")
```
ta strona Hugo renderuje go w ten sposób:
def hello():
print("Hello, world!")
Kod inline używa tej samej zasady dotyczącej apostrofów w mniejszej skali. Para pojedynczych apostrofów wystarcza dla git status. Gdy sam fragment zawiera apostrof, używamy po dwa apostrofy z każdej strony:
`` `kod` ``
Podświetlanie składni Diff
Atrybut oznaczony jako diff służy do wyświetlania zmian jako tekstu. Lexik (lexer) Chroma w Hugolu akceptuje diff i udiff. GitHub podświetla ten sam identyfikator z listy swoich języków.
- stara linia, która zostanie usunięta
+ nowa linia, która zostanie dodana
niezmienna linia
Linie zaczynające się od - przyjmują styl usuwania, a linie zaczynające się od + przyjmują styl dodawania. Linia bez żadnego z tych prefiksów to zwykły tekst w tym leksykonie. Kolorowanie obejmuje całą linię. Zmienione słowo w środku linii nie jest oznaczane osobno.
Identyfikatory języków
Pierwsze słowo w ciągu informacyjnym to język. Dokumentacja Hugola traktuje to słowo bez rozróżniania wielkości liter. Jeśli Chroma nie ma leksykona dla danego języka, Hugo 0.164 emituje zwykły <pre><code class="language-…"> bez okładki podświetlania. Lokalny render notalang zrobił to. guessSyntax domyślnie jest ustawione na false, a dokumentacja Hugola stwierdza, że tylko pięć leksykonów implementuje automatyczne wykrywanie, więc pominięty tag pozostaje zwykłym tekstem, a nie zgadywanym językiem.
HTML generowany z tych atrybutów używa klasy language-python i tego samego tokena. To właśnie tę klasa, którą konwerter musi zachować, gdy zamienia podświetloną stronę z powrotem w Markdown, co jest opisane w Konwertowanie HTML na Markdown w Pythonie.
Poniższe identyfikatory to te wymienione dla tych języków w tabeli Chroma w Hugolu. W renderze Hugola 0.164 cs, yml i markdown były też podświetlane, nawet tam, gdzie opublikowana tabela drukuje csharp, yaml i md.
| Język | Identyfikatory Hugo Chroma |
|---|---|
| Python | python, py |
| JavaScript | javascript, js |
| TypeScript | typescript, ts, tsx |
| Java | java |
| C | c |
| C++ | cpp, c++ |
| C# | csharp, c# |
| Go | go, golang |
| Ruby | ruby, rb |
| PHP | php |
| Rust | rust, rs |
| Swift | swift |
| Kotlin | kotlin |
| HTML | html |
| CSS | css |
| Shell | bash, sh, shell, zsh |
| SQL | sql |
| JSON | json |
| YAML | yaml |
| Markdown | md, mkd |
| Perl | perl |
| Lua | lua |
| R | r |
| Matlab | matlab |
| Makefile | make, makefile |
| Diff | diff, udiff |
Strony GitHub Pages, które nadal podświetlają za pomocą Jekyll, wymagają identyfikatora w małych literach. Własna dokumentacja GitHuba stwierdza to wymaganie osobno od renderowania na github.com.
GitHub traktuje również kilka atrybutów jako diagramy, a nie jako podświetlany kod źródłowy: mermaid, geojson, topojson i stl. Tabela Chroma w Hugolu nie wymienia mermaid. Na stronie Hugo atrybut pozostaje tekstem źródłowym, dopóki hook renderowania, shortcode lub skrypt go nie narysuje. Szybki start i ściągawka do diagramów Mermaid opisuje tę konfigurację.
Określanie nazwy pliku
Nic w CommonMark ani w dokumentacji GitHuba dotyczącej bloków kodu nie zamienia ciągu informacyjnego w nazwę pliku. Opcje podświetlania w Hugolu to pary klamer, takie jak {linenos=inline}. Nie zawierają one pola nazwy pliku.
Dwukropek po języku
Niektóre generatory traktują js:app.js jako język plus nazwa:
```js:app.js
console.log("Hello, world!");
```
GitHub nie. Hugo 0.164 zachowuje cały token jako klasę elementu kodu (language-js:app.js) i nie drukuje nazwy pliku. Które dialekty dodają znaczenie ponad pierwsze słowo, porównano w GFM vs CommonMark vs Pandoc Markdown.
Nazwa nad atrybutem
Linia z pogrubionym kodem inline nad atrybutem wyświetla nazwę na GitHubie, na tej stronie i w innych renderujących CommonMark:
**`app.js`**
```js
console.log("Hello, world!");
```
Nagłówek działa w ten sam sposób:
#### `app.js`
```js
console.log("Hello, world!");
```
Nazwa wewnątrz przykładu
Komentarz w pierwszej linii podróżuje z kodem, gdy ktoś kopiuje blok:
```js
// app.js
console.log("Hello, world!");
```
| Metoda | GitHub | Hugo 0.164 | Pokazuje nazwę po skopiowaniu |
|---|---|---|---|
js:app.js w ciągu informacyjnym |
Brak nazwy pliku | Brak nazwy pliku; klasa to cały token | Nie |
| Pogrubiony kod lub nagłówek nad atrybutem | Tak | Tak | Nie |
| Komentarz na pierwszej linii | Tak | Tak | Tak |
Escapowanie apostrofów
Cztery apostrofy na zewnątrz wyświetlają atrybut z trzema apostrofami, co jest wzorcem dla strony dokumentującej Markdown:
````markdown
```python
# Ten potrójny atrybut z apostrofami jest wewnątrz atrybutu z czworem apostrofów
print("hello")
```
````
Zamykający atrybut musi być z tym samym znakiem co otwierający i mieć długość co najmniej równą. Krótszy zamykający kończy blok zbyt wcześnie i zostawia resztę przykładu jako zwykłe akapity.
Opcje podświetlania Hugo
config.toml tej strony nie ma bloku [markup.highlight], więc obowiązują domyślne ustawienia Hugola: bloki z atrybutami są podświetlane, stylem jest monokai, style są zapisywane inline (noClasses true), a numery linii są wyłączone. Hugo 0.164 nadal koloruje atrybut, który prosi tylko o język, tak jak w powyższym przykładzie Pythona.
Numery linii i wyróżnione linie to opcje w klamerkach po języku. Ten atrybut prosi o numery inline i oznacza linię 2:
```python {linenos=inline hl_lines=[2]}
def hello():
print("Hello, world!")
```
1def hello():
2 print("Hello, world!")
linenos akceptuje inline, table, true lub false. hl_lines to lista numerów linii lub zakresów. linenostart ustawia pierwszy wyświetlany numer. Te same klucze są bezwzględnymi dla wielkości liter. Shortcode highlight przyjmuje je jako jeden cytowany ciąg, i ten ciąg nadal renderował numery linii w Hugolu 0.164:
{{< highlight python "linenos=true,hl_lines=2" >}}
def hello():
print("Hello, world!")
{{< /highlight >}}
Aby przenieść kolory do arkusza stylów, ustaw `noClasses` na false i wygeneruj CSS. Hugo 0.164 akceptuje `--mode` i `--modeSelector` w tym poleceniu:
```bash
hugo gen chromastyles --style=monokai --mode=light > assets/css/highlight.css
hugo gen chromastyles --style=monokai --mode=dark --modeSelector > assets/css/highlight-dark.css
--modeSelector zakresuje każdą regułę pod klasą najwyższego poziomu, taką jak .dark .chroma. Lista flag to hugo gen chromastyles --help.
Gdy atrybut wygląda nieprawidłowo
Sprawdź wygenerowany element, zanim zmienisz przykład. W tej wersji Hugola znany język to div.highlight, którego element kodu ma data-lang ustawiony na identyfikator. Nieznany identyfikator to nagi pre i code z class="language-…", co wyprodukowało notalang.
Jeśli nazwa app.js jest nieobecna, a klasa to language-js:app.js, użyto formy z dwukropkiem. Przenieś nazwę na linię nad atrybutem.
Jeśli atrybuty w samym poradniku pojawiają się jako luźne akapity, zewnętrzny atrybut ma tę samą długość co wewnętrzny. Wydłuż zewnętrzny atrybut.
Jeśli krótkie polecenie pochłania apostrof w środku zdania, fragment potrzebuje dłuższej pary apostrofów niż znak, który zawiera.