From: "Juan Manuel Macías" <maciaschain@posteo.net>
To: orgmode <emacs-orgmode@gnu.org>
Subject: [tip] org-publish to work with (very) large books
Date: Thu, 26 May 2022 10:01:02 +0000 [thread overview]
Message-ID: <87y1yovcip.fsf@posteo.net> (raw)
Hi all,
- tl; dr: I describe here my workflow with org-publish to work with long
books.
—
I discovered a long time ago that `org-publish' not only works very well
for managing websites but also for working with long and complex books
with many parts, with output to LaTeX/PDF. I developed a workflow around
it that has been quite productive for me, and that I briefly describe
here in case someone finds it useful and wants to try it or modify/adapt
it to their needs. I usually use it for my typesetting work, but I think
it can also be useful for personal projects, such as doctoral theses.
First of all, each folder of my project-books has the same structure:
two subdirectories named `/org' and `/tex', for the source `org' files
and for the output `.tex' documents, respectively. And, inside the `org'
directory I include a `setup' file, an `elisp' file (for export
filters), and another `/img' directory for image files. Each `org' file
is a part of the book, and usually begins simply with the directives:
┌────
│ #+SETUPFILE: xxx.setup
│ #+INCLUDE: "elisp"
└────
`Org-publish' exports the subdocuments (body only!) as `.tex' documents
in the `/tex' folder, but they are not compiled.
What gets compiled is a master `.org' file, which is also inside the
`org' folder. I compile this master file using an asynchronous function
that calls `latexmk'. I put all the LaTeX configuration, the packages to
load, the (re)defined commands and macros, the necessary Lua code, etc.
in a `.sty' file that I load at the very beginning of the master
document. Subdocuments are loaded into this file by the LaTeX command
(\input), not by the org #+INCLUDE directive. So the master file usually
looks like this:
┌────
│ #+LaTeX_CLASS: my-custom-latex-class
│ #+LaTeX_Header: \input{my-custom-conf.sty}
│ #+SETUPFILE: xxxx.setup
│ #+INCLUDE: "elisp"
│
│ * Part 1
│ ** Chapter 1
│ #+LaTeX: \input{chapter1.tex}
└────
When I eval my function, `latexmk' compiles the entire book with the
`-pvc' option, which keeps the session open, and if it detects any
changes to the entire document, it recompiles and refresh the pdf view.
For example, if I edit one of the subdocuments and run
`org-publish-current-file', everything is automatically recompiled.
When I have the project folder ready, I add this to
`org-publish-project-alist' (this is an example from one of the books I
did recently):
┌────
│ ("cartas-org"
│ :base-directory "~/Git/cartas/libro/org/"
│ :base-extension "org"
│ ;; Directorio para los ficheros *.tex
│ :publishing-directory "~/Git/cartas/libro/tex/"
│ :publishing-function org-latex-publish-to-latex
│ :body-only t ;; this is important!
│ :exclude "cartas-master\\.org\\|bibliografia-cartas\\.org"
│ :recursive t)
│
│ ("cartas-img"
│ :base-directory "~/Git/cartas/libro/org/img/"
│ :base-extension "jpg\\|png"
│ :publishing-directory "~/Git/cartas/libro/tex/img/"
│ :recursive t
│ :publishing-function org-publish-attachment)
│
│ ("cartas" :components ("cartas-tex" "cartas-img"))
└────
And finally, this is the function that compiles everything (each project
usually has some local variables, like the value of ’jobname’ or the
status of the printing proofs).
Nota Bene: The reason for using async is that in some projects,
especially bilingual editions, I need to pre-compile some files first.
Under normal conditions I don't think it's necessary to use async, since
org-publish just exports everything to .tex documents (short timeout)
and then start-process-shell-command run latexmk asynchronously.
Best regards,
Juan Manuel
┌────
│ (require 'async)
│ (require 'projectile)
│
│ (defun latexmk-compile-project-async ()
│ (interactive)
│ (let*
│ ((project-root (projectile-project-root))
│ (master-file (read-file-name "Compile: "
│ (concat project-root "libro/org/")))
│ (master-file-tex (file-name-sans-extension
│ (expand-file-name master-file)))
│ (dir-tex (file-name-directory
│ (expand-file-name
│ (replace-regexp-in-string "/org/" "/tex/" master-file)))))
│ ;; save the master document
│ (with-current-buffer
│ (find-file-noselect master-file)
│ (save-buffer))
│ (async-start
│ (lambda ()
│ (load "~/.emacs")
│ (with-current-buffer
│ (find-file-noselect master-file)
│ (org-show-all)
│ (save-buffer)
│ (org-latex-export-to-latex nil nil nil nil nil))
│ ;; remove all old auxiliary files before compiling
│ (shell-command (concat "rm -r " dir-tex (file-name-base master-file-tex) "*"))
│ (shell-command (concat "mv " master-file-tex ".tex" " " dir-tex))
│ "Document exported")
│ (lambda (resultado)
│ (message resultado)
│ (let
│ ((default-directory dir-tex)
│ (jobname (if (and jobname-local printing-proofs-state)
│ (concat jobname-local "_" printing-proofs-state "_"
│ (format-time-string "%d-%m-%y"))
│ (concat (file-name-sans-extension
│ (file-name-nondirectory master-file-tex))
│ "_"
│ (format-time-string "%d-%m-%y")))))
│ (start-process-shell-command
│ "project"
│ "*project*"
│ (concat
│ "latexmk"
│ " -jobname="
│ jobname
│ " -pvc -lualatex -e '$lualatex=q/lualatex %O -shell-escape %S/' "
│ (file-name-nondirectory master-file-tex)
│ ".tex")))))))
└────
next reply other threads:[~2022-05-26 10:03 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-26 10:01 Juan Manuel Macías [this message]
2022-05-26 12:46 ` [tip] org-publish to work with (very) large books Christian Moe
2022-05-26 13:11 ` Ihor Radchenko
2022-05-26 13:29 ` Christian Moe
2022-05-26 14:15 ` Ihor Radchenko
2022-05-26 13:48 ` Juan Manuel Macías
2022-05-26 17:47 ` Christian Moe
2022-05-27 4:19 ` Ihor Radchenko
2022-05-27 11:39 ` Juan Manuel Macías
2022-05-28 3:02 ` Ihor Radchenko
2022-05-28 8:59 ` Juan Manuel Macías
2022-05-29 12:15 ` Ihor Radchenko
2022-05-29 18:01 ` Juan Manuel Macías
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87y1yovcip.fsf@posteo.net \
--to=maciaschain@posteo.net \
--cc=emacs-orgmode@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).