Org-mode. Экспорт в Hugo

Экспорт org-mode в Hugo является одной из составных частей научного рабочего процесса на основе Emacs и org-mode.

Содержание

1 Использование языка Markdown внутри Org

  • При экспорте Org преобразуется в стандартный Markdown. Однако в Hugo используются собственные нестандартные расширения (см. Синтаксис Markdown для генератора сайтов Hugo).
  • При необходимости их можно вставлять прямо в текст.

2 Соответствие языков разметки

Таблица 1: Соответствие разметок org и markdown
OrgMarkdownПосле рендеринга
*bold***bold**bold
/italics/_italics_italics
=monospace=`monospace`monospace
~key-binding~`key-binding` 1key-binding
~key-binding~<kbd>key-binding</kbd> 2
+strike-through+~~strike-through~~strike-through
_underline_<span class = "underline">underline</span> 3underline

3 Настройка экспорта

  • Экспорт производится в рамках общего фреймворка org-mode для экспорта (см. Org-mode. Экспорт).

3.1 Экспорт специфических элементов

3.1.1 Экспорт операторов Hugo

  • Для экспорта конкретных элементов, необходимых только для Hugo, следует использовать блок export. Например, оглавление задаётся следующим образом:
    1#+begin_export hugo
    2{{</* toc */>}}
    3#+end_export
    
  • Это позволяет задавать оглавление только для Hugo.

3.1.2 Отбивка резюме (Summary Splitter)

  • Отбивка резюме задаётся конструкцией
    1#+hugo: more
    

3.1.3 Резюме и подробная информация

  • Специальный блок «Детали» #+begin_details … #+end_details используется для создания элемента, раскрывающего дополнительные сведения (<details> и <summary>).

    1#+begin_details
    2#+begin_summary
    3Краткая информация
    4#+end_summary
    5А здесь подробная информация.
    6#+end_details
    
  • Выглядить это так:

    Краткая информация

    А здесь подробная информация.

  • Если блок summary отсутствует, резюме будет заменено на некоторое значение по умолчанию. Так, блок

    1#+begin_details
    2А здесь подробная информация.
    3#+end_details
    

    будет иметь следующий вид:

    А здесь подробная информация.

  • Можно показывать блок открытым по умолчанию. Для этого следует добавить атрибут HTML #+attr_html: :open t:

    1#+attr_html: :open t
    2#+begin_details
    3#+begin_summary
    4Краткая информация
    5#+end_summary
    6А здесь подробная информация.
    7#+end_details
    
    Краткая информация

    А здесь подробная информация.

3.2 Свойства экспорта

3.2.1 Обязательные свойства

  • Для экспорта необходимо установить следующие обязательные свойства:
    • HUGO_SECTION - название раздела Hugo по умолчанию для всех сообщений. Обычно это свойство устанавливается для сообщений или блога. Значение по умолчанию устанавливается с помощью org-hugo-default-section-directory.
    • HUGO_BASE_DIR - корневой каталог сайта Hugo. Например, если HUGO_BASE_DIR установлен на ~/hugo/, то экспортированные файлы Markdown будут сохранены в каталог ~/hugo/content/<HUGO_SECTION>/.
  • Данные свойства можно устанавливать как на уровне файла, так и на уровне каталога или проекта.
  • Переменные на уровне каталога задаются в файле .dir-locals.el:
    1((org-mode . ((org-hugo-base-dir . "~/work/blog/git")
    2         (org-hugo-section . "ru/post"))))
    

3.2.2 Формат заголовка

  • Поддерживаются форматы заголовка TOML (по умолчанию) и YAML.
  1. Экспорт для всего файла

    1#+hugo_front_matter_format: yaml
    
  1. Экспорт для поддерева

    1:PROPERTIES:
    2:EXPORT_HUGO_FRONT_MATTER_FORMAT: yaml
    3:END:
    

3.2.3 Свойства экспорта для заголовка Hugo

