Как добавить "# + ATTR_ HTML" к выводу предварительного просмотра "# + RESULTS" исходного блока в режиме Org Emacs? - PullRequest
1 голос
/ 23 апреля 2020

Я использую Plantuml в org, и он работает нормально. Однако я пытаюсь внести некоторые изменения, автоматически добавив тег HTML непосредственно перед тегом вывода # + RESULTS , чтобы получить прекрасный HTML выходной эффект.

Мой пример кода выглядит следующим образом:

#+BEGIN_SRC plantuml :file test.png
@startuml

  package "Some Group" {
          HTTP - [First Component]
          [Another Component]
  }

  node "Other Groups" {
          FTP - [Second Component]
          [First Component] --> FTP
  } 

  cloud {
          [Example 1]
  }


  database "MySql" {
          folder "This is my folder" {
                  [Folder 3]
          }
          frame "Foo" {
                  [Frame 4]
          }
  }


  [Another Component] --> [Example 1]
  [Example 1] --> [Folder 3]
  [Folder 3] --> [Frame 4]

  @enduml
#+END_SRC

После "C - c C - c" plantuml вы получите следующий вывод чуть ниже блока кода plantuml:

#+RESULTS:
[[file:test.png]]

Однако, я хочу, чтобы автоматически добавлял вышеупомянутые теги # + RESULT , как показано ниже, что будет показано ниже под исходным блоком plantuml в Emacs:

#+ATTR_HTML: :width 80% 
#+ATTR_ORG: :width 80% 
#+ATTR_HTML: :style background-color: white; border-radius: 8px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
#+RESULTS:
[[file:test.png]]

Затем я могу вывести файл org в HTML с помощью "C - c C -eho" и получить красивый HTML.

Как я могу это сделать?

Спасибо!

1 Ответ

0 голосов
/ 29 апреля 2020

Стандартным способом является присвоение имени исходному блоку:

#+NAME: foo
#+BEGIN_SRC plantuml :file test.png
@startuml
...
#+END_SRC

Когда вы оцениваете блок кода, он создаст заголовок #+RESULTS:, подобный следующему:

#+RESULTS: foo
[[file:test.png]]

Теперь вы можете добавить свои объявления #+ATTR_* перед результатом:

#+ATTR_HTML: :width 80% 
#+ATTR_ORG: :width 
#+ATTR_HTML: :style background-color: white; border-radius: 8px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
#+RESULTS: foo
[[file:test.png]]

Повторный запуск блока кода поместит ссылку на файл в то же место и оставит материал #+ATTR-* в покое. Затем вы можете экспортировать и получить «красивый HTML»!

РЕДАКТИРОВАТЬ: основной упор вышеописанного избегает ручной работы, которая потребовалась бы, если бы блок был НЕ с именем: вам придется продолжать перемещать объявления атрибутов во вновь сгенерированный раздел # + RESULTS: после каждой переоценки исходного блока (и очистки старых результатов). Из моего POV, это раздражающая часть, и наименование блока очень хорошо об этом заботится.

Добавление объявлений атрибутов становится единовременной задачей, которую я не особенно wi * 1052. * для автоматизации, главным образом потому, что атрибуты должны быть разными для разных блоков, поэтому все, что я делаю для одного блока, должно быть полностью изменено для другого: я бы предпочел выполнять разовые задачи вручную.

Тем не менее, вы можете частично автоматизировать вставку атрибута, например, создав функцию для вставки и привязав ее к ключу:

(defun insert-attr-decls ()
  (interactive)
  (insert "#+ATTR_HTML: :width 80%\n")
  (insert "#+ATTR_ORG: :width 80%\n") 
  (insert "#+ATTR_HTML: :style background-color: white; border-radius: 8px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n"))

(define-key org-mode-map [f10] 'insert-attr-decls)

Затем после первой оценки поместите точку непосредственно перед #+RESULTS: foo сгенерированная строка и нажмите F10. Из моего POV я бы остановился (если бы зашел так далеко).

Следующим шагом будет поиск места, где вставка должна go, и затем вызов функция выше - что-то вроде этого, хотя я уверен, что ее можно улучшить:

(defun insert-attr-decls ()
  (insert "#+ATTR_HTML: :width 80%\n")
  (insert "#+ATTR_ORG: :width 80%\n") 
  (insert "#+ATTR_HTML: :style background-color: white; border-radius: 8px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);\n"))

(defun insert-attr-decls-at (s)
  (let ((case-fold-search t))
   (if (search-forward s nil t)
    (progn 
       (search-backward s nil t)
       (insert-attr-decls)))))

(defun insert-attr-decls-at-results ()
  (interactive)
  (save-excursion
   (insert-attr-decls-at "#+RESULTS:")))

(define-key org-mode-map [f10] 'insert-attr-decls-at-results)

Это уже квантовый скачок сложности и, вероятно, содержит ошибки: что произойдет, например, если нет #+RESULTS: строка в буфере? Я не проверял. Так что, если кто-то еще хочет потратить время на создание «идеальной» функции, тогда да, может быть, я возьму ее и использую. Но если это не будет моей обычной работой, я бы предпочел провести свое время в другом месте: вы всегда можете автоматизировать его позже, если это действительно приведет к потере времени.

Следующий шаг ( что я бы не сделал) было бы C-c C-c оценить блок и добавить объявления атрибутов. Вы можете сделать это, добавив insert-attr-decls-at-results к переменной org-babel-after-execute-hook:

(add-hook 'org-babel-after-execute-hook 'insert-attr-decls-at-results)

Проблема здесь в том, что при каждой оценке вы получите еще один добавленный блок объявления атрибута : вам действительно нужно переписать функцию вставки, чтобы проверить, есть ли блок объявления атрибута, и если это так, ничего не делать. Это просто упражнение.

Мораль истории AFAIA C такова: вы можете автоматизировать все, но не все стоит автоматизировать.

...