<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Luasmith Plugins</title>
<id>https://fita-slovo.codeberg.page/luasmith-plugins/</id>
<link rel="self" href="https://fita-slovo.codeberg.page/luasmith-plugins/feed.xml"/>
<link rel="alternate" href="https://fita-slovo.codeberg.page/luasmith-plugins/"/>
<author>
<name>Luasmith Plugins</name>
</author>
<updated>2026-09-18T00:00:00.000Z</updated>

<entry>
<title>Локализация</title>
<id>https://fita-slovo.codeberg.page/luasmith-plugins/ru/posts/localization/</id>
<link rel="alternate" href="https://fita-slovo.codeberg.page/luasmith-plugins/ru/posts/localization/"/>
<updated>2026-09-18T00:00:00.000Z</updated>
<summary type="text">Локализация</summary>
<content type="html">&lt;p&gt;Плагин &lt;code&gt;i18n&lt;/code&gt; для Luasmith предоставляет инструменты для создания многоязычных сайтов. Он использует &lt;a href=&quot;https://codeberg.org/fita-slovo/lettext&quot;&gt;Lettext&lt;/a&gt;, реализацию Gettext для Lua, позволяя переводить строки в шаблонах вашего сайта с использованием распространённого формата файлов PO. Плагин автоматически извлекает строки и генерирует PO(T) файлы при сборке веб-сайта, так что вам не понадобятся стандартные утилиты Gettext (такие как &lt;code&gt;xgettext&lt;/code&gt; и &lt;code&gt;msgmerge&lt;/code&gt;) — Lettext и плагин делают всё необходимое, чтобы упростить создание многоязычных сайтов.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Плагин не доделан&lt;/strong&gt;. Хотя основные вещи завершены, все ещё есть некоторые важные нереализованные части. Ожидаются кардинальные изменения.&lt;/p&gt;
&lt;h2 id=&quot;struktura-soderzhimogo&quot;&gt;Структура содержимого&lt;/h2&gt;
&lt;p&gt;Для указания языка страницы вы можете либо использовать поле &lt;code&gt;lang&lt;/code&gt; в метаданных, либо добавить суффикс к имени файла. Суффикс удобен, когда вы хотите использовать некоторые страницы как переводы друг для друга, и плагин учтёт это, позволяя создать переключатель языков (как тот, что вы можете видеть вверху этой страницы).&lt;/p&gt;
&lt;p&gt;Предположим, каталог &lt;code&gt;content&lt;/code&gt; выглядит следующим образом:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;content/
 | index.md
 | index.ru.md
 | some_page.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;И в &lt;code&gt;some_page.md&lt;/code&gt; указано &lt;code&gt;lang = ru&lt;/code&gt;; на выходе будет такая структура:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;out/
 | index.html
 | ru/
    | index.html
    | some_page.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Плагин сам отредактирует ссылки в содержимом страниц, так что их следует указывать так, как это корректно для структуры директории &lt;code&gt;content&lt;/code&gt;, не беспокойтесь о том, что путь к корню поменяется.&lt;/p&gt;