Таблица 2: Сводная таблица свойств экспорта для заголовка Hugo
Hugo front-matter (TOML)Уровень файлаУровень поддерева
title = "foo"#+title: foo* foo
date = 2017-09-11T14:32:00-04:00CLOSED: [2017-09-11 Mon 14:32]
date = 2017-07-24#+date: 2017-07-24:EXPORT_DATE: 2017-07-24
publishDate = 2018-01-26#+hugo_publishdate: 2018-01-26SCHEDULED: <2018-01-26 Fri>
publishDate = 2018-01-26:EXPORT_HUGO_PUBLISHDATE: 2018-01-26:
expiryDate = 2999-01-01#+hugo_expirydate: 2999-01-01DEADLINE: <2999-01-01 Tue>
expiryDate = 2999-01-01:EXPORT_HUGO_EXPIRYDATE: 2999-01-01:
lastmod = <current date>#+hugo_auto_set_lastmod: t:EXPORT_HUGO_AUTO_SET_LASTMOD: t
lastmod = <current date>#+hugo_auto_set_lastmod: t
tags = ["toto", "zulu"]#+hugo_tags: toto zulu* foo :toto:zulu:
categories = ["x", "y"]#+hugo_categories: x y* foo :@x:@y:
draft = true#+hugo_draft: true* TODO foo
draft = false#+hugo_draft: false* foo или * DONE foo
weight = 123 (manual)#+hugo_weight: 123:EXPORT_HUGO_WEIGHT: 123
weight = 123 (auto-calc):EXPORT_HUGO_WEIGHT: auto
tags_weight = 123 (manual)#+hugo_weight: :tags 123:EXPORT_HUGO_WEIGHT: :tags 123
tags_weight = 123 (auto-calc):EXPORT_HUGO_WEIGHT: :tags auto
weight = 123 (in [menu.foo])#+hugo_menu: :menu foo :weight 123:EXPORT_HUGO_MENU: :menu foo
categories_weight = 123#+hugo_weight: :categories 123

3.3 Особенности экспорта

4 Сочетания клавиш

  • Экспорт осуществляется через стандартный интерфейс экспорта в org-mode.

