├── example
├── eg0.png
├── eg0.org
└── eg0.html
├── README.org
└── ox-twbs.el
/example/eg0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marsmining/ox-twbs/HEAD/example/eg0.png
--------------------------------------------------------------------------------
/example/eg0.org:
--------------------------------------------------------------------------------
1 | #+TITLE: Example
2 |
3 | * Basics
4 |
5 | You can make words *bold*, /italic/, _underlined_, =code= and
6 | ~verbatim~, and, if you must, +strike-through+. Text in the code and
7 | verbatim string is not processed for Org mode specific syntax, it is
8 | exported verbatim.
9 |
10 | Some Greek like \alpha, \beta and \gamma.
11 |
12 | And here is an example link to [[http://orgmode.org/][org-mode]] homepage.
13 |
14 | * Headlines
15 |
16 | text
17 |
18 | ** Alpha
19 |
20 | text
21 |
22 | *** Bravo
23 |
24 | text
25 |
26 | * Lists
27 |
28 | - List Item 0
29 | - List Item 1
30 | - List Item 2
31 | - List Item 3
32 |
33 | * Blocks
34 | :PROPERTIES:
35 | :CUSTOM_ID: blocks
36 | :END:
37 |
38 | *** Normal blocks
39 |
40 | : Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
41 | : eiusmod tempor incididunt ut labore et dolore magna aliqua.
42 |
43 | *** Quote blocks
44 |
45 | #+BEGIN_QUOTE
46 | Programs must be written for people to read, and only incidentally
47 | for machines to execute.
48 |
49 | /Abelson & Sussman, SICP, preface to the first edition/
50 | #+END_QUOTE
51 |
52 | *** Source code blocks
53 |
54 | #+BEGIN_SRC elisp
55 | (defun yell (n)
56 | (if (= n 0) "hiya"
57 | (concat (yell (- n 1)) "!")))
58 |
59 | (yell 5) ;; "hiya!!!!"
60 | #+END_SRC
61 |
62 | * Tables
63 |
64 | | Name | Price | Freshwater | Family |
65 | |-----------+-------+------------+---------------|
66 | | Stingray | 49.99 | no | Myliobatoidei |
67 | | Salmon | 23.99 | both | Salmonidae |
68 | | Barracuda | 12.99 | no | Sphyraena |
69 |
70 | * Sections
71 |
72 | ** Lord of the Rings
73 |
74 | My favorite scenes are (in this order)
75 |
76 | 1. The attack of the Rohirrim
77 | 2. Eowyn's fight with the witch king
78 | + this was already my favorite scene in the book
79 | + I really like Miranda Otto.
80 | 3. Peter Jackson being shot by Legolas
81 | - on DVD only
82 | He makes a really funny face when it happens.
83 |
84 | But in the end, no individual scenes matter but the film as a whole.
85 |
86 | Important actors in this film are:
87 |
88 | - Elijah Wood :: He plays Frodo
89 | - Sean Austin :: He plays Sam, Frodo's friend. I still remember
90 | him very well from his role as Mikey Walsh in The Goonies.
91 |
92 | * HTML
93 |
94 | Here is some markup: not bold text
95 |
96 | And a source block:
97 |
98 | #+BEGIN_SRC html
99 | pow!
100 | #+END_SRC
101 |
102 | #+BEGIN_HTML
103 | pow!
104 |
105 |
bing
106 |
bam
107 |
boom
108 |
109 | #+END_HTML
110 |
111 | #+HTML: italics
112 |
113 | Finally inline: @@html:@@bold text@@html:@@
114 |
115 | See org-mode manual [[http://orgmode.org/manual/Quoting-HTML-tags.html#Quoting-HTML-tags][Quoting HTML tags]].
116 |
117 | * Footnote
118 |
119 | Here lies exact instructions [fn:a] for random [fn:b] noise.
120 |
121 | * Latex
122 |
123 | /Trace execution using example:/
124 |
125 | Assume $\alpha=9$, $n=16$ and $x=0$.
126 |
127 | Stack grows until base case $2^{x}=n$, thenunwinds.
128 |
129 | * Custom ID
130 |
131 | [[#blocks][Link to custom id]]
132 |
133 | [fn:a] Except for USA, Mexico and Canada
134 |
135 | [fn:b] Further tournament types will be added
136 |
--------------------------------------------------------------------------------
/README.org:
--------------------------------------------------------------------------------
1 | * ox-twbs
2 |
3 | ** Summary
4 |
5 | Export [[http://orgmode.org/][org-mode]] docs as HTML compatible with [[http://getbootstrap.com/][Twitter Bootstrap]].
6 |
7 | ** Example
8 |
9 | The following [[https://raw.githubusercontent.com/marsmining/ox-twbs/master/example/eg0.org][org source]] exports to [[http://clubctrl.com/org/prog/ox-twbs.html][this html]].
10 |
11 | ** Description
12 |
13 | Output your org-mode docs with a simple, clean and modern look.
14 |
15 | This library implements a new HTML back-end for exporting org-mode
16 | docs as HTML compatible with Twitter Bootstrap. By default, HTML is
17 | exported with jQuery and Bootstrap resources included via [[http://osscdn.com][osscdn]].
18 |
19 | Derived from the built-in HTML back-end of [[http://www.gnu.org/software/emacs/][GNU Emacs]], =ox-html.el=,
20 | which was written by Carsten Dominik and Jambunathan K.
21 |
22 | ** Install
23 |
24 | *** via package.el
25 |
26 | Latest builds available on [[http://melpa.org/#/][MELPA]] and for a bit more stability, use
27 | [[http://stable.melpa.org/#/][MELPA Stable]]. You can install ~ox-twbs~ using the following command:
28 |
29 | =M-x package-install [RET] ox-twbs [RET]=
30 |
31 | If the installation doesn't work try refreshing the package list:
32 |
33 | =M-x package-refresh-contents [RET]=
34 |
35 | *** Manual
36 |
37 | Put ~ox-twbs.el~ in your load path and require it. Alternatively, open
38 | =ox-twbs.el= in your buffer and run =package-install-file=, which will
39 | compile and install the package in your package folder.
40 |
41 | ** Usage
42 |
43 | Open or create an org file and run ~org-twbs-export-to-html~. This
44 | will create an HTML file in the same dir as your org file.
45 |
46 | You will more likely want more control and automation of the export
47 | process. You can read [[http://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html][the org-mode docs]] on setting up your project. An
48 | example configuration might look like:
49 |
50 | #+BEGIN_SRC elisp
51 | (setq org-publish-project-alist
52 | '(("org-notes"
53 | :base-directory "~/org/"
54 | :publishing-directory "~/public_html/"
55 | :publishing-function org-twbs-publish-to-html
56 | :with-sub-superscript nil
57 | )))
58 | #+END_SRC
59 |
60 | Using the above config, you can run: =org-publish-all=
61 |
62 | And you might create a function which publishes the current buffers
63 | file and opens it in your system's default browser. Here is what I
64 | use in my emacs config:
65 |
66 | #+BEGIN_SRC elisp
67 | (defun my-org-publish-buffer ()
68 | (interactive)
69 | (save-buffer)
70 | (save-excursion (org-publish-current-file))
71 | (let* ((proj (org-publish-get-project-from-filename buffer-file-name))
72 | (proj-plist (cdr proj))
73 | (rel (file-relative-name buffer-file-name
74 | (plist-get proj-plist :base-directory)))
75 | (dest (plist-get proj-plist :publishing-directory)))
76 | (browse-url (concat "file://"
77 | (file-name-as-directory (expand-file-name dest))
78 | (file-name-sans-extension rel)
79 | ".html"))))
80 | #+END_SRC
81 |
82 | And bind the above command. I'm on OSX and happen to use ~CMD-\~.
83 |
84 | #+BEGIN_SRC elisp
85 | (add-hook 'org-mode-hook
86 | (lambda ()
87 | (local-set-key (kbd "s-\\") 'my-org-publish-buffer)))
88 | #+END_SRC
89 |
90 | ** General Org Tips
91 |
92 | To specify a title of your org doc, other than the default:
93 |
94 | : #+TITLE: My Doc
95 |
96 | To quickly add blocks, check this [[http://orgmode.org/manual/Easy-Templates.html#Easy-Templates][easy template]] section of org manual.
97 |
98 | Be sure to understand how to [[http://orgmode.org/manual/Editing-source-code.html#Editing-source-code][edit source code blocks]].
99 |
100 | Controlling depth of section numbers, table of contents and headings
101 | can be controlled per document via a declaration like the following:
102 |
103 | : #+OPTIONS: num:5 whn:2 toc:4 H:6
104 |
105 | And to set these via your publish configuration using the
106 | =org-publish-project-alist=, the options would be =:section-numbers=,
107 | =:headline-levels= and =:with-toc=.
108 |
109 | The above options are described in the [[http://orgmode.org/manual/Export-settings.html][export settings]] section of the
110 | orgmode manual. This component introduces a new setting =whn= for per
111 | document, and =:with-headline-numbers= for publish config, which
112 | controls the display of section numbers. To disable, set to =nil=, to
113 | enable, set to =t=, and to control depth of display, use a whole
114 | number.
115 |
116 | ** Note re: latest Org 8.3.x
117 |
118 | Traditionally preventing section numbers from display was
119 | accomplished via the =:section-numbers= option, however, in 8.3.x,
120 | setting it to =nil= now also eliminates the numbering from the parsed
121 | document, which then breaks toc and linking. Therefore, this module
122 | introduces a new option =:with-headline-numbers= which can be used for
123 | toggling display of section numbers.
124 |
125 | ** Customize
126 |
127 | The first place to look is in the definition of [[https://github.com/marsmining/ox-twbs/blob/d5ae9c3fb224d081d59d3686d619edf152523f09/ox-twbs.el#L987-L1002][org-twbs-head]]. You can
128 | set this on a per-file basis using ~#+HTML_HEAD:~, or for publication
129 | projects using the ~:html-head~ property.
130 |
131 | ** Todo
132 |
133 | Contributions are welcome! A list of potential fixes and enhancements
134 | follows:
135 |
136 | - Allow users to more easily add a Twitter Bootstrap theme
137 | - Document areas where this package deviates from org-mode manual on
138 | [[http://orgmode.org/manual/HTML-export.html#HTML-export][HTML export]]
139 | - Improve Affix.js plugin scroll-spying/following
140 | - Ensure this package works well with org's sitemap function
141 |
--------------------------------------------------------------------------------
/example/eg0.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Example
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
172 |
184 |
185 |
186 |
187 |
188 |
Example
189 |
190 |
191 |
1 Basics
192 |
193 |
194 | You can make words bold, italic, underlined, code and
195 | verbatim, and, if you must, strike-through. Text in the code and
196 | verbatim string is not processed for Org mode specific syntax, it is
197 | exported verbatim.
198 |
199 |
200 |
201 | Some Greek like α, β and γ.
202 |
203 |
204 |
205 | And here is an example link to org-mode homepage.
206 |
207 |
208 |
209 |
210 |
211 |
2 Headlines
212 |
213 |
214 | text
215 |
216 |
217 |
218 |
219 |
2.1 Alpha
220 |
221 |
222 | text
223 |
224 |
225 |
226 |
227 |
2.1.1 Bravo
228 |
229 |
230 | text
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
3 Lists
239 |
240 |
241 |
List Item 0
242 |
243 |
List Item 1
244 |
245 |
List Item 2
246 |
247 |
List Item 3
248 |
249 |
250 |
251 |
252 |
253 |
254 |
4 Blocks
255 |
256 |
257 |
258 |
259 |
4.0.1 Normal blocks
260 |
261 |
262 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
263 | eiusmod tempor incididunt ut labore et dolore magna aliqua.
264 |
265 |
266 |
267 |
268 |
269 |
4.0.2 Quote blocks
270 |
271 |
272 |
273 | Programs must be written for people to read, and only incidentally
274 | for machines to execute.
275 |
276 |
277 |
278 | Abelson & Sussman, SICP, preface to the first edition
279 |
479 | Further tournament types will be added
480 |
481 |
482 |
483 |
484 |
508 |
509 |
515 |
516 |
517 |
--------------------------------------------------------------------------------
/ox-twbs.el:
--------------------------------------------------------------------------------
1 | ;;; ox-twbs.el --- Bootstrap compatible HTML Back-End for Org
2 |
3 | ;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
4 | ;; Copyright (C) 2016 Brandon van Beekum
5 |
6 | ;; Author: Carsten Dominik
7 | ;; Jambunathan K
8 | ;; Brandon van Beekum
9 | ;; URL: https://github.com/marsmining/ox-twbs
10 | ;; Keywords: org, html, publish, twitter, bootstrap
11 | ;; Version: 1.1.4
12 |
13 | ;; This file is not part of GNU Emacs.
14 |
15 | ;;; Commentary:
16 |
17 | ;; This library implements an HTML back-end for exporting org-mode
18 | ;; docs as HTML compatible with Twitter Bootstrap. Use the function
19 | ;; `org-twbs-export-to-html` to export an org file. For publishing
20 | ;; use the function `org-twbs-publish-to-html`.
21 |
22 | ;;; License:
23 |
24 | ;; This program is free software; you can redistribute it and/or
25 | ;; modify it under the terms of the GNU General Public License
26 | ;; as published by the Free Software Foundation; either version 3
27 | ;; of the License, or (at your option) any later version.
28 | ;;
29 | ;; This program is distributed in the hope that it will be useful,
30 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
31 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 | ;; GNU General Public License for more details.
33 | ;;
34 | ;; You should have received a copy of the GNU General Public License
35 | ;; along with GNU Emacs; see the file COPYING. If not, write to the
36 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
37 | ;; Boston, MA 02110-1301, USA.
38 |
39 | ;;; Code:
40 |
41 | ;;; Dependencies
42 |
43 | (require 'ox-publish)
44 | (require 'format-spec)
45 | (eval-when-compile (require 'cl) (require 'table nil 'noerror))
46 |
47 |
48 | ;;; Function Declarations
49 |
50 | (declare-function org-id-find-id-file "org-id" (id))
51 | (declare-function htmlize-region "ext:htmlize" (beg end))
52 | (declare-function org-pop-to-buffer-same-window
53 | "org-compat" (&optional buffer-or-name norecord label))
54 | (declare-function mm-url-decode-entities "mm-url" ())
55 |
56 | ;;; Define Back-End
57 |
58 | (org-export-define-backend 'twbs
59 | '((bold . org-twbs-bold)
60 | (center-block . org-twbs-center-block)
61 | (clock . org-twbs-clock)
62 | (code . org-twbs-code)
63 | (drawer . org-twbs-drawer)
64 | (dynamic-block . org-twbs-dynamic-block)
65 | (entity . org-twbs-entity)
66 | (example-block . org-twbs-example-block)
67 | (export-block . org-twbs-export-block)
68 | (export-snippet . org-twbs-export-snippet)
69 | (fixed-width . org-twbs-fixed-width)
70 | (footnote-definition . org-twbs-footnote-definition)
71 | (footnote-reference . org-twbs-footnote-reference)
72 | (headline . org-twbs-headline)
73 | (horizontal-rule . org-twbs-horizontal-rule)
74 | (inline-src-block . org-twbs-inline-src-block)
75 | (inlinetask . org-twbs-inlinetask)
76 | (inner-template . org-twbs-inner-template)
77 | (italic . org-twbs-italic)
78 | (item . org-twbs-item)
79 | (keyword . org-twbs-keyword)
80 | (latex-environment . org-twbs-latex-environment)
81 | (latex-fragment . org-twbs-latex-fragment)
82 | (line-break . org-twbs-line-break)
83 | (link . org-twbs-link)
84 | (paragraph . org-twbs-paragraph)
85 | (plain-list . org-twbs-plain-list)
86 | (plain-text . org-twbs-plain-text)
87 | (planning . org-twbs-planning)
88 | (property-drawer . org-twbs-property-drawer)
89 | (quote-block . org-twbs-quote-block)
90 | (quote-section . org-twbs-quote-section)
91 | (radio-target . org-twbs-radio-target)
92 | (section . org-twbs-section)
93 | (special-block . org-twbs-special-block)
94 | (src-block . org-twbs-src-block)
95 | (statistics-cookie . org-twbs-statistics-cookie)
96 | (strike-through . org-twbs-strike-through)
97 | (subscript . org-twbs-subscript)
98 | (superscript . org-twbs-superscript)
99 | (table . org-twbs-table)
100 | (table-cell . org-twbs-table-cell)
101 | (table-row . org-twbs-table-row)
102 | (target . org-twbs-target)
103 | (template . org-twbs-template)
104 | (timestamp . org-twbs-timestamp)
105 | (underline . org-twbs-underline)
106 | (verbatim . org-twbs-verbatim)
107 | (verse-block . org-twbs-verse-block))
108 | :filters-alist '((:filter-final-output . org-twbs-final-function))
109 | :menu-entry
110 | '(?w "Export to TWBS HTML"
111 | ((?H "As HTML buffer" org-twbs-export-as-html)
112 | (?h "As HTML file" org-twbs-export-to-html)
113 | (?o "As HTML file and open"
114 | (lambda (a s v b)
115 | (if a (org-twbs-export-to-html t s v b)
116 | (org-open-file (org-twbs-export-to-html nil s v b)))))))
117 | :options-alist
118 | '((:html-extension nil nil org-twbs-extension)
119 | (:html-link-org-files-as-html nil nil org-twbs-link-org-files-as-html)
120 | (:html-container "HTML_CONTAINER" nil org-twbs-container-element)
121 | (:html-link-use-abs-url nil "html-link-use-abs-url" org-twbs-link-use-abs-url)
122 | (:html-link-home "HTML_LINK_HOME" nil org-twbs-link-home)
123 | (:html-link-up "HTML_LINK_UP" nil org-twbs-link-up)
124 | (:html-mathjax "HTML_MATHJAX" nil "" space)
125 | (:html-mathjax-options nil nil org-twbs-mathjax-options)
126 | (:html-mathjax-template nil nil org-twbs-mathjax-template)
127 | (:html-postamble nil "html-postamble" org-twbs-postamble)
128 | (:html-preamble nil "html-preamble" org-twbs-preamble)
129 | (:html-head "HTML_HEAD" nil org-twbs-head newline)
130 | (:html-head-extra "HTML_HEAD_EXTRA" nil org-twbs-head-extra newline)
131 | (:html-head-include-default-style nil "html-style" org-twbs-head-include-default-style)
132 | (:html-head-include-scripts nil "html-scripts" org-twbs-head-include-scripts)
133 | (:html-table-attributes nil nil org-twbs-table-default-attributes)
134 | (:html-table-row-tags nil nil org-twbs-table-row-tags)
135 | (:html-inline-images nil nil org-twbs-inline-images)
136 | (:html-inline-image-rules nil nil org-twbs-inline-image-rules)
137 | ;; Redefine regular options.
138 | (:creator "CREATOR" nil org-twbs-creator-string)
139 | (:with-latex nil "tex" org-twbs-with-latex)
140 | (:with-toc nil nil 2)
141 | (:with-creator nil nil t)
142 | (:section-numbers nil nil t)
143 | ;; Extra Options
144 | (:gid nil "gid" nil)
145 | (:with-headline-numbers nil "whn" t)
146 | (:with-toc-todo-keywords nil "toc-todo" nil)
147 | (:with-toc-tags nil "toc-tag" nil)
148 | ;; Retrieve LaTeX header for fragments.
149 | (:latex-header "LATEX_HEADER" nil nil newline)))
150 |
151 |
152 | ;;; Internal Variables
153 |
154 | (defvar org-twbs-format-table-no-css)
155 | (defvar htmlize-buffer-places) ; from htmlize.el
156 |
157 | (defvar org-twbs--pre/postamble-class ""
158 | "CSS class used for pre/postamble")
159 |
160 | (defconst org-twbs-special-string-regexps
161 | '(("\\\\-" . "") ; shy
162 | ("---\\([^-]\\)" . "—\\1") ; mdash
163 | ("--\\([^-]\\)" . "–\\1") ; ndash
164 | ("\\.\\.\\." . "…")) ; hellip
165 | "Regular expressions for special string conversion.")
166 |
167 | (defconst org-twbs-scripts
168 | ""
179 | "Basic JavaScript that is needed by HTML files produced by Org mode.")
180 |
181 | (defconst org-twbs-style-default
182 | ""
349 | "The default style specification for exported HTML files.
350 | You can use `org-twbs-head' and `org-twbs-head-extra' to add to
351 | this style. If you don't want to include this default style,
352 | customize `org-twbs-head-include-default-style'.")
353 |
354 |
355 | ;;; User Configuration Variables
356 |
357 | (defgroup org-export-twbs nil
358 | "Options for exporting Org mode files to HTML compatible with Twitter's Bootstrap."
359 | :tag "Org Export TWBS"
360 | :group 'org-export)
361 |
362 | ;;;; Bold, etc.
363 |
364 | (defcustom org-twbs-text-markup-alist
365 | '((bold . "%s")
366 | (code . "%s")
367 | (italic . "%s")
368 | (strike-through . "%s")
369 | (underline . "%s")
370 | (verbatim . "%s"))
371 | "Alist of HTML expressions to convert text markup.
372 |
373 | The key must be a symbol among `bold', `code', `italic',
374 | `strike-through', `underline' and `verbatim'. The value is
375 | a formatting string to wrap fontified text with.
376 |
377 | If no association can be found for a given markup, text will be
378 | returned as-is."
379 | :group 'org-export-twbs
380 | :version "24.4"
381 | :package-version '(Org . "8.0")
382 | :type '(alist :key-type (symbol :tag "Markup type")
383 | :value-type (string :tag "Format string"))
384 | :options '(bold code italic strike-through underline verbatim))
385 |
386 | (defcustom org-twbs-indent nil
387 | "Non-nil means to indent the generated HTML.
388 | Warning: non-nil may break indentation of source code blocks."
389 | :group 'org-export-twbs
390 | :version "24.4"
391 | :package-version '(Org . "8.0")
392 | :type 'boolean)
393 |
394 | (defcustom org-twbs-use-unicode-chars nil
395 | "Non-nil means to use unicode characters instead of HTML entities."
396 | :group 'org-export-twbs
397 | :version "24.4"
398 | :package-version '(Org . "8.0")
399 | :type 'boolean)
400 |
401 | ;;;; Drawers
402 |
403 | (defcustom org-twbs-format-drawer-function
404 | (lambda (name contents) contents)
405 | "Function called to format a drawer in HTML code.
406 |
407 | The function must accept two parameters:
408 | NAME the drawer name, like \"LOGBOOK\"
409 | CONTENTS the contents of the drawer.
410 |
411 | The function should return the string to be exported.
412 |
413 | For example, the variable could be set to the following function
414 | in order to mimic default behaviour:
415 |
416 | The default value simply returns the value of CONTENTS."
417 | :group 'org-export-twbs
418 | :version "24.4"
419 | :package-version '(Org . "8.0")
420 | :type 'function)
421 |
422 | ;;;; Footnotes
423 |
424 | (defcustom org-twbs-footnotes-section "
425 |
%s:
426 |
427 | %s
428 |
429 |
"
430 | "Format for the footnotes section.
431 | Should contain a two instances of %s. The first will be replaced with the
432 | language-specific word for \"Footnotes\", the second one will be replaced
433 | by the footnotes themselves."
434 | :group 'org-export-twbs
435 | :type 'string)
436 |
437 | (defcustom org-twbs-footnote-format "%s"
438 | "The format for the footnote reference.
439 | %s will be replaced by the footnote reference itself."
440 | :group 'org-export-twbs
441 | :type 'string)
442 |
443 | (defcustom org-twbs-footnote-separator ", "
444 | "Text used to separate footnotes."
445 | :group 'org-export-twbs
446 | :type 'string)
447 |
448 | ;;;; Headline
449 |
450 | (defcustom org-twbs-toplevel-hlevel 2
451 | "The level for level 1 headings in HTML export.
452 | This is also important for the classes that will be wrapped around headlines
453 | and outline structure. If this variable is 1, the top-level headlines will
454 | be
, and the corresponding classes will be outline-1, section-number-1,
455 | and outline-text-1. If this is 2, all of these will get a 2 instead.
456 | The default for this variable is 2, because we use
for formatting the
457 | document title."
458 | :group 'org-export-twbs
459 | :type 'integer)
460 |
461 | (defcustom org-twbs-format-headline-function 'ignore
462 | "Function to format headline text.
463 |
464 | This function will be called with 5 arguments:
465 | TODO the todo keyword (string or nil).
466 | TODO-TYPE the type of todo (symbol: `todo', `done', nil)
467 | PRIORITY the priority of the headline (integer or nil)
468 | TEXT the main headline text (string).
469 | TAGS the tags (string or nil).
470 |
471 | The function result will be used in the section format string."
472 | :group 'org-export-twbs
473 | :version "24.4"
474 | :package-version '(Org . "8.0")
475 | :type 'function)
476 |
477 | ;;;; HTML-specific
478 |
479 | (defcustom org-twbs-allow-name-attribute-in-anchors t
480 | "When nil, do not set \"name\" attribute in anchors.
481 | By default, anchors are formatted with both \"id\" and \"name\"
482 | attributes, when appropriate."
483 | :group 'org-export-twbs
484 | :version "24.4"
485 | :package-version '(Org . "8.0")
486 | :type 'boolean)
487 |
488 | ;;;; Inlinetasks
489 |
490 | (defcustom org-twbs-format-inlinetask-function 'ignore
491 | "Function called to format an inlinetask in HTML code.
492 |
493 | The function must accept six parameters:
494 | TODO the todo keyword, as a string
495 | TODO-TYPE the todo type, a symbol among `todo', `done' and nil.
496 | PRIORITY the inlinetask priority, as a string
497 | NAME the inlinetask name, as a string.
498 | TAGS the inlinetask tags, as a list of strings.
499 | CONTENTS the contents of the inlinetask, as a string.
500 |
501 | The function should return the string to be exported."
502 | :group 'org-export-twbs
503 | :version "24.4"
504 | :package-version '(Org . "8.0")
505 | :type 'function)
506 |
507 | ;;;; LaTeX
508 |
509 | (defcustom org-twbs-with-latex org-export-with-latex
510 | "Non-nil means process LaTeX math snippets.
511 |
512 | When set, the exporter will process LaTeX environments and
513 | fragments.
514 |
515 | This option can also be set with the +OPTIONS line,
516 | e.g. \"tex:mathjax\". Allowed values are:
517 |
518 | nil Ignore math snippets.
519 | `verbatim' Keep everything in verbatim
520 | `dvipng' Process the LaTeX fragments to images. This will also
521 | include processing of non-math environments.
522 | `imagemagick' Convert the LaTeX fragments to pdf files and use
523 | imagemagick to convert pdf files to png files.
524 | `mathjax' Do MathJax preprocessing and arrange for MathJax.js to
525 | be loaded.
526 | t Synonym for `mathjax'."
527 | :group 'org-export-twbs
528 | :version "24.4"
529 | :package-version '(Org . "8.0")
530 | :type '(choice
531 | (const :tag "Do not process math in any way" nil)
532 | (const :tag "Use dvipng to make images" dvipng)
533 | (const :tag "Use imagemagick to make images" imagemagick)
534 | (const :tag "Use MathJax to display math" mathjax)
535 | (const :tag "Leave math verbatim" verbatim)))
536 |
537 | ;;;; Links :: Generic
538 |
539 | (defcustom org-twbs-link-org-files-as-html t
540 | "Non-nil means make file links to `file.org' point to `file.html'.
541 | When `org-mode' is exporting an `org-mode' file to HTML, links to
542 | non-html files are directly put into a href tag in HTML.
543 | However, links to other Org-mode files (recognized by the
544 | extension `.org.) should become links to the corresponding html
545 | file, assuming that the linked `org-mode' file will also be
546 | converted to HTML.
547 | When nil, the links still point to the plain `.org' file."
548 | :group 'org-export-twbs
549 | :type 'boolean)
550 |
551 | ;;;; Links :: Inline images
552 |
553 | (defcustom org-twbs-inline-images t
554 | "Non-nil means inline images into exported HTML pages.
555 | This is done using an tag. When nil, an anchor with href is used to
556 | link to the image."
557 | :group 'org-export-twbs
558 | :version "24.4"
559 | :package-version '(Org . "8.1")
560 | :type 'boolean)
561 |
562 | (defcustom org-twbs-inline-image-rules
563 | '(("file" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
564 | ("http" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'")
565 | ("https" . "\\.\\(jpeg\\|jpg\\|png\\|gif\\|svg\\)\\'"))
566 | "Rules characterizing image files that can be inlined into HTML.
567 | A rule consists in an association whose key is the type of link
568 | to consider, and value is a regexp that will be matched against
569 | link's path."
570 | :group 'org-export-twbs
571 | :version "24.4"
572 | :package-version '(Org . "8.0")
573 | :type '(alist :key-type (string :tag "Type")
574 | :value-type (regexp :tag "Path")))
575 |
576 | ;;;; Plain Text
577 |
578 | (defcustom org-twbs-protect-char-alist
579 | '(("&" . "&")
580 | ("<" . "<")
581 | (">" . ">"))
582 | "Alist of characters to be converted by `org-twbs-protect'."
583 | :group 'org-export-twbs
584 | :type '(repeat (cons (string :tag "Character")
585 | (string :tag "HTML equivalent"))))
586 |
587 | ;;;; Src Block
588 |
589 | (defcustom org-twbs-htmlize-output-type 'inline-css
590 | "Output type to be used by htmlize when formatting code snippets.
591 | Choices are `css', to export the CSS selectors only, or `inline-css', to
592 | export the CSS attribute values inline in the HTML. We use as default
593 | `inline-css', in order to make the resulting HTML self-containing.
594 |
595 | However, this will fail when using Emacs in batch mode for export, because
596 | then no rich font definitions are in place. It will also not be good if
597 | people with different Emacs setup contribute HTML files to a website,
598 | because the fonts will represent the individual setups. In these cases,
599 | it is much better to let Org/Htmlize assign classes only, and to use
600 | a style file to define the look of these classes.
601 | To get a start for your css file, start Emacs session and make sure that
602 | all the faces you are interested in are defined, for example by loading files
603 | in all modes you want. Then, use the command
604 | \\[org-twbs-htmlize-generate-css] to extract class definitions."
605 | :group 'org-export-twbs
606 | :type '(choice (const css) (const inline-css)))
607 |
608 | (defcustom org-twbs-htmlize-font-prefix "org-"
609 | "The prefix for CSS class names for htmlize font specifications."
610 | :group 'org-export-twbs
611 | :type 'string)
612 |
613 | ;;;; Table
614 |
615 | (defcustom org-twbs-table-default-attributes
616 | '(:class "table table-striped table-bordered table-hover table-condensed")
617 | "Default attributes and values which will be used in table tags.
618 | This is a plist where attributes are symbols, starting with
619 | colons, and values are strings."
620 | :group 'org-export-twbs
621 | :version "24.4"
622 | :package-version '(Org . "8.0")
623 | :type '(plist :key-type (symbol :tag "Property")
624 | :value-type (string :tag "Value")))
625 |
626 | (defcustom org-twbs-table-header-tags '("
" . "
")
627 | "The opening tag for table header fields.
628 | This is customizable so that alignment options can be specified.
629 | The first %s will be filled with the scope of the field, either row or col.
630 | The second %s will be replaced by a style entry to align the field.
631 | See also the variable `org-twbs-table-use-header-tags-for-first-column'.
632 | See also the variable `org-twbs-table-align-individual-fields'."
633 | :group 'org-export-twbs
634 | :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
635 |
636 | (defcustom org-twbs-table-data-tags '("
" . "
")
637 | "The opening tag for table data fields.
638 | This is customizable so that alignment options can be specified.
639 | The first %s will be filled with the scope of the field, either row or col.
640 | The second %s will be replaced by a style entry to align the field.
641 | See also the variable `org-twbs-table-align-individual-fields'."
642 | :group 'org-export-twbs
643 | :type '(cons (string :tag "Opening tag") (string :tag "Closing tag")))
644 |
645 | (defcustom org-twbs-table-row-tags '("
" . "
")
646 | "The opening and ending tags for table rows.
647 | This is customizable so that alignment options can be specified.
648 | Instead of strings, these can be Lisp forms that will be
649 | evaluated for each row in order to construct the table row tags.
650 |
651 | During evaluation, these variables will be dynamically bound so that
652 | you can reuse them:
653 |
654 | `row-number': row number (0 is the first row)
655 | `rowgroup-number': group number of current row
656 | `start-rowgroup-p': non-nil means the row starts a group
657 | `end-rowgroup-p': non-nil means the row ends a group
658 | `top-row-p': non-nil means this is the top row
659 | `bottom-row-p': non-nil means this is the bottom row
660 |
661 | For example:
662 |
663 | \(setq org-twbs-table-row-tags
664 | (cons '(cond (top-row-p \"
\"))
670 |
671 | will use the \"tr-top\" and \"tr-bottom\" classes for the top row
672 | and the bottom row, and otherwise alternate between \"tr-odd\" and
673 | \"tr-even\" for odd and even rows."
674 | :group 'org-export-twbs
675 | :type '(cons
676 | (choice :tag "Opening tag"
677 | (string :tag "Specify")
678 | (sexp))
679 | (choice :tag "Closing tag"
680 | (string :tag "Specify")
681 | (sexp))))
682 |
683 | (defcustom org-twbs-table-align-individual-fields t
684 | "Non-nil means attach style attributes for alignment to each table field.
685 | When nil, alignment will only be specified in the column tags, but this
686 | is ignored by some browsers (like Firefox, Safari). Opera does it right
687 | though."
688 | :group 'org-export-twbs
689 | :type 'boolean)
690 |
691 | (defcustom org-twbs-table-use-header-tags-for-first-column nil
692 | "Non-nil means format column one in tables with header tags.
693 | When nil, also column one will use data tags."
694 | :group 'org-export-twbs
695 | :type 'boolean)
696 |
697 | (defcustom org-twbs-table-caption-above t
698 | "When non-nil, place caption string at the beginning of the table.
699 | Otherwise, place it near the end."
700 | :group 'org-export-twbs
701 | :type 'boolean)
702 |
703 | ;;;; Tags
704 |
705 | (defcustom org-twbs-tag-class "badge"
706 | "Class name for tags."
707 | :group 'org-export-twbs
708 | :type 'string)
709 |
710 | (defcustom org-twbs-tag-class-prefix ""
711 | "Prefix to class names for TODO keywords.
712 | Each tag gets a class given by the tag itself, with this prefix.
713 | The default prefix is empty because it is nice to just use the keyword
714 | as a class name. But if you get into conflicts with other, existing
715 | CSS classes, then this prefix can be very useful."
716 | :group 'org-export-twbs
717 | :type 'string)
718 |
719 | ;;;; Template :: Generic
720 |
721 | (defcustom org-twbs-extension "html"
722 | "The extension for exported HTML files."
723 | :group 'org-export-twbs
724 | :type 'string)
725 |
726 | (defcustom org-twbs-coding-system 'utf-8
727 | "Coding system for HTML export.
728 | Use utf-8 as the default value."
729 | :group 'org-export-html
730 | :version "24.4"
731 | :package-version '(Org . "8.0")
732 | :type 'coding-system)
733 |
734 | (defcustom org-twbs-container-element "div"
735 | "HTML element to use for wrapping top level sections.
736 | Can be set with the in-buffer HTML_CONTAINER property or for
737 | publishing, with :html-container."
738 | :group 'org-export-twbs
739 | :version "24.4"
740 | :package-version '(Org . "8.0")
741 | :type 'string)
742 |
743 | (defcustom org-twbs-divs
744 | '((preamble "div" "preamble")
745 | (content "div" "content" "container")
746 | (postamble "footer" "postamble"))
747 | "Alist of the three section elements for HTML export.
748 | The car of each entry is one of 'preamble, 'content or 'postamble.
749 | The cdrs of each entry are the ELEMENT_TYPE and ID for each
750 | section of the exported document.
751 |
752 | Note that changing the default will prevent you from using
753 | org-info.js for your website."
754 | :group 'org-export-twbs
755 | :version "24.4"
756 | :package-version '(Org . "8.0")
757 | :type '(list :greedy t
758 | (list :tag "Preamble"
759 | (const :format "" preamble)
760 | (string :tag "element") (string :tag " id"))
761 | (list :tag "Content"
762 | (const :format "" content)
763 | (string :tag "element") (string :tag " id"))
764 | (list :tag "Postamble" (const :format "" postamble)
765 | (string :tag " id") (string :tag "element"))))
766 |
767 | (defcustom org-twbs-metadata-timestamp-format "%Y-%m-%d %a %H:%M"
768 | "Format used for timestamps in preamble, postamble and metadata.
769 | See `format-time-string' for more information on its components."
770 | :group 'org-export-twbs
771 | :version "24.4"
772 | :package-version '(Org . "8.0")
773 | :type 'string)
774 |
775 | ;;;; Template :: Mathjax
776 |
777 | (defcustom org-twbs-mathjax-options
778 | '((path "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_SVG")
779 | (scale "100")
780 | (dscale "100")
781 | (align "center")
782 | (indent "2em")
783 | (messages "none"))
784 | "Options for MathJax setup.
785 |
786 | path The path where to find MathJax
787 | scale Scaling for the HTML-CSS backend, omit percentage symbol
788 | dscale Scaling for displayed math, omit percentage symbol
789 | align How to align display math: left, center, or right
790 | indent If align is not center, how far from the left/right side?
791 | messages Should display messages in corner?
792 |
793 | You can also customize this for each buffer, using something like
794 |
795 | #+HTML_MATHJAX: scale:110 dscale:190 align:left messages:none"
796 | :group 'org-export-twbs
797 | :type '(list :greedy t
798 | (list :tag "path (the path from where to load MathJax.js)"
799 | (const :format " " path) (string))
800 | (list :tag "scale (scaling for math)"
801 | (const :format " " scale) (string))
802 | (list :tag "dscale (scaling for the displayed math)"
803 | (const :format " " scale) (string))
804 | (list :tag "align (alignment of displayed equations)"
805 | (const :format " " align) (string))
806 | (list :tag "indent (indentation with left or right alignment)"
807 | (const :format " " indent) (string))
808 | (list :tag "messages (show pocessing messages in corner)"
809 | (const :format " " messages)
810 | (choice (const "none")
811 | (const "simple")))))
812 |
813 | (defcustom org-twbs-mathjax-template
814 | "
815 |
839 | "
840 | "The MathJax setup for HTML files."
841 | :group 'org-export-twbs
842 | :type 'string)
843 |
844 | ;;;; Template :: Postamble
845 |
846 | (defcustom org-twbs-postamble 'auto
847 | "Non-nil means insert a postamble in HTML export.
848 |
849 | When set to 'auto, check against the
850 | `org-export-with-author/email/creator/date' variables to set the
851 | content of the postamble. When set to a string, use this string
852 | as the postamble. When t, insert a string as defined by the
853 | formatting string in `org-twbs-postamble-format'.
854 |
855 | When set to a function, apply this function and insert the
856 | returned string. The function takes the property list of export
857 | options as its only argument.
858 |
859 | Setting :html-postamble in publishing projects will take
860 | precedence over this variable."
861 | :group 'org-export-twbs
862 | :type '(choice (const :tag "No postamble" nil)
863 | (const :tag "Auto postamble" auto)
864 | (const :tag "Default formatting string" t)
865 | (string :tag "Custom formatting string")
866 | (function :tag "Function (must return a string)")))
867 |
868 | (defcustom org-twbs-postamble-format
869 | '(("en" "
Author: %a (%e)
870 |
Date: %d
871 |
%c
"))
872 | "Alist of languages and format strings for the HTML postamble.
873 |
874 | The first element of each list is the language code, as used for
875 | the LANGUAGE keyword. See `org-export-default-language'.
876 |
877 | The second element of each list is a format string to format the
878 | postamble itself. This format string can contain these elements:
879 |
880 | %t stands for the title.
881 | %a stands for the author's name.
882 | %e stands for the author's email.
883 | %d stands for the date.
884 | %c will be replaced by `org-twbs-creator-string'.
885 | %v will be replaced by `org-twbs-validation-link'.
886 | %T will be replaced by the export time.
887 | %C will be replaced by the last modification time.
888 |
889 | If you need to use a \"%\" character, you need to escape it
890 | like that: \"%%\"."
891 | :group 'org-export-twbs
892 | :type '(repeat
893 | (list (string :tag "Language")
894 | (string :tag "Format string"))))
895 |
896 | (defcustom org-twbs-validation-link
897 | "Validate"
898 | "Link to HTML validation service."
899 | :group 'org-export-twbs
900 | :type 'string)
901 |
902 | (defcustom org-twbs-creator-string
903 | (format "Emacs %s (Org-mode %s)"
904 | emacs-version
905 | (if (fboundp 'org-version) (org-version) "unknown version"))
906 | "Information about the creator of the HTML document.
907 | This option can also be set on with the CREATOR keyword."
908 | :group 'org-export-twbs
909 | :version "24.4"
910 | :package-version '(Org . "8.0")
911 | :type '(string :tag "Creator string"))
912 |
913 | ;;;; Template :: Preamble
914 |
915 | (defcustom org-twbs-preamble t
916 | "Non-nil means insert a preamble in HTML export.
917 |
918 | When t, insert a string as defined by the formatting string in
919 | `org-twbs-preamble-format'. When set to a string, use this
920 | formatting string instead (see `org-twbs-postamble-format' for an
921 | example of such a formatting string).
922 |
923 | When set to a function, apply this function and insert the
924 | returned string. The function takes the property list of export
925 | options as its only argument.
926 |
927 | Setting :html-preamble in publishing projects will take
928 | precedence over this variable."
929 | :group 'org-export-twbs
930 | :type '(choice (const :tag "No preamble" nil)
931 | (const :tag "Default preamble" t)
932 | (string :tag "Custom formatting string")
933 | (function :tag "Function (must return a string)")))
934 |
935 | (defcustom org-twbs-preamble-format '(("en" ""))
936 | "Alist of languages and format strings for the HTML preamble.
937 |
938 | The first element of each list is the language code, as used for
939 | the LANGUAGE keyword. See `org-export-default-language'.
940 |
941 | The second element of each list is a format string to format the
942 | preamble itself. This format string can contain these elements:
943 |
944 | %t stands for the title.
945 | %a stands for the author's name.
946 | %e stands for the author's email.
947 | %d stands for the date.
948 | %c will be replaced by `org-twbs-creator-string'.
949 | %v will be replaced by `org-twbs-validation-link'.
950 | %T will be replaced by the export time.
951 | %C will be replaced by the last modification time.
952 |
953 | If you need to use a \"%\" character, you need to escape it
954 | like that: \"%%\".
955 |
956 | See the default value of `org-twbs-postamble-format' for an
957 | example."
958 | :group 'org-export-twbs
959 | :type '(repeat
960 | (list (string :tag "Language")
961 | (string :tag "Format string"))))
962 |
963 | (defcustom org-twbs-link-up ""
964 | "Where should the \"UP\" link of exported HTML pages lead?"
965 | :group 'org-export-twbs
966 | :type '(string :tag "File or URL"))
967 |
968 | (defcustom org-twbs-link-home ""
969 | "Where should the \"HOME\" link of exported HTML pages lead?"
970 | :group 'org-export-twbs
971 | :type '(string :tag "File or URL"))
972 |
973 | (defcustom org-twbs-link-use-abs-url nil
974 | "Should we prepend relative links with HTML_LINK_HOME?"
975 | :group 'org-export-twbs
976 | :version "24.4"
977 | :package-version '(Org . "8.1")
978 | :type 'boolean)
979 |
980 | (defcustom org-twbs-home/up-format
981 | "
"
986 | "Snippet used to insert the HOME and UP links.
987 | This is a format string, the first %s will receive the UP link,
988 | the second the HOME link. If both `org-twbs-link-up' and
989 | `org-twbs-link-home' are empty, the entire snippet will be
990 | ignored."
991 | :group 'org-export-twbs
992 | :type 'string)
993 |
994 | ;;;; Template :: Scripts
995 |
996 | (define-obsolete-variable-alias
997 | 'org-twbs-style-include-scripts 'org-twbs-head-include-scripts "24.4")
998 | (defcustom org-twbs-head-include-scripts t
999 | "Non-nil means include the JavaScript snippets in exported HTML files.
1000 | The actual script is defined in `org-twbs-scripts' and should
1001 | not be modified."
1002 | :group 'org-export-twbs
1003 | :version "24.4"
1004 | :package-version '(Org . "8.0")
1005 | :type 'boolean)
1006 |
1007 | ;;;; Template :: Styles
1008 |
1009 | (define-obsolete-variable-alias
1010 | 'org-twbs-style-include-default 'org-twbs-head-include-default-style "24.4")
1011 | (defcustom org-twbs-head-include-default-style t
1012 | "Non-nil means include the default style in exported HTML files.
1013 | The actual style is defined in `org-twbs-style-default' and
1014 | should not be modified. Use `org-twbs-head' to use your own
1015 | style information."
1016 | :group 'org-export-twbs
1017 | :version "24.4"
1018 | :package-version '(Org . "8.0")
1019 | :type 'boolean)
1020 | ;;;###autoload
1021 | (put 'org-twbs-head-include-default-style 'safe-local-variable 'booleanp)
1022 |
1023 | (define-obsolete-variable-alias 'org-twbs-style 'org-twbs-head "24.4")
1024 | (defcustom org-twbs-head "
1025 |
1026 |
1027 | "
1028 | "Org-wide head definitions for exported HTML files.
1029 |
1030 | As the value of this option simply gets inserted into the HTML
1031 | header, you can use it to add any arbitrary text to the
1032 | header.
1033 |
1034 | You can set this on a per-file basis using #+HTML_HEAD:,
1035 | or for publication projects using the :html-head property."
1036 | :group 'org-export-twbs
1037 | :version "24.4"
1038 | :package-version '(Org . "8.0")
1039 | :type 'string)
1040 | ;;;###autoload
1041 | (put 'org-twbs-head 'safe-local-variable 'stringp)
1042 |
1043 | (defcustom org-twbs-head-extra ""
1044 | "More head information to add in the HTML output.
1045 |
1046 | You can set this on a per-file basis using #+HTML_HEAD_EXTRA:,
1047 | or for publication projects using the :html-head-extra property."
1048 | :group 'org-export-twbs
1049 | :version "24.4"
1050 | :package-version '(Org . "8.0")
1051 | :type 'string)
1052 | ;;;###autoload
1053 | (put 'org-twbs-head-extra 'safe-local-variable 'stringp)
1054 |
1055 | ;;;; Todos
1056 |
1057 | (defcustom org-twbs-todo-kwd-class-prefix ""
1058 | "Prefix to class names for TODO keywords.
1059 | Each TODO keyword gets a class given by the keyword itself, with this prefix.
1060 | The default prefix is empty because it is nice to just use the keyword
1061 | as a class name. But if you get into conflicts with other, existing
1062 | CSS classes, then this prefix can be very useful."
1063 | :group 'org-export-twbs
1064 | :type 'string)
1065 |
1066 | (defcustom org-twbs-todo-kwd-class-undone "label-primary"
1067 | "Class name for TODO keywords which are not done.
1068 | Traditionally this was not configurable, and was the value 'todo'."
1069 | :group 'org-export-twbs
1070 | :type 'string)
1071 |
1072 | (defcustom org-twbs-todo-kwd-class-done "label-default"
1073 | "Class name for TODO keywords which are done.
1074 | Traditionally this was not configurable, and was the value 'done'."
1075 | :group 'org-export-twbs
1076 | :type 'string)
1077 |
1078 | ;;;; Google Analytics
1079 |
1080 | (defcustom org-twbs-google-analytics "
1081 | \n"
1091 | "Snippet used to insert the Google Analytics tracking code.
1092 | This is a format string, the %s will be replaced with the value
1093 | set using the :gid keyword."
1094 | :group 'org-export-twbs
1095 | :type 'string)
1096 |
1097 |
1098 | ;;; Internal Functions
1099 |
1100 | (defun org-twbs-close-tag (tag attr info)
1101 | (concat "<" tag " " attr ">"))
1102 |
1103 | (defun org-twbs--make-attribute-string (attributes)
1104 | "Return a list of attributes, as a string.
1105 | ATTRIBUTES is a plist where values are either strings or nil. An
1106 | attributes with a nil value will be omitted from the result."
1107 | (let (output)
1108 | (dolist (item attributes (mapconcat 'identity (nreverse output) " "))
1109 | (cond ((null item) (pop output))
1110 | ((symbolp item) (push (substring (symbol-name item) 1) output))
1111 | (t (let ((key (car output))
1112 | (value (replace-regexp-in-string
1113 | "\"" """ (org-twbs-encode-plain-text item))))
1114 | (setcar output (format "%s=\"%s\"" key value))))))))
1115 |
1116 | (defun org-twbs--wrap-image (contents info &optional caption label)
1117 | "Wrap CONTENTS string within an appropriate environment for images.
1118 | INFO is a plist used as a communication channel. When optional
1119 | arguments CAPTION and LABEL are given, use them for caption and
1120 | \"id\" attribute."
1121 | (format "\n%s%s\n"
1122 | ;; ID.
1123 | (if (not (org-string-nw-p label)) ""
1124 | (format " id=\"%s\"" label))
1125 | ;; Contents.
1126 | (format "\n
%s
" contents)
1127 | ;; Caption.
1128 | (if (not (org-string-nw-p caption)) ""
1129 | (format "\n%s" caption))))
1130 |
1131 | (defun org-twbs--format-image (source attributes info)
1132 | "Return \"img\" tag with given SOURCE and ATTRIBUTES.
1133 | SOURCE is a string specifying the location of the image.
1134 | ATTRIBUTES is a plist, as returned by
1135 | `org-export-read-attribute'. INFO is a plist used as
1136 | a communication channel."
1137 | (org-twbs-close-tag
1138 | "img"
1139 | (org-twbs--make-attribute-string
1140 | (org-combine-plists
1141 | (list :src source
1142 | :class "img-responsive"
1143 | :alt (if (string-match-p "^ltxpng/" source)
1144 | (org-twbs-encode-plain-text
1145 | (org-find-text-property-in-string 'org-latex-src source))
1146 | (file-name-nondirectory source)))
1147 | attributes))
1148 | info))
1149 |
1150 | (defun org-twbs--textarea-block (element)
1151 | "Transcode ELEMENT into a textarea block.
1152 | ELEMENT is either a src block or an example block."
1153 | (let* ((code (car (org-export-unravel-code element)))
1154 | (attr (org-export-read-attribute :attr_html element)))
1155 | (format "
\n\n
"
1156 | (or (plist-get attr :width) 80)
1157 | (or (plist-get attr :height) (org-count-lines code))
1158 | code)))
1159 |
1160 | (defun org-twbs--has-caption-p (element &optional info)
1161 | "Non-nil when ELEMENT has a caption affiliated keyword.
1162 | INFO is a plist used as a communication channel. This function
1163 | is meant to be used as a predicate for `org-export-get-ordinal' or
1164 | a value to `org-twbs-standalone-image-predicate'."
1165 | (org-element-property :caption element))
1166 |
1167 | ;;;; Table
1168 |
1169 | (defun org-twbs-htmlize-region-for-paste (beg end)
1170 | "Convert the region between BEG and END to HTML, using htmlize.el.
1171 | This is much like `htmlize-region-for-paste', only that it uses
1172 | the settings define in the org-... variables."
1173 | (let* ((htmlize-output-type org-twbs-htmlize-output-type)
1174 | (htmlize-css-name-prefix org-twbs-htmlize-font-prefix)
1175 | (htmlbuf (htmlize-region beg end)))
1176 | (unwind-protect
1177 | (with-current-buffer htmlbuf
1178 | (buffer-substring (plist-get htmlize-buffer-places 'content-start)
1179 | (plist-get htmlize-buffer-places 'content-end)))
1180 | (kill-buffer htmlbuf))))
1181 |
1182 | ;;;###autoload
1183 | (defun org-twbs-htmlize-generate-css ()
1184 | "Create the CSS for all font definitions in the current Emacs session.
1185 | Use this to create face definitions in your CSS style file that can then
1186 | be used by code snippets transformed by htmlize.
1187 | This command just produces a buffer that contains class definitions for all
1188 | faces used in the current Emacs session. You can copy and paste the ones you
1189 | need into your CSS file.
1190 |
1191 | If you then set `org-twbs-htmlize-output-type' to `css', calls
1192 | to the function `org-twbs-htmlize-region-for-paste' will
1193 | produce code that uses these same face definitions."
1194 | (interactive)
1195 | (require 'htmlize)
1196 | (and (get-buffer "*html*") (kill-buffer "*html*"))
1197 | (with-temp-buffer
1198 | (let ((fl (face-list))
1199 | (htmlize-css-name-prefix "org-")
1200 | (htmlize-output-type 'css)
1201 | f i)
1202 | (while (setq f (pop fl)
1203 | i (and f (face-attribute f :inherit)))
1204 | (when (and (symbolp f) (or (not i) (not (listp i))))
1205 | (insert (org-add-props (copy-sequence "1") nil 'face f))))
1206 | (htmlize-region (point-min) (point-max))))
1207 | (org-pop-to-buffer-same-window "*html*")
1208 | (goto-char (point-min))
1209 | (if (re-search-forward "")
1358 | (when (plist-get info :html-head-include-scripts) org-twbs-scripts)
1359 | (org-element-normalize-string (plist-get info :html-head-extra)))))
1360 |
1361 | (defun org-twbs--build-mathjax-config (info)
1362 | "Insert the user setup into the mathjax template.
1363 | INFO is a plist used as a communication channel."
1364 | (when (and (memq (plist-get info :with-latex) '(mathjax t))
1365 | (org-element-map (plist-get info :parse-tree)
1366 | '(latex-fragment latex-environment) 'identity info t))
1367 | (let ((template (plist-get info :html-mathjax-template))
1368 | (options (plist-get info :html-mathjax-options))
1369 | (in-buffer (or (plist-get info :html-mathjax) "")))
1370 | (dolist (e options (org-element-normalize-string template))
1371 | (let ((name (car e))
1372 | (val (nth 1 e)))
1373 | (when (string-match (concat "\\<" (symbol-name name) ":") in-buffer)
1374 | (setq val
1375 | (car (read-from-string (substring in-buffer (match-end 0))))))
1376 | (unless (stringp val) (setq val (format "%s" val)))
1377 | (while (string-match (concat "%" (upcase (symbol-name name)))
1378 | template)
1379 | (setq template (replace-match val t t template))))))))
1380 |
1381 | (defun org-twbs-format-spec (info)
1382 | "Return format specification for elements that can be
1383 | used in the preamble or postamble."
1384 | `((?t . ,(org-export-data (plist-get info :title) info))
1385 | (?d . ,(org-export-data (org-export-get-date info) info))
1386 | (?T . ,(format-time-string org-twbs-metadata-timestamp-format))
1387 | (?a . ,(org-export-data (plist-get info :author) info))
1388 | (?e . ,(mapconcat
1389 | (lambda (e)
1390 | (format "%s" e e))
1391 | (split-string (plist-get info :email) ",+ *")
1392 | ", "))
1393 | (?c . ,(plist-get info :creator))
1394 | (?C . ,(let ((file (plist-get info :input-file)))
1395 | (format-time-string org-twbs-metadata-timestamp-format
1396 | (if file (nth 5 (file-attributes file))
1397 | (current-time)))))
1398 | (?v . ,(or org-twbs-validation-link ""))))
1399 |
1400 | (defun org-twbs--build-pre/postamble (type info)
1401 | "Return document preamble or postamble as a string, or nil.
1402 | TYPE is either 'preamble or 'postamble, INFO is a plist used as a
1403 | communication channel."
1404 | (let ((section (plist-get info (intern (format ":html-%s" type))))
1405 | (spec (org-twbs-format-spec info)))
1406 | (when section
1407 | (let ((section-contents
1408 | (if (functionp section) (funcall section info)
1409 | (cond
1410 | ((stringp section) (format-spec section spec))
1411 | ((eq section 'auto)
1412 | (let ((date (cdr (assq ?d spec)))
1413 | (author (cdr (assq ?a spec)))
1414 | (email (cdr (assq ?e spec)))
1415 | (creator (cdr (assq ?c spec)))
1416 | (timestamp (cdr (assq ?T spec)))
1417 | (validation-link (cdr (assq ?v spec))))
1418 | (concat
1419 | "
"))))
1832 |
1833 | (defun org-twbs-list-of-tables (info)
1834 | "Build a list of tables.
1835 | INFO is a plist used as a communication channel. Return the list
1836 | of tables as a string, or nil if it is empty."
1837 | (let ((lol-entries (org-export-collect-tables info)))
1838 | (when lol-entries
1839 | (concat "
"))))
1867 |
1868 |
1869 | ;;; Transcode Functions
1870 |
1871 | ;;;; Bold
1872 |
1873 | (defun org-twbs-bold (bold contents info)
1874 | "Transcode BOLD from Org to HTML.
1875 | CONTENTS is the text with bold markup. INFO is a plist holding
1876 | contextual information."
1877 | (format (or (cdr (assq 'bold org-twbs-text-markup-alist)) "%s")
1878 | contents))
1879 |
1880 | ;;;; Center Block
1881 |
1882 | (defun org-twbs-center-block (center-block contents info)
1883 | "Transcode a CENTER-BLOCK element from Org to HTML.
1884 | CONTENTS holds the contents of the block. INFO is a plist
1885 | holding contextual information."
1886 | (format "
\n%s
" contents))
1887 |
1888 | ;;;; Clock
1889 |
1890 | (defun org-twbs-clock (clock contents info)
1891 | "Transcode a CLOCK element from Org to HTML.
1892 | CONTENTS is nil. INFO is a plist used as a communication
1893 | channel."
1894 | (format "
1895 |
1896 | %s%s%s
1897 |
1898 |
"
1899 | org-clock-string
1900 | (org-timestamp-translate (org-element-property :value clock))
1901 | (let ((time (org-element-property :duration clock)))
1902 | (and time (format " (%s)" time)))))
1903 |
1904 | ;;;; Code
1905 |
1906 | (defun org-twbs-code (code contents info)
1907 | "Transcode CODE from Org to HTML.
1908 | CONTENTS is nil. INFO is a plist holding contextual
1909 | information."
1910 | (format (or (cdr (assq 'code org-twbs-text-markup-alist)) "%s")
1911 | (org-twbs-encode-plain-text (org-element-property :value code))))
1912 |
1913 | ;;;; Drawer
1914 |
1915 | (defun org-twbs-drawer (drawer contents info)
1916 | "Transcode a DRAWER element from Org to HTML.
1917 | CONTENTS holds the contents of the block. INFO is a plist
1918 | holding contextual information."
1919 | (if (functionp org-twbs-format-drawer-function)
1920 | (funcall org-twbs-format-drawer-function
1921 | (org-element-property :drawer-name drawer)
1922 | contents)
1923 | ;; If there's no user defined function: simply
1924 | ;; display contents of the drawer.
1925 | contents))
1926 |
1927 | ;;;; Dynamic Block
1928 |
1929 | (defun org-twbs-dynamic-block (dynamic-block contents info)
1930 | "Transcode a DYNAMIC-BLOCK element from Org to HTML.
1931 | CONTENTS holds the contents of the block. INFO is a plist
1932 | holding contextual information. See `org-export-data'."
1933 | contents)
1934 |
1935 | ;;;; Entity
1936 |
1937 | (defun org-twbs-entity (entity contents info)
1938 | "Transcode an ENTITY object from Org to HTML.
1939 | CONTENTS are the definition itself. INFO is a plist holding
1940 | contextual information."
1941 | (org-element-property :html entity))
1942 |
1943 | ;;;; Example Block
1944 |
1945 | (defun org-twbs-example-block (example-block contents info)
1946 | "Transcode a EXAMPLE-BLOCK element from Org to HTML.
1947 | CONTENTS is nil. INFO is a plist holding contextual
1948 | information."
1949 | (if (org-export-read-attribute :attr_html example-block :textarea)
1950 | (org-twbs--textarea-block example-block)
1951 | (format "
\n%s
"
1952 | (org-twbs-format-code example-block info))))
1953 |
1954 | ;;;; Export Snippet
1955 |
1956 | (defun org-twbs-export-snippet (export-snippet contents info)
1957 | "Transcode a EXPORT-SNIPPET object from Org to HTML.
1958 | CONTENTS is nil. INFO is a plist holding contextual
1959 | information."
1960 | (when (eq (org-export-snippet-backend export-snippet) 'html)
1961 | (org-element-property :value export-snippet)))
1962 |
1963 | ;;;; Export Block
1964 |
1965 | (defun org-twbs-export-block (export-block contents info)
1966 | "Transcode a EXPORT-BLOCK element from Org to HTML.
1967 | CONTENTS is nil. INFO is a plist holding contextual information."
1968 | (when (string= (org-element-property :type export-block) "HTML")
1969 | (org-remove-indentation (org-element-property :value export-block))))
1970 |
1971 | ;;;; Fixed Width
1972 |
1973 | (defun org-twbs-fixed-width (fixed-width contents info)
1974 | "Transcode a FIXED-WIDTH element from Org to HTML.
1975 | CONTENTS is nil. INFO is a plist holding contextual information."
1976 | (format "
\n%s
"
1977 | (org-twbs-do-format-code
1978 | (org-remove-indentation
1979 | (org-trim
1980 | (org-element-property :value fixed-width))))))
1981 |
1982 | ;;;; Footnote Reference
1983 |
1984 | (defun org-twbs-footnote-reference (footnote-reference contents info)
1985 | "Transcode a FOOTNOTE-REFERENCE element from Org to HTML.
1986 | CONTENTS is nil. INFO is a plist holding contextual information."
1987 | (concat
1988 | ;; Insert separator between two footnotes in a row.
1989 | (let ((prev (org-export-get-previous-element footnote-reference info)))
1990 | (when (eq (org-element-type prev) 'footnote-reference)
1991 | org-twbs-footnote-separator))
1992 | (cond
1993 | ((not (org-export-footnote-first-reference-p footnote-reference info))
1994 | (org-twbs-format-footnote-reference
1995 | (org-export-get-footnote-number footnote-reference info)
1996 | "IGNORED" 100))
1997 | ;; Inline definitions are secondary strings.
1998 | ((eq (org-element-property :type footnote-reference) 'inline)
1999 | (org-twbs-format-footnote-reference
2000 | (org-export-get-footnote-number footnote-reference info)
2001 | "IGNORED" 1))
2002 | ;; Non-inline footnotes definitions are full Org data.
2003 | (t (org-twbs-format-footnote-reference
2004 | (org-export-get-footnote-number footnote-reference info)
2005 | "IGNORED" 1)))))
2006 |
2007 | ;;;; Headline
2008 |
2009 | (defun org-twbs-format-headline--wrap
2010 | (headline info &optional format-function &rest extra-keys)
2011 | "Transcode a HEADLINE element from Org to HTML.
2012 | CONTENTS holds the contents of the headline. INFO is a plist
2013 | holding contextual information."
2014 | (let* ((level (+ (org-export-get-relative-level headline info)
2015 | (1- org-twbs-toplevel-hlevel)))
2016 | (headline-number (org-export-get-headline-number headline info))
2017 | (section-number (and (not (org-export-low-level-p headline info))
2018 | (org-export-numbered-headline-p headline info)
2019 | (org-twbs-display-headline-number-p headline-number info)
2020 | (mapconcat 'number-to-string
2021 | headline-number ".")))
2022 | (todo (and (plist-get info :with-todo-keywords)
2023 | (let ((todo (org-element-property :todo-keyword headline)))
2024 | (and todo (org-export-data todo info)))))
2025 | (todo-type (and todo (org-element-property :todo-type headline)))
2026 | (priority (and (plist-get info :with-priority)
2027 | (org-element-property :priority headline)))
2028 | (text (org-export-data (org-element-property :title headline) info))
2029 | (tags (and (plist-get info :with-tags)
2030 | (org-export-get-tags headline info)))
2031 | (headline-label (or (org-element-property :CUSTOM_ID headline)
2032 | (concat "sec-" (mapconcat 'number-to-string
2033 | headline-number "-"))))
2034 | (format-function
2035 | (cond ((functionp format-function) format-function)
2036 | ((not (eq org-twbs-format-headline-function 'ignore))
2037 | (lambda (todo todo-type priority text tags &rest ignore)
2038 | (funcall org-twbs-format-headline-function
2039 | todo todo-type priority text tags)))
2040 | (t 'org-twbs-format-headline))))
2041 | (apply format-function
2042 | todo todo-type priority text tags
2043 | :headline-label headline-label :level level
2044 | :section-number section-number extra-keys)))
2045 |
2046 | (defun org-twbs-headline (headline contents info)
2047 | "Transcode a HEADLINE element from Org to HTML.
2048 | CONTENTS holds the contents of the headline. INFO is a plist
2049 | holding contextual information."
2050 | (unless (org-element-property :footnote-section-p headline)
2051 | (let* ((contents (or contents ""))
2052 | (numberedp (org-export-numbered-headline-p headline info))
2053 | (level (org-export-get-relative-level headline info))
2054 | (text (org-export-data (org-element-property :title headline) info))
2055 | (todo (and (plist-get info :with-todo-keywords)
2056 | (let ((todo (org-element-property :todo-keyword headline)))
2057 | (and todo (org-export-data todo info)))))
2058 | (todo-type (and todo (org-element-property :todo-type headline)))
2059 | (tags (and (plist-get info :with-tags)
2060 | (org-export-get-tags headline info)))
2061 | (priority (and (plist-get info :with-priority)
2062 | (org-element-property :priority headline)))
2063 | (section-number (mapconcat #'number-to-string
2064 | (org-export-get-headline-number
2065 | headline info) "-"))
2066 | (ids (delq 'nil
2067 | (list (org-element-property :CUSTOM_ID headline)
2068 | (concat "sec-" section-number)
2069 | (org-element-property :ID headline))))
2070 | (preferred-id (car ids))
2071 | (extra-ids (mapconcat
2072 | (lambda (id)
2073 | (org-twbs--anchor
2074 | (if (org-uuidgen-p id) (concat "ID-" id) id)))
2075 | (cdr ids) ""))
2076 | ;; Create the headline text.
2077 | (full-text (org-twbs-format-headline--wrap headline info)))
2078 | (if (org-export-low-level-p headline info)
2079 | ;; This is a deep sub-tree: export it as a list item.
2080 | (let* ((type (if numberedp 'ordered 'unordered))
2081 | (itemized-body
2082 | (org-twbs-format-list-item
2083 | contents type nil info nil
2084 | (concat (org-twbs--anchor preferred-id) extra-ids
2085 | full-text))))
2086 | (concat
2087 | (and (org-export-first-sibling-p headline info)
2088 | (org-twbs-begin-plain-list type))
2089 | itemized-body
2090 | (and (org-export-last-sibling-p headline info)
2091 | (org-twbs-end-plain-list type))))
2092 | ;; Standard headline. Export it as a section.
2093 | (let ((extra-class (org-element-property :HTML_CONTAINER_CLASS headline))
2094 | (level1 (+ level (1- org-twbs-toplevel-hlevel)))
2095 | (first-content (car (org-element-contents headline))))
2096 | (format "<%s id=\"%s\" class=\"%s\">%s%s%s>\n"
2097 | (org-twbs--container headline info)
2098 | (format "outline-container-%s"
2099 | (or (org-element-property :CUSTOM_ID headline)
2100 | (concat "sec-" section-number)))
2101 | (concat (format "outline-%d" level1) (and extra-class " ")
2102 | extra-class)
2103 | (format "\n%s%s\n"
2104 | level1 preferred-id extra-ids full-text level1)
2105 | ;; When there is no section, pretend there is an
2106 | ;; empty one to get the correct
\n" class extra) text "
\n")))
2143 |
2144 | (defun org-twbs-inlinetask (inlinetask contents info)
2145 | "Transcode an INLINETASK element from Org to HTML.
2146 | CONTENTS holds the contents of the block. INFO is a plist
2147 | holding contextual information."
2148 | (cond
2149 | ;; If `org-twbs-format-inlinetask-function' is not 'ignore, call it
2150 | ;; with appropriate arguments.
2151 | ((not (eq org-twbs-format-inlinetask-function 'ignore))
2152 | (let ((format-function
2153 | (function*
2154 | (lambda (todo todo-type priority text tags
2155 | &key contents &allow-other-keys)
2156 | (funcall org-twbs-format-inlinetask-function
2157 | todo todo-type priority text tags contents)))))
2158 | (org-twbs-format-headline--wrap
2159 | inlinetask info format-function :contents contents)))
2160 | ;; Otherwise, use a default template.
2161 | (t (format "
" extra)
2202 | (when headline (concat headline br)))))
2203 | (descriptive
2204 | (let* ((term term-counter-id))
2205 | (setq term (or term "(no term)"))
2206 | ;; Check-boxes in descriptive lists are associated to tag.
2207 | (concat (format "
%s
"
2208 | (concat checkbox term))
2209 | "
"))))
2210 | (unless (eq type 'descriptive) checkbox)
2211 | contents
2212 | (case type
2213 | (ordered "
")
2214 | (unordered "")
2215 | (descriptive "")))))
2216 |
2217 | (defun org-twbs-item (item contents info)
2218 | "Transcode an ITEM element from Org to HTML.
2219 | CONTENTS holds the contents of the item. INFO is a plist holding
2220 | contextual information."
2221 | (let* ((plain-list (org-export-get-parent item))
2222 | (type (org-element-property :type plain-list))
2223 | (counter (org-element-property :counter item))
2224 | (checkbox (org-element-property :checkbox item))
2225 | (tag (let ((tag (org-element-property :tag item)))
2226 | (and tag (org-export-data tag info)))))
2227 | (org-twbs-format-list-item
2228 | contents type checkbox info (or tag counter))))
2229 |
2230 | ;;;; Keyword
2231 |
2232 | (defun org-twbs-keyword (keyword contents info)
2233 | "Transcode a KEYWORD element from Org to HTML.
2234 | CONTENTS is nil. INFO is a plist holding contextual information."
2235 | (let ((key (org-element-property :key keyword))
2236 | (value (org-element-property :value keyword)))
2237 | (cond
2238 | ((string= key "HTML") value)
2239 | ((string= key "TOC")
2240 | (let ((value (downcase value)))
2241 | (cond
2242 | ((string-match "\\" value)
2243 | (let ((depth (or (and (string-match "[0-9]+" value)
2244 | (string-to-number (match-string 0 value)))
2245 | (plist-get info :with-toc))))
2246 | (org-twbs-toc depth info)))
2247 | ((string= "listings" value) (org-twbs-list-of-listings info))
2248 | ((string= "tables" value) (org-twbs-list-of-tables info))))))))
2249 |
2250 | ;;;; Latex Environment
2251 |
2252 | (defun org-twbs-format-latex-arity (prefix &optional dir overlays msg
2253 | at forbuffer processing-type)
2254 | "Arity fix for org-format-latex signature change here:
2255 | http://orgmode.org/w/?p=org-mode.git;a=commit;h=8daf4a89f1a157c0ee2c91e5b990203679b31cf7
2256 | Call 7-arity first, then 6-arity if first fails."
2257 | (with-no-warnings
2258 | (condition-case nil
2259 | (org-format-latex prefix nil nil dir overlays msg forbuffer processing-type)
2260 | (error
2261 | (condition-case nil
2262 | (org-format-latex prefix dir overlays msg at forbuffer processing-type)
2263 | (error
2264 | (org-format-latex prefix dir overlays msg forbuffer processing-type)))))))
2265 |
2266 | (defun org-twbs-format-latex (latex-frag processing-type info)
2267 | "Format a LaTeX fragment LATEX-FRAG into HTML.
2268 | PROCESSING-TYPE designates the tool used for conversion. It is
2269 | a symbol among `mathjax', `dvipng', `imagemagick', `verbatim' nil
2270 | and t. See `org-twbs-with-latex' for more information. INFO is
2271 | a plist containing export properties."
2272 | (let ((cache-relpath "") (cache-dir ""))
2273 | (unless (eq processing-type 'mathjax)
2274 | (let ((bfn (or (buffer-file-name)
2275 | (make-temp-name
2276 | (expand-file-name "latex" temporary-file-directory))))
2277 | (latex-header
2278 | (let ((header (plist-get info :latex-header)))
2279 | (and header
2280 | (concat (mapconcat
2281 | (lambda (line) (concat "#+LATEX_HEADER: " line))
2282 | (org-split-string header "\n")
2283 | "\n")
2284 | "\n")))))
2285 | (setq cache-relpath
2286 | (concat "ltxpng/"
2287 | (file-name-sans-extension
2288 | (file-name-nondirectory bfn)))
2289 | cache-dir (file-name-directory bfn))
2290 | ;; Re-create LaTeX environment from original buffer in
2291 | ;; temporary buffer so that dvipng/imagemagick can properly
2292 | ;; turn the fragment into an image.
2293 | (setq latex-frag (concat latex-header latex-frag))))
2294 | (with-temp-buffer
2295 | (insert latex-frag)
2296 | (org-twbs-format-latex-arity cache-relpath cache-dir nil
2297 | "Creating LaTeX Image..."
2298 | nil nil processing-type)
2299 | (buffer-string))))
2300 |
2301 | (defun org-twbs-latex-environment (latex-environment contents info)
2302 | "Transcode a LATEX-ENVIRONMENT element from Org to HTML.
2303 | CONTENTS is nil. INFO is a plist holding contextual information."
2304 | (let ((processing-type (plist-get info :with-latex))
2305 | (latex-frag (org-remove-indentation
2306 | (org-element-property :value latex-environment)))
2307 | (attributes (org-export-read-attribute :attr_html latex-environment)))
2308 | (case processing-type
2309 | ((t mathjax)
2310 | (org-twbs-format-latex latex-frag 'mathjax info))
2311 | ((dvipng imagemagick)
2312 | (let ((formula-link
2313 | (org-twbs-format-latex latex-frag processing-type info)))
2314 | (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
2315 | ;; Do not provide a caption or a name to be consistent with
2316 | ;; `mathjax' handling.
2317 | (org-twbs--wrap-image
2318 | (org-twbs--format-image
2319 | (match-string 1 formula-link) attributes info) info))))
2320 | (t latex-frag))))
2321 |
2322 | ;;;; Latex Fragment
2323 |
2324 | (defun org-twbs-latex-fragment (latex-fragment contents info)
2325 | "Transcode a LATEX-FRAGMENT object from Org to HTML.
2326 | CONTENTS is nil. INFO is a plist holding contextual information."
2327 | (let ((latex-frag (org-element-property :value latex-fragment))
2328 | (processing-type (plist-get info :with-latex)))
2329 | (case processing-type
2330 | ((t mathjax)
2331 | (org-twbs-format-latex latex-frag 'mathjax info))
2332 | ((dvipng imagemagick)
2333 | (let ((formula-link
2334 | (org-twbs-format-latex latex-frag processing-type info)))
2335 | (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link))
2336 | (org-twbs--format-image (match-string 1 formula-link) nil info))))
2337 | (t latex-frag))))
2338 |
2339 | ;;;; Line Break
2340 |
2341 | (defun org-twbs-line-break (line-break contents info)
2342 | "Transcode a LINE-BREAK object from Org to HTML.
2343 | CONTENTS is nil. INFO is a plist holding contextual information."
2344 | (concat (org-twbs-close-tag "br" nil info) "\n"))
2345 |
2346 | ;;;; Link
2347 |
2348 | (defun org-twbs-inline-image-p (link info)
2349 | "Non-nil when LINK is meant to appear as an image.
2350 | INFO is a plist used as a communication channel. LINK is an
2351 | inline image when it has no description and targets an image
2352 | file (see `org-twbs-inline-image-rules' for more information), or
2353 | if its description is a single link targeting an image file."
2354 | (if (not (org-element-contents link))
2355 | (org-export-inline-image-p link org-twbs-inline-image-rules)
2356 | (not
2357 | (let ((link-count 0))
2358 | (org-element-map (org-element-contents link)
2359 | (cons 'plain-text org-element-all-objects)
2360 | (lambda (obj)
2361 | (case (org-element-type obj)
2362 | (plain-text (org-string-nw-p obj))
2363 | (link (if (= link-count 1) t
2364 | (incf link-count)
2365 | (not (org-export-inline-image-p
2366 | obj org-twbs-inline-image-rules))))
2367 | (otherwise t)))
2368 | info t)))))
2369 |
2370 | (defvar org-twbs-standalone-image-predicate)
2371 | (defun org-twbs-standalone-image-p (element info)
2372 | "Non-nil if ELEMENT is a standalone image.
2373 |
2374 | INFO is a plist holding contextual information.
2375 |
2376 | An element or object is a standalone image when
2377 |
2378 | - its type is `paragraph' and its sole content, save for white
2379 | spaces, is a link that qualifies as an inline image;
2380 |
2381 | - its type is `link' and its containing paragraph has no other
2382 | content save white spaces.
2383 |
2384 | Bind `org-twbs-standalone-image-predicate' to constrain paragraph
2385 | further. For example, to check for only captioned standalone
2386 | images, set it to:
2387 |
2388 | \(lambda (paragraph) (org-element-property :caption paragraph))"
2389 | (let ((paragraph (case (org-element-type element)
2390 | (paragraph element)
2391 | (link (org-export-get-parent element)))))
2392 | (and (eq (org-element-type paragraph) 'paragraph)
2393 | (or (not (fboundp 'org-twbs-standalone-image-predicate))
2394 | (funcall org-twbs-standalone-image-predicate paragraph))
2395 | (catch 'exit
2396 | (let ((link-count 0))
2397 | (org-element-map (org-element-contents paragraph)
2398 | (cons 'plain-text org-element-all-objects)
2399 | #'(lambda (obj)
2400 | (when (case (org-element-type obj)
2401 | (plain-text (org-string-nw-p obj))
2402 | (link (or (> (incf link-count) 1)
2403 | (not (org-twbs-inline-image-p obj info))))
2404 | (otherwise t))
2405 | (throw 'exit nil)))
2406 | info nil 'link)
2407 | (= link-count 1))))))
2408 |
2409 | (defun org-twbs-export-file-uri (filename)
2410 | "Return file URI associated to FILENAME."
2411 | (cond ((org-string-match-p "\\`//" filename) (concat "file:" filename))
2412 | ((not (file-name-absolute-p filename)) filename)
2413 | ((org-file-remote-p filename) (concat "file:/" filename))
2414 | (t (concat "file://" (expand-file-name filename)))))
2415 |
2416 | (defun org-twbs-fuzzy (file search)
2417 | (cond ((fboundp 'org-publish-resolve-external-fuzzy-link)
2418 | (let ((numbers
2419 | (org-publish-resolve-external-fuzzy-link file search)))
2420 | (and numbers (concat "#sec-"
2421 | (mapconcat 'number-to-string
2422 | numbers "-")))))
2423 | ((fboundp 'org-publish-resolve-external-link)
2424 | (let ((rez (org-publish-resolve-external-link search file)))
2425 | (concat "#" rez)))
2426 | (t "")))
2427 |
2428 | (defun org-twbs-link (link desc info)
2429 | "Transcode a LINK object from Org to HTML.
2430 | DESC is the description part of the link, or the empty string.
2431 | INFO is a plist holding contextual information. See
2432 | `org-export-data'."
2433 | (let* ((home (when (plist-get info :html-link-home)
2434 | (org-trim (plist-get info :html-link-home))))
2435 | (use-abs-url (plist-get info :html-link-use-abs-url))
2436 | (link-org-files-as-html-maybe
2437 | (lambda (raw-path info)
2438 | ;; Treat links to `file.org' as links to `file.html', if
2439 | ;; needed. See `org-twbs-link-org-files-as-html'.
2440 | (cond
2441 | ((and (plist-get info :html-link-org-files-as-html)
2442 | (string= ".org"
2443 | (downcase (file-name-extension raw-path "."))))
2444 | (concat (file-name-sans-extension raw-path) "."
2445 | (plist-get info :html-extension)))
2446 | (t raw-path))))
2447 | (type (org-element-property :type link))
2448 | (raw-path (org-element-property :path link))
2449 | ;; Ensure DESC really exists, or set it to nil.
2450 | (desc (org-string-nw-p desc))
2451 | (path
2452 | (cond
2453 | ((member type '("http" "https" "ftp" "mailto"))
2454 | (with-no-warnings
2455 | ;; handle changes in arity and naming between org 9.1 and 9.3
2456 | (condition-case nil
2457 | (org-link-encode
2458 | (org-link-decode
2459 | (concat type ":" raw-path)) '(32 91 93 37))
2460 | (error
2461 | (org-link-escape
2462 | (org-link-unescape
2463 | (concat type ":" raw-path)) '(32 91 93 37))))))
2464 | ((string= type "file")
2465 | ;; Treat links to ".org" files as ".html", if needed.
2466 | (setq raw-path
2467 | (funcall link-org-files-as-html-maybe raw-path info))
2468 | ;; If file path is absolute, prepend it with protocol
2469 | ;; component - "file://".
2470 | (cond
2471 | ((file-name-absolute-p raw-path)
2472 | (setq raw-path (org-twbs-export-file-uri raw-path)))
2473 | ((and home use-abs-url)
2474 | (setq raw-path (concat (file-name-as-directory home) raw-path))))
2475 | ;; Add search option, if any. A search option can be
2476 | ;; relative to a custom-id, a headline title a name,
2477 | ;; a target or a radio-target.
2478 | (let ((option (org-element-property :search-option link)))
2479 | (cond ((not option) raw-path)
2480 | ;; Since HTML back-end use custom-id value as-is,
2481 | ;; resolving is them is trivial.
2482 | ((eq (string-to-char option) ?#) (concat raw-path option))
2483 | (t
2484 | (concat raw-path
2485 | (org-twbs-fuzzy
2486 | (org-element-property :path link)
2487 | option))))))
2488 | (t raw-path)))
2489 | ;; Extract attributes from parent's paragraph. HACK: Only do
2490 | ;; this for the first link in parent (inner image link for
2491 | ;; inline images). This is needed as long as attributes
2492 | ;; cannot be set on a per link basis.
2493 | (attributes-plist
2494 | (let* ((parent (org-export-get-parent-element link))
2495 | (link (let ((container (org-export-get-parent link)))
2496 | (if (and (eq (org-element-type container) 'link)
2497 | (org-twbs-inline-image-p link info))
2498 | container
2499 | link))))
2500 | (and (eq (org-element-map parent 'link 'identity info t) link)
2501 | (org-export-read-attribute :attr_html parent))))
2502 | (attributes
2503 | (let ((attr (org-twbs--make-attribute-string attributes-plist)))
2504 | (if (org-string-nw-p attr) (concat " " attr) ""))))
2505 | (cond
2506 | ;; Image file.
2507 | ((and (plist-get info :html-inline-images)
2508 | (org-export-inline-image-p
2509 | link (plist-get info :html-inline-image-rules)))
2510 | (org-twbs--format-image path attributes-plist info))
2511 | ;; Radio target: Transcode target's contents and use them as
2512 | ;; link's description.
2513 | ((string= type "radio")
2514 | (let ((destination (org-export-resolve-radio-link link info)))
2515 | (if (not destination) desc
2516 | (format "%s"
2517 | (org-element-property :value destination)
2518 | attributes desc))))
2519 | ;; Links pointing to a headline: Find destination and build
2520 | ;; appropriate referencing command.
2521 | ((member type '("custom-id" "fuzzy" "id"))
2522 | (let ((destination (if (string= type "fuzzy")
2523 | (org-export-resolve-fuzzy-link link info)
2524 | (org-export-resolve-id-link link info))))
2525 | (case (org-element-type destination)
2526 | ;; ID link points to an external file.
2527 | (plain-text
2528 | (let ((fragment (concat "ID-" path))
2529 | ;; Treat links to ".org" files as ".html", if needed.
2530 | (path (funcall link-org-files-as-html-maybe
2531 | destination info)))
2532 | (format "%s"
2533 | path fragment attributes (or desc destination))))
2534 | ;; Fuzzy link points nowhere.
2535 | ((nil)
2536 | (format "%s"
2537 | (or desc
2538 | (org-export-data
2539 | (org-element-property :raw-link link) info))))
2540 | ;; Link points to a headline.
2541 | (headline
2542 | (let ((href
2543 | ;; What href to use?
2544 | (cond
2545 | ;; Case 1: Headline is linked via it's CUSTOM_ID
2546 | ;; property. Use CUSTOM_ID.
2547 | ((string= type "custom-id")
2548 | (org-element-property :CUSTOM_ID destination))
2549 | ;; Case 2: Headline is linked via it's ID property
2550 | ;; or through other means. Use the default href.
2551 | ((member type '("id" "fuzzy"))
2552 | (format "sec-%s"
2553 | (mapconcat 'number-to-string
2554 | (org-export-get-headline-number
2555 | destination info) "-")))
2556 | (t (error "Shouldn't reach here"))))
2557 | ;; What description to use? Previously, we'd look if
2558 | ;; section numbering was enabled, and use that
2559 | ;; number, however, rendering a link description as
2560 | ;; number seems less useful than destination title.
2561 | ;; And since Org 8.3 there has been a lot of
2562 | ;; dependencies on :section-number, so will do
2563 | ;; something simple here for now.
2564 | (desc
2565 | (or desc (org-export-data (org-element-property
2566 | :title destination) info))))
2567 | (format "%s"
2568 | href attributes desc)))
2569 | ;; Fuzzy link points to a target or an element.
2570 | (t
2571 | (let* ((path path)
2572 | (org-twbs-standalone-image-predicate 'org-twbs--has-caption-p)
2573 | (number (cond
2574 | (desc nil)
2575 | ((org-twbs-standalone-image-p destination info)
2576 | (org-export-get-ordinal
2577 | (org-element-map destination 'link
2578 | 'identity info t)
2579 | info 'link 'org-twbs-standalone-image-p))
2580 | (t (org-export-get-ordinal
2581 | destination info nil 'org-twbs--has-caption-p))))
2582 | (desc (cond (desc)
2583 | ((not number) "No description for this link")
2584 | ((numberp number) (number-to-string number))
2585 | (t (mapconcat 'number-to-string number ".")))))
2586 | (format "%s" path attributes desc))))))
2587 | ;; Coderef: replace link with the reference name or the
2588 | ;; equivalent line number.
2589 | ((string= type "coderef")
2590 | (let ((fragment (concat "coderef-" (org-twbs-encode-plain-text path))))
2591 | (format "%s"
2592 | fragment
2593 | (format "class=\"coderef\" onmouseover=\"CodeHighlightOn(this, \
2594 | '%s');\" onmouseout=\"CodeHighlightOff(this, '%s');\""
2595 | fragment fragment)
2596 | attributes
2597 | (format (org-export-get-coderef-format path desc)
2598 | (org-export-resolve-coderef path info)))))
2599 | ;; External link with a description part.
2600 | ((and path desc) (format "%s"
2601 | (org-twbs-encode-plain-text path)
2602 | attributes
2603 | desc))
2604 | ;; External link without a description part.
2605 | (path (let ((path (org-twbs-encode-plain-text path)))
2606 | (format "%s" path attributes path)))
2607 | ;; No path, only description. Try to do something useful.
2608 | (t (format "%s" desc)))))
2609 |
2610 | ;;;; Paragraph
2611 |
2612 | (defun org-twbs-paragraph (paragraph contents info)
2613 | "Transcode a PARAGRAPH element from Org to HTML.
2614 | CONTENTS is the contents of the paragraph, as a string. INFO is
2615 | the plist used as a communication channel."
2616 | (let* ((parent (org-export-get-parent paragraph))
2617 | (parent-type (org-element-type parent))
2618 | (style '((footnote-definition " class=\"footpara\"")))
2619 | (extra (or (cadr (assoc parent-type style)) "")))
2620 | (cond
2621 | ((and (eq (org-element-type parent) 'item)
2622 | (= (org-element-property :begin paragraph)
2623 | (org-element-property :contents-begin parent)))
2624 | ;; Leading paragraph in a list item have no tags.
2625 | contents)
2626 | ((org-twbs-standalone-image-p paragraph info)
2627 | ;; Standalone image.
2628 | (let ((caption
2629 | (let ((raw (org-export-data
2630 | (org-export-get-caption paragraph) info))
2631 | (org-twbs-standalone-image-predicate
2632 | 'org-twbs--has-caption-p))
2633 | (if (not (org-string-nw-p raw)) raw
2634 | (concat
2635 | ""
2636 | (format (org-twbs--translate "Figure %d:" info)
2637 | (org-export-get-ordinal
2638 | (org-element-map paragraph 'link
2639 | 'identity info t)
2640 | info nil 'org-twbs-standalone-image-p))
2641 | " " raw))))
2642 | (label (org-element-property :name paragraph)))
2643 | (org-twbs--wrap-image contents info caption label)))
2644 | ;; Regular paragraph.
2645 | (t (format "
\n%s
" extra contents)))))
2646 |
2647 | ;;;; Plain List
2648 |
2649 | ;; FIXME Maybe arg1 is not needed because
already sets
2650 | ;; the correct value for the item counter
2651 | (defun org-twbs-begin-plain-list (type &optional arg1)
2652 | "Insert the beginning of the HTML list depending on TYPE.
2653 | When ARG1 is a string, use it as the start parameter for ordered
2654 | lists."
2655 | (case type
2656 | (ordered
2657 | (format ""
2658 | (if arg1 (format " start=\"%d\"" arg1) "")))
2659 | (unordered "
")
2660 | (descriptive "
")))
2661 |
2662 | (defun org-twbs-end-plain-list (type)
2663 | "Insert the end of the HTML list depending on TYPE."
2664 | (case type
2665 | (ordered "
")
2666 | (unordered "")
2667 | (descriptive "")))
2668 |
2669 | (defun org-twbs-plain-list (plain-list contents info)
2670 | "Transcode a PLAIN-LIST element from Org to HTML.
2671 | CONTENTS is the contents of the list. INFO is a plist holding
2672 | contextual information."
2673 | (let* (arg1 ;; (assoc :counter (org-element-map plain-list 'item
2674 | (type (org-element-property :type plain-list)))
2675 | (format "%s\n%s%s"
2676 | (org-twbs-begin-plain-list type)
2677 | contents (org-twbs-end-plain-list type))))
2678 |
2679 | ;;;; Plain Text
2680 |
2681 | (defun org-twbs-convert-special-strings (string)
2682 | "Convert special characters in STRING to HTML."
2683 | (let ((all org-twbs-special-string-regexps)
2684 | e a re rpl start)
2685 | (while (setq a (pop all))
2686 | (setq re (car a) rpl (cdr a) start 0)
2687 | (while (string-match re string start)
2688 | (setq string (replace-match rpl t nil string))))
2689 | string))
2690 |
2691 | (defun org-twbs-encode-plain-text (text)
2692 | "Convert plain text characters from TEXT to HTML equivalent.
2693 | Possible conversions are set in `org-twbs-protect-char-alist'."
2694 | (mapc
2695 | (lambda (pair)
2696 | (setq text (replace-regexp-in-string (car pair) (cdr pair) text t t)))
2697 | org-twbs-protect-char-alist)
2698 | text)
2699 |
2700 | (defun org-twbs-plain-text (text info)
2701 | "Transcode a TEXT string from Org to HTML.
2702 | TEXT is the string to transcode. INFO is a plist holding
2703 | contextual information."
2704 | (let ((output text))
2705 | ;; Protect following characters: <, >, &.
2706 | (setq output (org-twbs-encode-plain-text output))
2707 | ;; Handle smart quotes. Be sure to provide original string since
2708 | ;; OUTPUT may have been modified.
2709 | (when (plist-get info :with-smart-quotes)
2710 | (setq output (org-export-activate-smart-quotes output :html info text)))
2711 | ;; Handle special strings.
2712 | (when (plist-get info :with-special-strings)
2713 | (setq output (org-twbs-convert-special-strings output)))
2714 | ;; Handle break preservation if required.
2715 | (when (plist-get info :preserve-breaks)
2716 | (setq output
2717 | (replace-regexp-in-string
2718 | "\\(\\\\\\\\\\)?[ \t]*\n"
2719 | (concat (org-twbs-close-tag "br" nil info) "\n") output)))
2720 | ;; Return value.
2721 | output))
2722 |
2723 |
2724 | ;; Planning
2725 |
2726 | (defun org-twbs-planning (planning contents info)
2727 | "Transcode a PLANNING element from Org to HTML.
2728 | CONTENTS is nil. INFO is a plist used as a communication
2729 | channel."
2730 | (let ((span-fmt "%s%s"))
2731 | (format
2732 | "
%s
"
2733 | (mapconcat
2734 | 'identity
2735 | (delq nil
2736 | (list
2737 | (let ((closed (org-element-property :closed planning)))
2738 | (when closed
2739 | (format span-fmt org-closed-string
2740 | (org-timestamp-translate closed))))
2741 | (let ((deadline (org-element-property :deadline planning)))
2742 | (when deadline
2743 | (format span-fmt org-deadline-string
2744 | (org-timestamp-translate deadline))))
2745 | (let ((scheduled (org-element-property :scheduled planning)))
2746 | (when scheduled
2747 | (format span-fmt org-scheduled-string
2748 | (org-timestamp-translate scheduled))))))
2749 | " "))))
2750 |
2751 | ;;;; Property Drawer
2752 |
2753 | (defun org-twbs-property-drawer (property-drawer contents info)
2754 | "Transcode a PROPERTY-DRAWER element from Org to HTML.
2755 | CONTENTS is nil. INFO is a plist holding contextual
2756 | information."
2757 | ;; The property drawer isn't exported but we want separating blank
2758 | ;; lines nonetheless.
2759 | "")
2760 |
2761 | ;;;; Quote Block
2762 |
2763 | (defun org-twbs-quote-block (quote-block contents info)
2764 | "Transcode a QUOTE-BLOCK element from Org to HTML.
2765 | CONTENTS holds the contents of the block. INFO is a plist
2766 | holding contextual information."
2767 | (format "
\n%s
" contents))
2768 |
2769 | ;;;; Quote Section
2770 |
2771 | (defun org-twbs-quote-section (quote-section contents info)
2772 | "Transcode a QUOTE-SECTION element from Org to HTML.
2773 | CONTENTS is nil. INFO is a plist holding contextual information."
2774 | (let ((value (org-remove-indentation
2775 | (org-element-property :value quote-section))))
2776 | (when value (format "
\n%s
" value))))
2777 |
2778 | ;;;; Section
2779 |
2780 | (defun org-twbs-section (section contents info)
2781 | "Transcode a SECTION element from Org to HTML.
2782 | CONTENTS holds the contents of the section. INFO is a plist
2783 | holding contextual information."
2784 | (let ((parent (org-export-get-parent-headline section)))
2785 | ;; Before first headline: no container, just return CONTENTS.
2786 | (if (not parent) contents
2787 | ;; Get div's class and id references.
2788 | (let* ((class-num (+ (org-export-get-relative-level parent info)
2789 | (1- org-twbs-toplevel-hlevel)))
2790 | (section-number
2791 | (mapconcat
2792 | 'number-to-string
2793 | (org-export-get-headline-number parent info) "-")))
2794 | ;; Build return value.
2795 | (format "
\n%s
"
2796 | class-num
2797 | (or (org-element-property :CUSTOM_ID parent) section-number)
2798 | (or contents ""))))))
2799 |
2800 | ;;;; Radio Target
2801 |
2802 | (defun org-twbs-radio-target (radio-target text info)
2803 | "Transcode a RADIO-TARGET object from Org to HTML.
2804 | TEXT is the text of the target. INFO is a plist holding
2805 | contextual information."
2806 | (let ((id (org-element-property :value radio-target)))
2807 | (org-twbs--anchor id text)))
2808 |
2809 | ;;;; Special Block
2810 |
2811 | (defun org-twbs-special-block (special-block contents info)
2812 | "Transcode a SPECIAL-BLOCK element from Org to HTML.
2813 | CONTENTS holds the contents of the block. INFO is a plist
2814 | holding contextual information."
2815 | (let* ((block-type (downcase
2816 | (org-element-property :type special-block)))
2817 | (contents (or contents ""))
2818 | (is-html5-tag? (member block-type org-html-html5-elements))
2819 | (attributes (org-export-read-attribute :attr_html special-block)))
2820 | (unless is-html5-tag?
2821 | (let ((class (plist-get attributes :class)))
2822 | (setq attributes (plist-put attributes :class
2823 | (if class (concat class " " block-type)
2824 | block-type)))))
2825 | (setq attributes (org-twbs--make-attribute-string attributes))
2826 | (when (not (equal attributes ""))
2827 | (setq attributes (concat " " attributes)))
2828 | (if is-html5-tag?
2829 | (format "<%s%s>\n%s%s>" block-type attributes contents block-type)
2830 | (format "
")
3041 | (concat
3042 | ""
3043 | (format (org-twbs--translate "Table %d:" info) number)
3044 | " " (org-export-data caption info))))
3045 | (funcall table-column-specs table info)
3046 | contents)))))
3047 |
3048 | ;;;; Target
3049 |
3050 | (defun org-twbs-target (target contents info)
3051 | "Transcode a TARGET object from Org to HTML.
3052 | CONTENTS is nil. INFO is a plist holding contextual
3053 | information."
3054 | (let ((id (org-element-property :value target)))
3055 | (org-twbs--anchor id)))
3056 |
3057 | ;;;; Timestamp
3058 |
3059 | (defun org-twbs-timestamp (timestamp contents info)
3060 | "Transcode a TIMESTAMP object from Org to HTML.
3061 | CONTENTS is nil. INFO is a plist holding contextual
3062 | information."
3063 | (let ((value (org-twbs-plain-text
3064 | (org-timestamp-translate timestamp) info)))
3065 | (format "%s"
3066 | (replace-regexp-in-string "--" "–" value))))
3067 |
3068 | ;;;; Underline
3069 |
3070 | (defun org-twbs-underline (underline contents info)
3071 | "Transcode UNDERLINE from Org to HTML.
3072 | CONTENTS is the text with underline markup. INFO is a plist
3073 | holding contextual information."
3074 | (format (or (cdr (assq 'underline org-twbs-text-markup-alist)) "%s")
3075 | contents))
3076 |
3077 | ;;;; Verbatim
3078 |
3079 | (defun org-twbs-verbatim (verbatim contents info)
3080 | "Transcode VERBATIM from Org to HTML.
3081 | CONTENTS is nil. INFO is a plist holding contextual
3082 | information."
3083 | (format (or (cdr (assq 'verbatim org-twbs-text-markup-alist)) "%s")
3084 | (org-twbs-encode-plain-text (org-element-property :value verbatim))))
3085 |
3086 | ;;;; Verse Block
3087 |
3088 | (defun org-twbs-verse-block (verse-block contents info)
3089 | "Transcode a VERSE-BLOCK element from Org to HTML.
3090 | CONTENTS is verse block contents. INFO is a plist holding
3091 | contextual information."
3092 | ;; Replace each newline character with line break. Also replace
3093 | ;; each blank line with a line break.
3094 | (setq contents (replace-regexp-in-string
3095 | "^ *\\\\\\\\$" (format "%s\n" (org-twbs-close-tag "br" nil info))
3096 | (replace-regexp-in-string
3097 | "\\(\\\\\\\\\\)?[ \t]*\n"
3098 | (format "%s\n" (org-twbs-close-tag "br" nil info)) contents)))
3099 | ;; Replace each white space at beginning of a line with a
3100 | ;; non-breaking space.
3101 | (while (string-match "^[ \t]+" contents)
3102 | (let* ((num-ws (length (match-string 0 contents)))
3103 | (ws (let (out) (dotimes (i num-ws out)
3104 | (setq out (concat out " "))))))
3105 | (setq contents (replace-match ws nil t contents))))
3106 | (format "
\n%s
" contents))
3107 |
3108 |
3109 | ;;; Filter Functions
3110 |
3111 | (defun org-twbs-final-function (contents backend info)
3112 | "Filter to indent the HTML and convert HTML entities."
3113 | (with-temp-buffer
3114 | (insert contents)
3115 | (set-auto-mode t)
3116 | (if org-twbs-indent
3117 | (indent-region (point-min) (point-max)))
3118 | (when org-twbs-use-unicode-chars
3119 | (require 'mm-url)
3120 | (mm-url-decode-entities))
3121 | (buffer-substring-no-properties (point-min) (point-max))))
3122 |
3123 |
3124 | ;;; End-user functions
3125 |
3126 | ;;;###autoload
3127 | (defun org-twbs-export-as-html
3128 | (&optional async subtreep visible-only body-only ext-plist)
3129 | "Export current buffer to an HTML buffer.
3130 |
3131 | If narrowing is active in the current buffer, only export its
3132 | narrowed part.
3133 |
3134 | If a region is active, export that region.
3135 |
3136 | A non-nil optional argument ASYNC means the process should happen
3137 | asynchronously. The resulting buffer should be accessible
3138 | through the `org-export-stack' interface.
3139 |
3140 | When optional argument SUBTREEP is non-nil, export the sub-tree
3141 | at point, extracting information from the headline properties
3142 | first.
3143 |
3144 | When optional argument VISIBLE-ONLY is non-nil, don't export
3145 | contents of hidden elements.
3146 |
3147 | When optional argument BODY-ONLY is non-nil, only write code
3148 | between \"\" and \"\" tags.
3149 |
3150 | EXT-PLIST, when provided, is a property list with external
3151 | parameters overriding Org default settings, but still inferior to
3152 | file-local settings.
3153 |
3154 | Export is done in a buffer named \"*Org HTML Export*\", which
3155 | will be displayed when `org-export-show-temporary-export-buffer'
3156 | is non-nil."
3157 | (interactive)
3158 | (org-export-to-buffer 'twbs "*Org HTML Export*"
3159 | async subtreep visible-only body-only ext-plist
3160 | (lambda () (set-auto-mode t))))
3161 |
3162 | ;;;###autoload
3163 | (defun org-twbs-convert-region-to-html ()
3164 | "Assume the current region has org-mode syntax, and convert it to HTML.
3165 | This can be used in any buffer. For example, you can write an
3166 | itemized list in org-mode syntax in an HTML buffer and use this
3167 | command to convert it."
3168 | (interactive)
3169 | (org-export-replace-region-by 'twbs))
3170 |
3171 | ;;;###autoload
3172 | (defun org-twbs-export-to-html
3173 | (&optional async subtreep visible-only body-only ext-plist)
3174 | "Export current buffer to a HTML file.
3175 |
3176 | If narrowing is active in the current buffer, only export its
3177 | narrowed part.
3178 |
3179 | If a region is active, export that region.
3180 |
3181 | A non-nil optional argument ASYNC means the process should happen
3182 | asynchronously. The resulting file should be accessible through
3183 | the `org-export-stack' interface.
3184 |
3185 | When optional argument SUBTREEP is non-nil, export the sub-tree
3186 | at point, extracting information from the headline properties
3187 | first.
3188 |
3189 | When optional argument VISIBLE-ONLY is non-nil, don't export
3190 | contents of hidden elements.
3191 |
3192 | When optional argument BODY-ONLY is non-nil, only write code
3193 | between \"\" and \"\" tags.
3194 |
3195 | EXT-PLIST, when provided, is a property list with external
3196 | parameters overriding Org default settings, but still inferior to
3197 | file-local settings.
3198 |
3199 | Return output file's name."
3200 | (interactive)
3201 | (let* ((extension (concat "." org-twbs-extension))
3202 | (file (org-export-output-file-name extension subtreep))
3203 | (org-export-coding-system org-twbs-coding-system))
3204 | (org-export-to-file 'twbs file
3205 | async subtreep visible-only body-only ext-plist)))
3206 |
3207 | ;;;###autoload
3208 | (defun org-twbs-publish-to-html (plist filename pub-dir)
3209 | "Publish an org file to HTML.
3210 |
3211 | FILENAME is the filename of the Org file to be published. PLIST
3212 | is the property list for the given project. PUB-DIR is the
3213 | publishing directory.
3214 |
3215 | Return output file name."
3216 | (org-publish-org-to 'twbs filename
3217 | (concat "." (or (plist-get plist :html-extension)
3218 | org-twbs-extension "html"))
3219 | plist pub-dir))
3220 |
3221 |
3222 | (provide 'ox-twbs)
3223 |
3224 | ;; Local variables:
3225 | ;; coding: utf-8
3226 | ;; End:
3227 |
3228 | ;;; ox-twbs.el ends here
3229 |
--------------------------------------------------------------------------------