&lt;h2 id=&quot;payplayn&quot;&gt;Пайплайн&lt;/h2&gt;
&lt;p&gt;Для локализации ваших страниц потребуется всего 2 узла в пайплайне.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;i18n.localize(defaultLang, potAsDefault)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Этот узел проходит через все страницы, меняя пути и относительные ссылки так, как нужно; необходимые специфические поля у каждого элемента (item) также будут установлены.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;defaultLang&lt;/code&gt; — код языка по умолчанию для вашего сайта. Страницы без указанного поля &lt;code&gt;lang&lt;/code&gt; и без кода языка в суффиксе имени файла будут считаться страницами на языке по умолчанию. Если &lt;code&gt;defaultLang&lt;/code&gt; - nil, то язык по умолчанию будет &lt;code&gt;en&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;potAsDefault&lt;/code&gt; устанавливает, будет ли файл &lt;code&gt;messages.pot&lt;/code&gt; использоваться как резервный источник перевода строк для языка по умолчанию. Если язык по умолчанию имеет несколько форм множественного числа (как русский язык, например), то будет недостаточно использовать только &lt;code&gt;msgid&lt;/code&gt; и &lt;code&gt;msgid_plural&lt;/code&gt; для корректного отображения; если &lt;code&gt;potAsDefault&lt;/code&gt; является true, вы можете добавить &lt;code&gt;msgstr&lt;/code&gt; в POT файл, чтобы обойти ограничение и плагин успешно отобразит корректные строки; но это может быть несколько неправильно — писать &amp;quot;перевод&amp;quot; в POT файле (поскольку это PO &lt;em&gt;Template&lt;/em&gt;, то есть шаблон), и в этом случае вы можете предпочесть указать false для &lt;code&gt;potAsDefault&lt;/code&gt;, тогда отдельный PO файл будет сгенерирован для языка по умолчанию, а POT файл можно будет оставить чистым. Если &lt;code&gt;potAsDefault&lt;/code&gt; - nil, то это то же, что он равен true.&lt;/p&gt;
&lt;p&gt;Если вы используете плагин &lt;code&gt;i18n&lt;/code&gt; вместе с другими плагинами, которые меняют пути страниц (поле &lt;code&gt;path&lt;/code&gt;), тогда &lt;code&gt;i18n.localize&lt;/code&gt; &lt;strong&gt;должен&lt;/strong&gt; быть вызван до узлов других плагинов, чтобы не потерять суффиксы с кодами языков.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;i18n.writeTranslations()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Этот узел записывает все файлы для перевода в директорию &lt;code&gt;po&lt;/code&gt;. PO-файл будет сгенерирован для каждого языка, который плагин обнаружит, так что вам не нужно редактировать LINGUAS и/или создавать PO-файлы самостоятельно. Этот узел следует вызывать после применения шаблонов и других преобразований, которые вызывают фукнции перевода строк, чтобы плагин собрал все необходимые строки.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Также ещё пока что есть &lt;code&gt;i18n.setLang(path, lang)&lt;/code&gt; как замена отсутствующему функционалу, чтобы установить язык и прочие вещи для страниц, сгенерированных в пайплайне (то есть не из папки &lt;code&gt;content&lt;/code&gt;). Этот узел скорее всего будет удалён в будущем.&lt;/p&gt;
&lt;h2 id=&quot;ispolzovanie-v-shablonakh&quot;&gt;Использование в шаблонах&lt;/h2&gt;
&lt;p&gt;Бо́льшую часть функционала плагина для шаблонов можно изучить, взглянув на код переключения языков на этой странице:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-etlua&quot;&gt;&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;if&lt;/b&gt; &lt;span class=&quot;hl-operator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-identifier&quot;&gt;nlangs&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;i class=&quot;hl-number&quot;&gt;1&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;then&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;div&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%=&lt;/i&gt; &lt;b class=&quot;hl-function&quot;&gt;_&lt;/b&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;apos;Languages&amp;apos;&lt;/i&gt; &lt;span class=&quot;hl-operator&quot;&gt;..&lt;/span&gt; &lt;i class=&quot;hl-string&quot;&gt;&amp;apos;:&amp;apos;&lt;/i&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt;  &lt;b class=&quot;hl-keyword&quot;&gt;for&lt;/b&gt; &lt;span class=&quot;hl-identifier&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;path&lt;/span&gt; &lt;b class=&quot;hl-keyword&quot;&gt;in&lt;/b&gt; &lt;b class=&quot;hl-function&quot;&gt;iterLangs&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt; &lt;b class=&quot;hl-keyword&quot;&gt;do&lt;/b&gt;
    &lt;b class=&quot;hl-keyword&quot;&gt;if&lt;/b&gt; &lt;span class=&quot;hl-identifier&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;lang&lt;/span&gt; &lt;b class=&quot;hl-keyword&quot;&gt;then&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
    &lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;b&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%=&lt;/i&gt; &lt;b class=&quot;hl-function&quot;&gt;getLangName&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-identifier&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;%&amp;gt;&lt;/i&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;b&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
    &lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;else&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
    &lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;a&lt;/b&gt; &lt;span class=&quot;hl-attribute&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;quot;&amp;lt;%= p %&amp;gt;&amp;quot;&lt;/i&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%=&lt;/i&gt; &lt;b class=&quot;hl-function&quot;&gt;getLangName&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-identifier&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;%&amp;gt;&lt;/i&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;a&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
    &lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;end&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt;  &lt;b class=&quot;hl-keyword&quot;&gt;end&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;div&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;end&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;nlangs&lt;/code&gt; — счётчик количества языков, на которых страница доступна. Для &lt;em&gt;этой&lt;/em&gt; страницы непосредственно &lt;code&gt;nlangs&lt;/code&gt; равен 2. Значение поля задаётся автоматически, не редактируйте его самостоятельно.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;_&amp;#x27;Languages&amp;#x27;&lt;/code&gt; — строка для перевода. Если вы когда-нибудь писали код с использованием Gettext, то вам могут быть знакомы функции &lt;code&gt;_(...)&lt;/code&gt;, &lt;code&gt;_p(...)&lt;/code&gt;, &lt;code&gt;_n(...)&lt;/code&gt; and &lt;code&gt;_np(...)&lt;/code&gt; — это функции для перевода строк, со слегка отличающимися опциями, но главная задача у них одна: строка будет заменена на перевод из каталога сообщений для текущего языка (или оригинальная строка будет возвращена, если перевода нет). Посмотрите на &lt;a href=&quot;https://codeberg.org/fita-slovo/lettext/src/branch/main/demo.lua&quot;&gt;демонастрционный скрипт Lettext&lt;/a&gt; для изучения детального использования этих фукнций.&lt;/p&gt;