4.1 Для режимов один пост на файл и один пост на поддерево

  • C-c C-e H H Экспорт «Что я имею в виду».
    • Если курсор находится в допустимом поддереве сообщения Hugo, экспортирует это поддерево в сообщение Hugo в Markdown. Допустимое поддерево сообщений Hugo - это поддерево, для которого установлено свойство EXPORT_FILE_NAME.
    • Если файл предназначен для экспорта целиком (т.е. имеет ключевое слово #+title), экспортирует весь файл Org в сообщение Hugo в Markdown.
  • C-c C-e H A Экспорт всего «Что я имею в виду».
    • Если в org-файле есть одно или несколько действительных поддеревьев сообщений Hugo, экспортирует их в сообщения Hugo в Markdown.
    • Если файл предназначен для экспорта целиком (т. е. вообще нет действительных поддеревьев сообщений Hugo и есть ключевое слово #+title), экспортирует весь org-файл в сообщение Hugo в Markdown.

4.2 Для режима один пост на файл

  • C-c C-e H h Экспорт файла Org в сообщение Hugo в Markdown.

5 Теги и категории

5.1 Экспорт уровня файла

  • Список тегов:
    1#+hugo_tags
    
  • Список категорий:
    1#+hugo_categories
    

5.2 Экспорт уровня поддерева

5.2.1 Теги

Экспортируемые теги Hugo задаются как теги org-mode:

1* My post                                                         :tag1:tag2:

5.2.2 Категории

Экспортируемые категорий Hugo задаются как теги org-mode, для которых установлен префикс @:

1* My post                                                       :@cat1:@cat2:

5.2.3 Использование filetags

Для экспорта на уровне поддерева можно использовать оператор

1#+filetags

Например:

1#+filetags: :@cat1:tag1:tag2:

5.3 Дефисы и пробелы в тегах

В тегах org-mode нельзя использовать дефисы и пробелы. Конвертер использует следующие настройки:

  • одиночное подчёркивание переводится в дефис (конфигурационная переменная org-hugo-prefer-hyphen-in-tags);
  • двойное подчёркивание переводится в пробел (конфигурационная переменная org-hugo-allow-spaces-in-tags).

6 Дополнительные поля

Нестандартные дополнительные поля в основном используются для установки пользовательских параметров оформления.

  • Чтобы установить настраиваемый параметр предварительной записи в поддереве, используется свойство :EXPORT_HUGO_CUSTOM_FRONT_MATTER:.
  • Чтобы задать настраиваемый параметр внешнего вида глобально или для потока экспорта для каждого файла, используется ключевое слово #+HUGO_CUSTOM_FRONT_MATTER:.

6.1 Синтаксис

6.1.1 Пары ключ-значение

  • Можно записывать в одном поле:
    1:PROPERTIES:
    2:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :key1 value1 :key2 value2
    3:END:
    
  • Можно разбить на несколько полей:
    1:PROPERTIES:
    2:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :key1 value1
    3:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :key2 value2
    4:END:
    
  • На уровне файла посредством ключевого слова:
    1#+hugo_custom_front_matter: :key1 value1
    2#+hugo_custom_front_matter: :key2 value2
    
  • Например, запись
    1:PROPERTIES:
    2:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :feature true
    3:END:
    
    примет вид (для TOML)
    1feature = true
    

6.1.2 Списочные значения

  • Запись имеет следующий вид:
    1:PROPERTIES:
    2:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :key1 '(elem11 elem12) :key2 '(elem21 elem22)
    3:END:
    
  • Например, запись
    1:PROPERTIES:
    2:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :animals '(dog cat "penguin" "mountain gorilla")
    3:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :integers '(123 -5 17 1_234)
    4:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :floats '(12.3 -5.0 -17E-6)
    5:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :booleans '(true false)
    6:END:
    
    примет вид (для TOML)
    1animals = ["dog", "cat", "penguin", "mountain gorilla"]
    2integers = [123, -5, 17, 1_234]
    3floats = [12.3, -5.0, -1.7e-05]
    4booleans = [true, false]
    

6.1.3 Многоуровневые значения

  • Запись имеет следующий вид:
    1:PROPERTIES:
    2:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :key1 '((subkey11 . subval11) (subkey12 . (subelem121 subelem122))) :key2 '((subkey21 . subval21))
    3:END:
    
  • Например, запись
    1:PROPERTIES:
    2:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :versions '((emacs . "27.0.50") (hugo . "0.48"))
    3:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :header '((image . "projects/Readingabook.jpg") (caption . "stay hungry, stay foolish"))
    4:EXPORT_HUGO_CUSTOM_FRONT_MATTER+: :collection '((animals . (dog cat "penguin" "mountain gorilla")) (integers . (123 -5 17 1_234)) (floats . (12.3 -5.0 -17E-6)) (booleans . (true false)))
    5:END:
    
    примет вид (для TOML)
     1[versions]
     2  emacs = "27.0.50"
     3  hugo = 0.48
     4[header]
     5  image = "projects/Readingabook.jpg"
     6  caption = "stay hungry, stay foolish"
     7[collection]
     8  animals = ["dog", "cat", "penguin", "mountain gorilla"]
     9  integers = [123, -5, 17, 1_234]
    10  floats = [12.3, -5.0, -1.7e-05]
    11  booleans = [true, false]
    

6.1.4 Прямая вставка преамбул

Можно описать преамбулу непосредственно (если невозможно сгенерить средствами экспорта). Для этого используется аргумент заголовка блока кода :front_matter_extra t.

  1. Преамбула TOML

    По умолчанию используется преамбула в формате TOML, поэтому нет необходимости устанавливать ключевое слово :EXPORT_HUGO_FRONT_MATTER_FORMAT: toml.

     1* Post with TOML front-matter (default)
     2:PROPERTIES:
     3:EXPORT_FILE_NAME: extra-front-matter-toml
     4:END:
     5The contents of the ~#+begin_src toml :front_matter_extra t~ TOML
     6block here will get appended to the TOML front-matter.
     7#+begin_src toml :front_matter_extra t
     8[[foo]]
     9  bar = 1
    10  zoo = "abc"
    11[[foo]]
    12  bar = 2
    13  zoo = "def"
    14#+end_src
    
  1. Преамбула YAML

     1* Post with YAML front-matter
     2:PROPERTIES:
     3:EXPORT_FILE_NAME: extra-front-matter-yaml
     4:EXPORT_HUGO_FRONT_MATTER_FORMAT: yaml
     5:END:
     6The contents of the ~#+begin_src yaml :front_matter_extra t~ YAML
     7block here will get appended to the YAML front-matter.
     8#+begin_src yaml :front_matter_extra t
     9foo:
    10  - bar: 1
    11    zoo: abc
    12  - bar: 2
    13    zoo: def
    14#+end_src
    

7 Экспорт элементов

  • При экспорте элементов для Hugo используется блок
    1#+begin_export hugo
    2Текст для Hugo
    3#+end_export
    
  • Возникла коллизия, когда из единого источника необходимо было вывести информацию и в Hugo, и в Markdown. При экспорте посредством блока
    1#+begin_export markdown
    2Текст для Markdown
    3#+end_export
    
    этот текст появлялся и в файле для Hugo. Для обхода этой ситуации я стал задавать блок для Markdown в следующем виде:
    1#+begin_src markdown :exports (if (eq org-export-current-backend 'md) "" "none")
    2Текст для Markdown
    3#+end_src
    

8 Пакет страниц (page bundle)

8.1 Общая информация

  • Для экспорта в пакет (папку) страниц нужно установить для свойства :EXPORT_HUGO_BUNDLE: (или =#+HUGO_BUNDLE) имя каталога в качестве значения.
  • Значение :EXPORT_FILE_NAME: или #+EXPORT_FILE_NAME устанавливается в зависимости от вида пакетов страниц.
  • Пакеты страниц (Hugo Page Bundle) бывают двух видов:
    • пакет-страница (Leaf Bundle)
      • нет подстраниц,
      • контент и вложения для отдельных страниц,
      • индексный файл: index.md,
      • пример: content/posts/my-post/index.md,
      • :EXPORT_FILE_NAME: index,
      • #+EXPORT_FILE_NAME: index.
    • пакет веток (Branch Bundle)
      • содержит подстраницы,
      • контент и вложения для страниц раздела (домашняя страница, раздел, термины таксономии, список таксономии),
      • индексный файл: _index.md,
      • пример: content/posts/_index.md,
      • :EXPORT_FILE_NAME: _index,
      • #+EXPORT_FILE_NAME: _index.
    • Пример пакет-страницы (Leaf Bundle):
      • экспорт в content/xyz/index.md
        1​* Page title
        2:PROPERTIES:
        3:EXPORT_HUGO_BUNDLE: xyz
        4:EXPORT_FILE_NAME: index
        5:END:
        6Content
        
    • Пример пакета веток (Branch Bundle)
      • экспорт в content/uvw/_index.md
        1​* Page title
        2:PROPERTIES:
        3:EXPORT_HUGO_BUNDLE: uvw
        4:EXPORT_FILE_NAME: _index
        5:END:
        6Content
        

8.2 Читаемые курсы

Чтобы сделать список и содержание читаемых курсов (или какой-либо документации).

  • Пусть курс называется mathsec.
  • Свойства для экспорта:
    1:PROPERTIES:
    2:EXPORT_HUGO_SECTION: ru/course
    3:EXPORT_HUGO_BUNDLE: mathsec
    4:EXPORT_FILE_NAME: _index
    5:END:
    

9 Автоматический экспорт при сохранении

9.1 Установка на уровне каталога

  • Установка делается в файле .dir-locals.el в текущем каталоге:
    1((org-mode . ((eval . (org-hugo-auto-export-mode)))))
    
  • Конфигурация применяется ко всем org-файлам в каталоге.

9.2 Установка на уровне проекта

  • Если org-файлы находятся в некотором каталоге, например в content-org, то в файле .dir-locals.el задаётся конфигурация для этого каталога:
    1(("content-org/"
    2  . ((org-mode . ((eval . (org-hugo-auto-export-mode)))))))
    

9.3 Установка для конкретного файла

  • Для каждого файла можно задать локальные переменные:
    1​* COMMENT Local Variables                          :ARCHIVE:
    2# Local Variables:
    3# eval: (org-hugo-auto-export-mode)
    4# End:
    
  • Рекомендуется добавить заголовок Footnotes перед заголовком Local Variables, чтобы в случае добавления каких-либо сносок они добавлялись в данный раздел.
  • В противном случае будет автоматически создан новый заголовок Footnotes в конце файла, и заголовок Local Variables больше не будет последним и не будет обрабатываться.
  • Перечитать локальные переменные можно командой:
    1M-x normal-mode
    

9.4 Запрет авто сохранения для конкретного файла

  • Для каждого файла можно задать локальные переменные для запрета экспорта:
    1​* COMMENT Local Variables                          :ARCHIVE:
    2# Local Variables:
    3# eval: (org-hugo-auto-export-mode -1)
    4# End:
    

10 Цитирование

10.1 Формат цитирования pandoc

  • Исторический формат цитирования.
  • Рекомендуется перейти на формат цитирования org-cite.

10.2 Формат цитирования org-cite

  • Цитирование основано на org-cite (см. Emacs. Работа с библиографией. Org-cite).
  • Рекомендуется использовать процессор экспорта csl.
  • При задании ключевого слова #+print_bibliography: по умолчанию создаётся секция References.
  • Можно задать другое название для этой секции:
    1(with-eval-after-load 'ox-hugo
    2  (plist-put org-hugo-citations-plist :bibliography-section-heading "Bibliography"))
    
  • Если для этого свойства задана пустая строка, этот заголовок не будет вставлен автоматически 4:
    1(with-eval-after-load 'ox-hugo
    2  (plist-put org-hugo-citations-plist :bibliography-section-heading ""))
    

  1. Если org-hugo-use-code-for-kbd равно nil (по умолчанию). ↩︎

  2. Если org-hugo-use-code-for-kbd не равно nil. Требует настроек CSS для интерпретации тега <kbd>↩︎

  3. Требует настроек CSS для интерпретации тега <underline>↩︎

  4. Так должно быть, но не работает. Вообще литература не печатается. ↩︎


Дмитрий Сергеевич Кулябов
Дмитрий Сергеевич Кулябов
Профессор кафедры теории вероятностей и кибербезопасности

Мои научные интересы включают физику, администрирование Unix и сетей.

Похожие