Publishing
Org includes a publishing management system that allows you to configure automatic HTML conversion of projects composed of interlinked Org files. You can also configure Org to automatically upload your exported HTML pages and related attachments, such as images and source code files, to a web server.
You can also use Org to convert files into PDF, or even combine HTML and PDF conversion so that files are available in both formats on the server.
Publishing has been contributed to Org by David O'Toole.
Configuration
Publishing needs significant configuration to specify files, destination and many other properties of a project.
The variable org-publish-project-alist
Publishing is configured almost entirely through setting the value of
one variable, called org-publish-project-alist. Each element of the
list configures one project, and may be in one of the two following
forms:
("project-name" :property value :property value ...)i.e., a well-formed property list with alternating keys and values, or:
("project-name" :components ("project-name" "project-name" ...))
In both cases, projects are configured by specifying property values.
A project defines the set of files that are to be published, as well
as the publishing configuration to use when publishing those files.
When a project takes the second form listed above, the individual
members of the :components property are taken to be sub-projects,
which group together files requiring different publishing options.
When you publish such a "meta-project", all the components are also
published, in the sequence given.
Sources and destinations for files
Most properties are optional, but some should always be set. In particular, Org needs to know where to look for source files, and where to put published files.
-
:base-directory - Directory containing publishing source files.
-
:publishing-directory - Directory where output files are published. You can directly publish to a web server using a file name syntax appropriate for the Emacs tramp package. Or you can publish to a local directory and use external tools to upload your website (see Uploading Files).
-
:preparation-function -
Function or list of functions to be called before starting the
publishing process, for example, to run
makefor updating files to be published. Each preparation function is called with a single argument, the project property list. -
:completion-function - Function or list of functions called after finishing the publishing process, for example, to change permissions of the resulting files. Each completion function is called with a single argument, the project property list.
Selecting files
By default, all files with extension .org in the base directory are
considered part of the project. This can be modified by setting the
following properties
-
:base-extension -
Extension—without the dot—of source files. This actually is
a regular expression. Set this to the symbol
anyif you want to get all files in:base-directory, even without extension. -
:exclude - Regular expression to match file names that should not be published, even though they have been selected on the basis of their extension.
-
:include -
List of files to be included regardless of
:base-extensionand:exclude. -
:recursive -
Non-
nilmeans, check base-directory recursively for files to publish.
Publishing action
Publishing means that a file is copied to the destination directory
and possibly transformed in the process. The default transformation
is to export Org files as HTML files, and this is done by the function
org-html-publish-to-html which calls the HTML exporter (see HTML Export). But you can also publish your content as PDF files using
org-latex-publish-to-pdf, or as ASCII, Texinfo, etc., using the
corresponding functions.
If you want to publish the Org file as an .org file but with
archived, commented, and tag-excluded trees removed, use
org-org-publish-to-org. This produces file.org and puts it in the
publishing directory. If you want a htmlized version of this file,
set the parameter :htmlized-source to t. It produces
file.org.html in the publishing directory(note: If the publishing
directory is the same as the source directory, file.org is exported
as file.org.org, so you probably do not want to do this.).
Other files like images only need to be copied to the publishing
destination; for this you can use org-publish-attachment. For
non-Org files, you always need to specify the publishing function:
-
:publishing-function - Function executing the publication of a file. This may also be a list of functions, which are all called in turn.
-
:htmlized-source -
Non-
nilmeans, publish an htmlized version of the source.
The function must accept three arguments: a property list containing
at least a :publishing-directory property, the name of the file to
be published, and the path to the publishing directory of the output
file. It should take the specified file, make the necessary
transformation, if any, and place the result into the destination
folder.
Options for the exporters
The property list can be used to set many export options for the HTML and LaTeX exporters. In most cases, these properties correspond to user variables in Org. The table below lists these properties along with the variable they belong to. See the documentation string for the respective variable for details.
When a property is given a value in org-publish-project-alist, its
setting overrides the value of the corresponding user variable, if
any, during publishing. Options set within a file (see Export Settings), however, override everything.
Generic properties
ASCII specific properties
Beamer specific properties
HTML specific properties
LaTeX specific properties
Markdown specific properties
ODT specific properties
Texinfo specific properties
Publishing links
To create a link from one Org file to another, you would use something
like [[file:foo.org][The foo]] or simply [[file:foo.org]] (see
External Links). When published, this link becomes a link to
foo.html. You can thus interlink the pages of your "Org web"
project and the links will work as expected when you publish them to
HTML. If you also publish the Org source file and want to link to it,
use an http link instead of a file: link, because file links are
converted to link to the corresponding .html file.
Links to encrypted Org files, like [[file:foo.org.gpg]] are also
supported.
You may also link to related files, such as images. Provided you are careful with relative file names, and provided you have also configured Org to upload the related files, these links will work too. See Example: complex publishing configuration, for an example of this usage.
Links between published documents can contain some search options (see
Search Options in File Links), which will be resolved to the
appropriate location in the linked file. For example, once published
to HTML, the following links all point to a dedicated anchor in
foo.html.
[[file:foo.org::*heading]] [[file:foo.org::#custom-id]] [[file:foo.org::target]]
Generating a sitemap
The following properties may be used to control publishing of a map of files for a given project.
-
:auto-sitemap -
When non-
nil, publish a sitemap duringorg-publish-current-projectororg-publish-all. -
:sitemap-filename -
Filename for output of sitemap. Defaults to
sitemap.org, which becomessitemap.html. -
:sitemap-title - Title of sitemap page. Defaults to name of file.
-
:sitemap-style -
Can be
list(site-map is just an itemized list of the titles of the files involved) ortree(the directory structure of the source files is reflected in the site-map). Defaults totree. -
:sitemap-format-entry
With this option one can tell how a site-map entry is formatted in
the site-map. It is a function called with three arguments: the
file or directory name relative to base directory of the project,
the site-map style and the current project. It is expected to
return a string. Default value turns file names into links and use
document titles as descriptions. For specific formatting needs, one
can use org-publish-find-date, org-publish-find-title and
org-publish-find-property, to retrieve additional information
about published documents.
-
:sitemap-function -
Plug-in function to use for generation of the sitemap. It is called
with two arguments: the title of the site-map and a representation
of the files and directories involved in the project as a nested
list, which can further be transformed using
org-list-to-generic,org-list-to-subtreeand alike. Default value generates a plain list of links to all files in the project. -
:sitemap-sort-folders -
Where folders should appear in the sitemap. Set this to
first(default) orlastto display folders first or last, respectively. When set toignore, folders are ignored altogether. Any other value mixes files and folders. This variable has no effect when site-map style istree. -
:sitemap-sort-files -
How the files are sorted in the site map. Set this to
alphabetically(default),chronologicallyoranti-chronologically.chronologicallysorts the files with older date first whileanti-chronologicallysorts the files with newer date first.alphabeticallysorts the files alphabetically. The date of a file is retrieved withorg-publish-find-date. -
:sitemap-ignore-case -
Should sorting be case-sensitive? Default
nil.
Generating an index
Org mode can generate an index across the files of a publishing project.
-
:makeindex -
When non-
nil, generate in index in the filetheindex.organd publish it astheindex.html.
The file is created when first publishing a project with the
:makeindex set. The file only contains a statement #+INCLUDE:
"theindex.inc". You can then build around this include statement by
adding a title, style information, etc.
Index entries are specified with INDEX keyword. An entry that
contains an exclamation mark creates a sub item.
*** Curriculum Vitae #+INDEX: CV #+INDEX: Application!CV
Uploading Files
For those people already utilizing third party sync tools such as Rsync or Unison, it might be preferable not to use the built-in remote publishing facilities of Org mode which rely heavily on Tramp. Tramp, while very useful and powerful, tends not to be so efficient for multiple file transfer and has been known to cause problems under heavy usage.
Specialized synchronization utilities offer several advantages. In addition to timestamp comparison, they also do content and permissions/attribute checks. For this reason you might prefer to publish your web to a local directory—possibly even in place with your Org files—and then use Unison or Rsync to do the synchronization with the remote host.
Since Unison, for example, can be configured as to which files to
transfer to a certain remote destination, it can greatly simplify the
project publishing definition. Simply keep all files in the correct
location, process your Org files with org-publish and let the
synchronization tool do the rest. You do not need, in this scenario,
to include attachments such as JPG, CSS or PNG files in the project
definition since the third-party tool syncs them.
Publishing to a local directory is also much faster than to a remote
one, so that you can more easily afford to republish entire projects.
If you set org-publish-use-timestamps-flag to nil, you gain the
main benefit of re-including any changed external files such as source
example files you might include with INCLUDE keyword. The timestamp
mechanism in Org is not smart enough to detect if included files have
been modified.
Sample Configuration
Below we provide two example configurations. The first one is a simple project publishing only a set of Org files. The second example is more complex, with a multi-component project.
Example: simple publishing configuration
This example publishes a set of Org files to the public_html
directory on the local machine.
(setq org-publish-project-alist
'(("org"
:base-directory "~/org/"
:publishing-function org-html-publish-to-html
:publishing-directory "~/public_html"
:section-numbers nil
:with-toc nil
:html-head "<link rel=\"stylesheet\"
href=\"../other/mystyle.css\"
type=\"text/css\"/>")))Example: complex publishing configuration
This more complicated example publishes an entire website, including Org files converted to HTML, image files, Emacs Lisp source code, and style sheets. The publishing directory is remote and private files are excluded.
To ensure that links are preserved, care should be taken to replicate
your directory structure on the web server, and to use relative file
paths. For example, if your Org files are kept in ~/org/ and your
publishable images in ~/images/, you would link to an image with
file:../images/myimage.png
On the web server, the relative path to the image should be the same.
You can accomplish this by setting up an images/ folder in the right
place on the web server, and publishing images to it.
(setq org-publish-project-alist
`(("orgfiles"
:base-directory "~/org/"
:base-extension "org"
:publishing-directory "/ssh:user@host:~/html/notebook/"
:publishing-function org-html-publish-to-html
:exclude ,(rx (or "PrivateFile.org" (seq line-start "private/"))) ;; regexp
:headline-levels 3
:section-numbers nil
:with-toc nil
:html-head "<link rel=\"stylesheet\"
href=\"../other/mystyle.css\" type=\"text/css\"/>"
:html-preamble t)
("images"
:base-directory "~/images/"
:base-extension "jpg\\|gif\\|png"
:publishing-directory "/ssh:user@host:~/html/images/"
:publishing-function org-publish-attachment)
("other"
:base-directory "~/other/"
:base-extension "css\\|el"
:publishing-directory "/ssh:user@host:~/html/other/"
:publishing-function org-publish-attachment)
("website" :components ("orgfiles" "images" "other"))))Triggering Publication
Once properly configured, Org can publish with the following commands:
-
C-c C-e P x(org-publish)
Prompt for a specific project and publish all files that belong to it.
-
C-c C-e P p(org-publish-current-project)
Publish the project containing the current file.
-
C-c C-e P f(org-publish-current-file)
Publish only the current file.
-
C-c C-e P a(org-publish-all)
Publish every project.
Org uses timestamps to track when a file has changed. The above
functions normally only publish changed files. You can override this
and force publishing of all files by giving a prefix argument to any
of the commands above, or by customizing the variable
org-publish-use-timestamps-flag. This may be necessary in
particular if files include other files via SETUPFILE or INCLUDE
keywords.