&lt;p&gt;Если посмотреть в файле &lt;code&gt;ru.po&lt;/code&gt; среди исходников этого сайта, можно найти перевод для указанной строки:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;msgid &amp;quot;Languages&amp;quot;
msgstr &amp;quot;Языки&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;iterLangs()&lt;/code&gt; перебирает языки страницы, возвращая код языка и путь к странице на другом языке. Итератор также выдаст текущую страницу, что можно обнаружить, сравнив возвращённый код языка с кодом текущей страницы (&lt;code&gt;lang&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;getLangName(lang)&lt;/code&gt; возвращает название языка для предоставленного кода. На данный момент функция возвращает название на английском, но это изменится в будущем. Так что сейчас функция возвращает &amp;quot;English&amp;quot; для &lt;code&gt;en&lt;/code&gt; и &amp;quot;Russian&amp;quot; для &lt;code&gt;ru&lt;/code&gt; независимо от языка текущей страницы.&lt;/p&gt;
&lt;p&gt;А теперь, ещё одна вещь, которую можно использовать в шаблонах:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;getLangRoot()&lt;/code&gt; возвращает путь к корневой директории языка текущей страницы.&lt;/p&gt;
&lt;h2 id=&quot;planiruemye-izmeneniya&quot;&gt;Планируемые изменения&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Добавление функции для получения даты и времени в локализованном формате;&lt;/li&gt;
&lt;li&gt;Добавление опции для создания поддиректории для языка по умолчанию (чтобы можно было сделать выбор языков на странице &lt;code&gt;index.html&lt;/code&gt;, а всё остальное поместить в поддиректории, подобно тому, что делает &lt;a href=&quot;https://www.wikipedia.org/&quot;&gt;Википедия&lt;/a&gt;, с той разницей, что Википедия использует поддомены, а не поддиректории);&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getLangName&lt;/code&gt; будет возвращать локализованные названия языков;&lt;/li&gt;
&lt;li&gt;Добавление простого способа создания локализованных индексных и других сгенерированных в пайплайне страниц.&lt;/li&gt;
&lt;/ul&gt;
</content>
</entry>
<entry>
<title>Localization</title>
<id>https://fita-slovo.codeberg.page/luasmith-plugins/posts/localization/</id>
<link rel="alternate" href="https://fita-slovo.codeberg.page/luasmith-plugins/posts/localization/"/>
<updated>2026-09-18T00:00:00.000Z</updated>
<summary type="text">Localization</summary>
<content type="html">&lt;p&gt;&lt;code&gt;i18n&lt;/code&gt; plugin for Luasmith provides tools to create multi-language websites. It uses &lt;a href=&quot;https://codeberg.org/fita-slovo/lettext&quot;&gt;Lettext&lt;/a&gt;, a Gettext implementation for Lua, allowing you to translate strings in your website templates utilizing a commonly used PO file format. The plugin automatically extracts strings and generates PO(T) files when building the website, so you don&amp;#x27;t have to have standard Gettext utilities (such as &lt;code&gt;xgettext&lt;/code&gt; and &lt;code&gt;msgmerge&lt;/code&gt;) being installed — everything is handled by Lettext and the plugin to simplify creation of multi-language websites.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The plugin is unfinished&lt;/strong&gt;. While the core things are complete, there are still some important missing parts. Breaking changes are expected.&lt;/p&gt;
&lt;h2 id=&quot;content-structure&quot;&gt;Content structure&lt;/h2&gt;
&lt;p&gt;You can use either &lt;code&gt;lang&lt;/code&gt; field in front-matter or add a filename suffix to set the language of a page. A suffix is useful when you want some pages to be translations to each other, and the plugin will be aware of that, so you will be able to create a language switcher (like you can see one on the top of this page).&lt;/p&gt;
&lt;p&gt;Assuming we have this content directory structure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;content/
 | index.md
 | index.ru.md
 | some_page.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With &lt;code&gt;some_page.md&lt;/code&gt; having &lt;code&gt;lang = ru&lt;/code&gt;, this structure will be produced on output:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;out/
 | index.html
 | ru/
    | index.html
    | some_page.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Changing the links in the content of pages is done by the plugin, so you should write relative links&amp;#x27; paths as they are in your &lt;code&gt;content&lt;/code&gt; folder and there&amp;#x27;s no need to be bothered of the fact that the path to root will change.&lt;/p&gt;
&lt;h2 id=&quot;pipeline&quot;&gt;Pipeline&lt;/h2&gt;
&lt;p&gt;There are just 2 things that you need to call in your pipeline for your content to be localized.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;i18n.localize(defaultLang, potAsDefault)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This node walks over all items, changing their paths and relative links in the content as needed; it will also set required plugin-specific item fields.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;defaultLang&lt;/code&gt; is the language code for the default language of your website. Pages without &lt;code&gt;lang&lt;/code&gt; field set and with no language code in file suffix are assumed to be pages in the default language. If &lt;code&gt;defaultLang&lt;/code&gt; is nil, it will be set to &lt;code&gt;en&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;potAsDefault&lt;/code&gt; defines whether the generated &lt;code&gt;messages.pot&lt;/code&gt; file should be used as a fallback for strings translations for the default language. If the default language has multiple plural forms, it may be insufficient to use only &lt;code&gt;msgid&lt;/code&gt; and &lt;code&gt;msgid_plural&lt;/code&gt; to provide proper strings; if &lt;code&gt;potAsDefault&lt;/code&gt; is true, you can add &lt;code&gt;msgstr&lt;/code&gt; in the POT file to workaround that and the plugin will read proper strings, but that may not feel right to write &amp;quot;translations&amp;quot; into the POT file (which is the PO &lt;em&gt;Template&lt;/em&gt; file), in such case you may want to set &lt;code&gt;potAsDefault&lt;/code&gt; to false and then a separate PO file for your default language will be generated, allowing you to keep the POT file clean. If &lt;code&gt;potAsDefault&lt;/code&gt; is nil, it will be set to true.&lt;/p&gt;
&lt;p&gt;If you use &lt;code&gt;i18n&lt;/code&gt; plugin together with some other plugins that modify items&amp;#x27; paths (such as &lt;code&gt;anyslug&lt;/code&gt; or &lt;code&gt;prettyurls&lt;/code&gt;) then &lt;code&gt;i18n.localize&lt;/code&gt; &lt;strong&gt;must&lt;/strong&gt; be called before other plugins&amp;#x27; nodes to avoid losing filename suffixes with language codes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;i18n.writeTranslations()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This node writes all translation files into &lt;code&gt;po&lt;/code&gt; directory. A PO file will be generated for each language that the plugin will encounter, so that you don&amp;#x27;t need to edit LINGUAS and/or create PO files yourself. This node should be called after applying all your template and doing other stuff that calls translation functions so that all strings will be collected.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There&amp;#x27;s also &lt;code&gt;i18n.setLang(path, lang)&lt;/code&gt; currently available as a workaround for missing functionality to set the language and add some extra stuff to pipeline-generated pages (i.e. not generated from content files). This node will most likely be removed in the future.&lt;/p&gt;
&lt;h2 id=&quot;usage-in-templates&quot;&gt;Usage in templates&lt;/h2&gt;
&lt;p&gt;Most of the functionality of the plugin for templates can be inspected in the code of the language switcher on this page:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-etlua&quot;&gt;&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;if&lt;/b&gt; &lt;span class=&quot;hl-identifier&quot;&gt;nlangs&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;i class=&quot;hl-number&quot;&gt;1&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;then&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;div&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%=&lt;/i&gt; &lt;b class=&quot;hl-function&quot;&gt;_&lt;/b&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;apos;Languages&amp;apos;&lt;/i&gt; &lt;span class=&quot;hl-operator&quot;&gt;..&lt;/span&gt; &lt;i class=&quot;hl-string&quot;&gt;&amp;apos;:&amp;apos;&lt;/i&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt;  &lt;b class=&quot;hl-keyword&quot;&gt;for&lt;/b&gt; &lt;span class=&quot;hl-identifier&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;p&lt;/span&gt; &lt;b class=&quot;hl-keyword&quot;&gt;in&lt;/b&gt; &lt;b class=&quot;hl-function&quot;&gt;iterLangs&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt; &lt;b class=&quot;hl-keyword&quot;&gt;do&lt;/b&gt;
    &lt;b class=&quot;hl-keyword&quot;&gt;if&lt;/b&gt; &lt;span class=&quot;hl-identifier&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;hl-identifier&quot;&gt;lang&lt;/span&gt; &lt;b class=&quot;hl-keyword&quot;&gt;then&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
    &lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;b&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%=&lt;/i&gt; &lt;b class=&quot;hl-function&quot;&gt;getLangName&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-identifier&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;%&amp;gt;&lt;/i&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;b&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
    &lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;else&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
    &lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;a&lt;/b&gt; &lt;span class=&quot;hl-attribute&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;quot;&amp;lt;%= p %&amp;gt;&amp;quot;&lt;/i&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%=&lt;/i&gt; &lt;b class=&quot;hl-function&quot;&gt;getLangName&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-identifier&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;%&amp;gt;&lt;/i&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;a&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
    &lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;end&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt;  &lt;b class=&quot;hl-keyword&quot;&gt;end&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;div&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
&lt;i class=&quot;hl-preprocessor&quot;&gt;&amp;lt;%&lt;/i&gt; &lt;b class=&quot;hl-keyword&quot;&gt;end&lt;/b&gt; &lt;i class=&quot;hl-preprocessor&quot;&gt;-%&amp;gt;&lt;/i&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;nlangs&lt;/code&gt; is the count of languages the page is available in. &lt;em&gt;This&lt;/em&gt; page in pacticular has &lt;code&gt;nlangs&lt;/code&gt; being 2. The field is set automatically, don&amp;#x27;t overwrite it yourself.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;_&amp;#x27;Languages&amp;#x27;&lt;/code&gt; is a translatable string. If you have ever written a code using Gettext, then you may be familiar with &lt;code&gt;_(...)&lt;/code&gt;, &lt;code&gt;_p(...)&lt;/code&gt;, &lt;code&gt;_n(...)&lt;/code&gt; and &lt;code&gt;_np(...)&lt;/code&gt; — these are translation function with slightly different options, but the main thing is the same: a string will be replaced by its translation from a messages catalog for the current language (or the original string is returned if there&amp;#x27;s no translation). See &lt;a href=&quot;https://codeberg.org/fita-slovo/lettext/src/branch/main/demo.lua&quot;&gt;Lettext demo&lt;/a&gt; for detailed usage examples of these functions.&lt;/p&gt;
&lt;p&gt;If you will look at &lt;code&gt;messages.pot&lt;/code&gt; file in the source code of this website, an entry with the string is there:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;msgid &amp;quot;Languages&amp;quot;
msgstr &amp;quot;&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;iterLangs()&lt;/code&gt; iterates over all languages for the page, returning a language code and a path to the page in another language. The iterator will go over the current page itself, this can be detected by comparing returned language code with the language code of the current page (&lt;code&gt;lang&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;getLangName(lang)&lt;/code&gt; returns the name of the language for the provided code. Currently it returns the name in English, but this will change in the future. So, now it returns &amp;quot;English&amp;quot; for &lt;code&gt;en&lt;/code&gt; and &amp;quot;Russian&amp;quot; for &lt;code&gt;ru&lt;/code&gt; no matter what the current page&amp;#x27;s language is.&lt;/p&gt;
&lt;p&gt;Now, one more thing that you can use in templates:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;getLangRoot()&lt;/code&gt; returns a path to the language root directory for the current page.&lt;/p&gt;
&lt;h2 id=&quot;planned-features&quot;&gt;Planned features&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A function to get date and time in localized format;&lt;/li&gt;
&lt;li&gt;An option to create subdirectory for the default language (so you can have a language selection page on &lt;code&gt;index.html&lt;/code&gt; and everything else will be in subdirectories, similar to what &lt;a href=&quot;https://www.wikipedia.org/&quot;&gt;Wikipedia&lt;/a&gt; does, except it does it on subdomains, not subdirectories);&lt;/li&gt;
&lt;li&gt;&lt;code&gt;getLangName&lt;/code&gt; returning localized language names;&lt;/li&gt;
&lt;li&gt;An easy way to create localized indexes and other pipeline-generated pages.&lt;/li&gt;
&lt;/ul&gt;
</content>
</entry>
<entry>
<title>Non-ASCII paths sluggification</title>
<id>https://fita-slovo.codeberg.page/luasmith-plugins/posts/ne-aski-fayl/</id>
<link rel="alternate" href="https://fita-slovo.codeberg.page/luasmith-plugins/posts/ne-aski-fayl/"/>
<updated>2026-09-11T00:00:00.000Z</updated>
<summary type="text">Non-ASCII paths sluggification</summary>
<content type="html">&lt;p&gt;This page is created from a file called &lt;em&gt;&amp;quot;Не АСКИ файл.md&amp;quot;&lt;/em&gt; (&amp;quot;non-ASCII file&amp;quot; in Russian), but as you can see the URL contains &amp;quot;ne-aski-fayl&amp;quot; instead.&lt;/p&gt;
&lt;h3 id=&quot;zagolovok-s-emodzi-disguised_face&quot;&gt;Заголовок с эмодзи 🥸&lt;/h3&gt;
&lt;p&gt;And the heading above also has properly sluggified ID in the generated HTML code:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;h3&lt;/b&gt; &lt;span class=&quot;hl-attribute&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;quot;zagolovok-s-emodzi-disguised_face&amp;quot;&lt;/i&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;&lt;span class=&quot;hl-default&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-default&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;hl-default&quot;&gt;.&lt;/span&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;h3&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These things are possible thanks to the &lt;code&gt;anyslug&lt;/code&gt; plugin.&lt;/p&gt;
&lt;h2 id=&quot;how-to-use&quot;&gt;How to use&lt;/h2&gt;
&lt;p&gt;Use the module and its 2 nodes for your pipeline:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lua&quot;&gt;&lt;span class=&quot;hl-identifier&quot;&gt;anyslug&lt;/span&gt; &lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt; &lt;b class=&quot;hl-function&quot;&gt;require&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;quot;anyslug&amp;quot;&lt;/i&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;hl-operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;.&lt;/span&gt;

&lt;b class=&quot;hl-keyword&quot;&gt;return&lt;/b&gt; &lt;span class=&quot;hl-operator&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;hl-operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;.&lt;/span&gt;
    &lt;span class=&quot;hl-identifier&quot;&gt;anyslug&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;.&lt;/span&gt;&lt;b class=&quot;hl-function&quot;&gt;sluggifyPaths&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hl-operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;.&lt;/span&gt;
    &lt;span class=&quot;hl-identifier&quot;&gt;anyslug&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;.&lt;/span&gt;&lt;b class=&quot;hl-function&quot;&gt;sluggifyLinks&lt;/b&gt;&lt;span class=&quot;hl-operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;hl-operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;hl-operator&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you &lt;code&gt;require&lt;/code&gt; the module it uses a little hack to inject the implementation of &lt;code&gt;sluggify&lt;/code&gt; function provided by the module into Luasmith, that&amp;#x27;s how headings&amp;#x27; IDs with non-ASCII characters also get sluggified properly.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sluggifyPaths&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This node walks over all items and sluggifies their paths. It should be executed before any other nodes that collects items&amp;#x27; paths (like &lt;code&gt;aggregate&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;If you use &lt;code&gt;anyslug&lt;/code&gt; together with &lt;code&gt;i18n&lt;/code&gt; module, then &lt;code&gt;i18n.localize&lt;/code&gt; &lt;strong&gt;must&lt;/strong&gt; be used before &lt;code&gt;anyslug.sluggifyPaths&lt;/code&gt;, otherwise pages&amp;#x27; language suffixes will be malformed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;sluggifyLinks&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This node sluggifies all links in items&amp;#x27; content. It should be used closer to the end of your pipeline, after applying templates and doing other stuff that changes content.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content>
</entry>
<entry>
<title>Pandoc plugin</title>
<id>https://fita-slovo.codeberg.page/luasmith-plugins/posts/pandoc/</id>
<link rel="alternate" href="https://fita-slovo.codeberg.page/luasmith-plugins/posts/pandoc/"/>
<updated>2026-09-02T00:00:00.000Z</updated>
<summary type="text">Pandoc plugin</summary>
<content type="html">&lt;p&gt;This page was written in &lt;em&gt;LibreOffice Writer&lt;/em&gt; and saved in ODT
format. 😵‍💫 Sounds like a 1st April joke, but it’s just to demonstrate
possibilities of Pandoc plugin for
&lt;em&gt;&lt;strong&gt;Luasmith&lt;/strong&gt;&lt;/em&gt;!&lt;/p&gt;
&lt;h2 id=&quot;how-to-use&quot;&gt;How to use&lt;/h2&gt;
&lt;p&gt;Use the module:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;pandoc = require(&quot;pandoc&quot;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And then add a node to your pipeline:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;pandoc.processPandoc(pattern, options, contentSource)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;All arguments are optional.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;pattern&lt;/strong&gt; is a filter that defines what files will be
processed (default: &lt;em&gt;%.md$&lt;/em&gt;);&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;options&lt;/strong&gt; is a string with additional arguments that
will be passed to Pandoc command-line (you don’t need to specify -t html
here, this will be passed anyway);&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;contentSource&lt;/strong&gt; is your content directory (if not
provided, the plugin will fall back to &lt;em&gt;source&lt;/em&gt; global variable
or &lt;em&gt;args[3]&lt;/em&gt; global variable if available, otherwise it will fall
back to &quot;content&quot; directory)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A formatting that will be exported to HTML completely depends on how
Pandoc parses your document, so refer to Pandoc documentation (this page
in particular has a very limited formatting because I didn’t bother to
write custom filters or find another way, if it exists, to enrich ODT
export; yet &lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-plugins/posts/pandoc/../localization.html&quot;&gt;relative links&lt;/a&gt; work as
expected).&lt;/p&gt;
&lt;p&gt;Since it’s possible to add arguments to command-line, you can also
use Lua filters for Pandoc (or simply modify
&lt;em&gt;luasmith-pandoc-filter.lua&lt;/em&gt; that comes along with the plugin and
gets passed to Pandoc automatically).&lt;/p&gt;
&lt;p&gt;Take a note that calling Pandoc as an external program for each page
leads to a SEVERE increase of build time for your site compared to using
built-in Markdown parser of Luasmith; it’s not the best idea to pass all
your Markdown content to Pandoc if it can be processed using the
built-in parser. For example, compiling &lt;a
href=&quot;https://log.schemescape.com/&quot;&gt;Jared Krinke’s blog&lt;/a&gt; with
built-in blog theme takes less than 500ms, but when using modified theme
with Pandoc processing — almost 15 seconds!&lt;/p&gt;
&lt;p&gt;For documents that can’t have metadata in a front-matter (like .odt
files), you can write a separate metadata file and it will be
automatically passed to Pandoc. This file must have the same name as
your document but with .yaml extension (for example, this page is
generated from &lt;em&gt;pandoc.odt &lt;/em&gt;and &lt;em&gt;pandoc.yaml&lt;/em&gt; with
metadata next to it). If metadata file is not found, the plugin will try
to read metadata from the document. In both cases metadata will be
parsed by built-in Luasmith front-matter parser that has limited YAML
support for now. Used metadata files will automatically be removed from
Luasmith items list, so they won’t appear in your website.&lt;/p&gt;
</content>
</entry>
<entry>
<title>Markdown syntax guide</title>
<id>https://fita-slovo.codeberg.page/luasmith-plugins/posts/markdown/</id>
<link rel="alternate" href="https://fita-slovo.codeberg.page/luasmith-plugins/posts/markdown/"/>
<updated>2026-08-31T00:00:00.000Z</updated>
<summary type="text">Markdown syntax guide</summary>
<content type="html">&lt;p&gt;This article offers a sample of basic Markdown syntax that can be used in Luasmith content files. This sample is based on “Markdown syntax guide” that is often seen on sites demonstrating themes for Hugo, another static site generator, but the content of the page was adapted for Luasmith that uses different Markdown parser.&lt;/p&gt;
&lt;h2 id=&quot;headings&quot;&gt;Headings&lt;/h2&gt;
&lt;p&gt;The following HTML &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;—&lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt; elements represent six levels of section headings. &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; is the highest section level while &lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt; is the lowest.&lt;/p&gt;
&lt;h1 id=&quot;h1&quot;&gt;H1&lt;/h1&gt;
&lt;h2 id=&quot;h2&quot;&gt;H2&lt;/h2&gt;
&lt;h3 id=&quot;h3&quot;&gt;H3&lt;/h3&gt;
&lt;h4 id=&quot;h4&quot;&gt;H4&lt;/h4&gt;
&lt;h5 id=&quot;h5&quot;&gt;H5&lt;/h5&gt;
&lt;h6 id=&quot;h6&quot;&gt;H6&lt;/h6&gt;
&lt;h2 id=&quot;paragraph&quot;&gt;Paragraph&lt;/h2&gt;
&lt;p&gt;Xerum, quo qui aut unt expliquam qui dolut labo. Aque venitatiusda cum, voluptionse latur sitiae dolessi aut parist aut dollo enim qui voluptate ma dolestendit peritin re plis aut quas inctum laceat est volestemque commosa as cus endigna tectur, offic to cor sequas etum rerum idem sintibus eiur? Quianimin porecus evelectur, cum que nis nust voloribus ratem aut omnimi, sitatur? Quiatem. Nam, omnis sum am facea corem alique molestrunt et eos evelece arcillit ut aut eos eos nus, sin conecerem erum fuga. Ri oditatquam, ad quibus unda veliamenimin cusam et facea ipsamus es exerum sitate dolores editium rerore eost, temped molorro ratiae volorro te reribus dolorer sperchicium faceata tiustia prat.&lt;/p&gt;
&lt;p&gt;Itatur? Quiatae cullecum rem ent aut odis in re eossequodi nonsequ idebis ne sapicia is sinveli squiatum, core et que aut hariosam ex eat.&lt;/p&gt;
&lt;h2 id=&quot;blockquotes&quot;&gt;Blockquotes&lt;/h2&gt;
&lt;p&gt;The blockquote element represents content that is quoted from another source, optionally with a citation which must be within a &lt;code&gt;footer&lt;/code&gt; or &lt;code&gt;cite&lt;/code&gt; element, and optionally with in-line changes such as annotations and abbreviations.&lt;/p&gt;
&lt;h4 id=&quot;blockquote-without-attribution&quot;&gt;Blockquote without attribution&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Tiam, ad mint andaepu dandae nostion secatur sequo quae.
&lt;strong&gt;Note&lt;/strong&gt; that you can use &lt;em&gt;Markdown syntax&lt;/em&gt; within a blockquote.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;blockquote-with-attribution&quot;&gt;Blockquote with attribution&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;It&amp;#x27;s more important to receive, sometimes, that good people that I recognize that like the result, than a lot of people that I have no idea what they are, who they are etc.&lt;br&gt;
— &lt;cite&gt;Roberto Ierusalimschy, creator of Lua&lt;sup&gt;&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-plugins/posts/markdown/#fn-1&quot;href=&quot;https://fita-slovo.codeberg.page/luasmith-plugins/posts/markdown/#fn-1&quot;id=&quot;fnref-1-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;tables&quot;&gt;Tables&lt;/h2&gt;
&lt;p&gt;Tables aren&amp;#x27;t part of the core Markdown spec, but Luasmith supports them out-of-the-box.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Italics&lt;/th&gt;
&lt;th&gt;Bold&lt;/th&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;em&gt;italics&lt;/em&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;bold&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;code&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;code-blocks&quot;&gt;Code Blocks&lt;/h2&gt;
&lt;h4 id=&quot;code-block-with-backticks&quot;&gt;Code block with backticks&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;!doctype html&amp;gt;&lt;/b&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;html&lt;/b&gt; &lt;span class=&quot;hl-attribute&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;quot;en&amp;quot;&lt;/i&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;head&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
  &lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;meta&lt;/b&gt; &lt;span class=&quot;hl-attribute&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;hl-operator&quot;&gt;=&lt;/span&gt;&lt;i class=&quot;hl-string&quot;&gt;&amp;quot;utf-8&amp;quot;&lt;/i&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
  &lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;title&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;&lt;span class=&quot;hl-default&quot;&gt;Example&lt;/span&gt; &lt;span class=&quot;hl-default&quot;&gt;HTML5&lt;/span&gt; &lt;span class=&quot;hl-default&quot;&gt;Document&lt;/span&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;title&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;head&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;body&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
  &lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;p&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;&lt;span class=&quot;hl-default&quot;&gt;Test&lt;/span&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;p&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;body&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
&lt;b class=&quot;hl-tag&quot;&gt;&amp;lt;/&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;html&lt;/b&gt;&lt;b class=&quot;hl-tag&quot;&gt;&amp;gt;&lt;/b&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;code-block-indented-with-four-spaces&quot;&gt;Code block indented with four spaces&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!doctype html&amp;gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta charset=&amp;quot;utf-8&amp;quot;&amp;gt;
  &amp;lt;title&amp;gt;Example HTML5 Document&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;p&amp;gt;Test&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;list-types&quot;&gt;List Types&lt;/h2&gt;
&lt;h4 id=&quot;ordered-list&quot;&gt;Ordered List&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;First item&lt;/li&gt;
&lt;li&gt;Second item&lt;/li&gt;
&lt;li&gt;Third item&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;unordered-list&quot;&gt;Unordered List&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;List item&lt;/li&gt;
&lt;li&gt;Another item&lt;/li&gt;
&lt;li&gt;And another item&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;nested-list&quot;&gt;Nested list&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Fruit&lt;ul&gt;
&lt;li&gt;Apple&lt;/li&gt;
&lt;li&gt;Orange&lt;/li&gt;
&lt;li&gt;Banana&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dairy&lt;ul&gt;
&lt;li&gt;Milk&lt;/li&gt;
&lt;li&gt;Cheese&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;other-elements---abbr-sub-sup-kbd-mark&quot;&gt;Other Elements — abbr, sub, sup, kbd, mark&lt;/h2&gt;
&lt;p&gt;&lt;abbr title=&quot;Graphics Interchange Format&quot;&gt;GIF&lt;/abbr&gt; is a bitmap image format.&lt;/p&gt;
&lt;p&gt;H&lt;sub&gt;2&lt;/sub&gt;O&lt;/p&gt;
&lt;p&gt;X&lt;sup&gt;n&lt;/sup&gt; + Y&lt;sup&gt;n&lt;/sup&gt; = Z&lt;sup&gt;n&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Press &lt;kbd&gt;&lt;kbd&gt;CTRL&lt;/kbd&gt;+&lt;kbd&gt;ALT&lt;/kbd&gt;+&lt;kbd&gt;Delete&lt;/kbd&gt;&lt;/kbd&gt; to end the session.&lt;/p&gt;
&lt;p&gt;Most &lt;mark&gt;salamanders&lt;/mark&gt; are nocturnal, and hunt for insects, worms, and other small creatures.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-1&quot;&gt;
The above quote is from &lt;a href=&quot;https://youtu.be/jCZnFKk6M9A?t=3547&quot;&gt;Ryan Peterman&amp;#x27;s interview with Roberto Ierusalimschy&lt;/a&gt;, August 3, 2026.&lt;a href=&quot;https://fita-slovo.codeberg.page/luasmith-plugins/posts/markdown/#fnref-1-1&quot;href=&quot;https://fita-slovo.codeberg.page/luasmith-plugins/posts/markdown/#fnref-1-1&quot;class=&quot;footnote-backref&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
</entry>
</feed>
