Элисп, алист и струн; путаница - PullRequest
3 голосов
/ 26 февраля 2012

Я пытаюсь опубликовать org-проект в формате html и автоматизировать задачу с помощью следующего определения проекта org:

(defconst home (file-name-directory (or load-file-name buffer-file-name)))

(require 'org-publish)
(setq org-publish-project-alist
      '(
        ;; add all the components here
        ;; *notes* - publishes org files to html
        ("org-notes"
         :base-directory (concat home "org/")
         :base-extension "org"  ; Filename suffix without dot
         :publishing-directory (concat home "../public_html/")
         :recursive t           ; includes subdirectories
         :publishing-function org-publish-org-to-html
         :headline-levels 4             ; Just the default for this project.
         :auto-preamble t
         :auto-sitemap t                ; generate automagically
         :sitemap-filename "sitemap.org"
         :sitemap-title "Sitemap"
         )

        ;; *static* - copies files to directories
        ("org-static"
         :base-directory (concat home "org/")
         :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf"
         :publishing-directory (concat home "../public_html/")
         :recursive t
         :publishing-function org-publish-attachment
         )

        ;; *publish* with M-x org-publish-project RET emacsclub RET
        ("emacsclub" :components ("org-notes" "org-static"))
        ))

Однако при экспорте проекта выдается ошибка

Неправильный аргумент типа: stringp, (concat home "org")

С точки зрения Элиспа, что, черт возьми, происходит? Разве вывод concat не является строкой? В каком случае это терпит неудачу? Я пытаюсь stringp самостоятельно с аргументом concat, и он возвращает true.

Что-то еще, что я пытаюсь сделать, это экспортировать весь проект, когда этот файл будет оценен. Я пробовал такие вещи, как (команда-выполнить org-publish-all) но он также жалуется на неверный аргумент типа. Что я могу использовать, чтобы сделать это?

1 Ответ

10 голосов
/ 26 февраля 2012

Проблема в том, что цитирование второго аргумента в (setq org-publish-project-alist '(...)) означает, что ничего в этой структуре списка не будет оцениваться. Другими словами, Emacs говорит вам, что значение (concat home "org") не является строкой: на самом деле это список из трех элементов (который при оценке даст вам строку).

Одним из возможных путей решения этой проблемы может быть использование механизма «обратной цитаты» или «квазицитаты», который аналогичен quote или ', но позволяет выборочно объединять биты оцененного кода Лиспа, используя , и * 1008. *. (Подробнее см. (elisp)Backquote в руководстве Info). Таким образом, вы можете изменить свой код выше на что-то вроде

(setq org-publish-project-alist
  `(                            ; note ` instead of '
    ("org-notes"
     ;; Note commas , in front of code to evaluate
     :base-directory ,(concat home "org/")
     :base-extension "org"
     :publishing-directory ,(concat home "../public_html/")
     ....

Обратите внимание, что кусочки без кавычек будут оцениваться и вставляться в список только один раз, когда оценивается форма (setq ...): другими словами, это не поможет вам, если вам нужно, чтобы эти значения динамически изменялись для другого проекта каталоги. Но так как вы определяете home как константу, может это не имеет значения?

PS: Если вам нужно более подробно выяснить, откуда происходят ваши wrong-type-argument ошибки, попробуйте выполнить M-x toggle-debug-on-error или оценить (setq debug-on-error t), чтобы получить подробный обратный след.

...