1 ;;File adding and overriding parts of org-html
4 ;;;_ , General: make HTML links
5 ;;;_ . tehom-org-html-cvt-link-fn
6 (defconst tehom-org-html-cvt-link-fn
7 ;;May change to take more args and combine type + path + fragment
9 "Function to convert link URLs to exportable URLs.
10 Intended for remote exporting." )
12 ;;Special variables seen:
13 ;;`html-extension' -- From plist
16 ;;;_ . tehom-org-html-make-link
17 ;;Adapted from `org-export-as-html'
18 (defun tehom-org-html-make-link (type path fragment desc descp attr
21 TYPE is the device-type of the link (And isn't used yet) (THIS://foo.html)
22 PATH is the path of the link (http://THIS)
23 FRAGMENT is the fragment part of the link, if any (The foo.html#THIS part)
24 DESC is the link description, if any.
25 DESCP is whether there originally was a description.
26 ATTR is a string of other attributes of the a element.
27 MAY-INLINE-P allows inlining it as an image."
28 ;;`org-par-open' is a special variable so it's not in the arglist.
33 ;;First pass. Mostly deals with treating local files. TYPE
36 ((string= type
"file")
37 ;;Substitute just if original path was absolute.
38 ;;(Otherwise path must remain relative)
40 (if (file-name-absolute-p filename
)
41 (expand-file-name filename
)
44 (when (and org-export-html-link-org-files-as-html
45 (string-match "\\.org$" thefile
))
47 (setq thefile
(concat (substring thefile
0
49 "." html-extension
))))
50 (t (setq thefile filename
)))
52 ;;If applicable, convert local path to remote URL
55 (funcall tehom-org-html-cvt-link-fn thefile
)
58 ;;Second pass. Build final link except for leading type
59 ;;spec. Now TYPE is final.
63 (string= type
"https"))
65 (setq thefile
(concat thefile
"#" fragment
))))
69 ;;Final URL-build, for all types.
71 (concat type
":" (org-export-html-format-href thefile
)))
75 ;;Can't inline a URL with a fragment.
78 (eq t org-export-html-inline-images
)
80 org-export-html-inline-images
83 filename org-export-html-inline-image-extensions
))
86 (message "image %s %s" thefile org-par-open
)
87 (org-export-html-format-image thefile org-par-open
))
89 "<a href=\"" thefile
"\"" attr
">"
90 (org-export-html-format-desc desc
)
93 ;;;_ . Borrowed from org-html
95 (defun org-export-as-html (arg &optional hidden ext-plist
96 to-buffer body-only pub-dir
)
97 "Export the outline as a pretty HTML file.
98 If there is an active region, export only the region. The prefix
99 ARG specifies how many levels of the outline should become
100 headlines. The default is 3. Lower levels will become bulleted
101 lists. HIDDEN is obsolete and does nothing.
102 EXT-PLIST is a property list with external parameters overriding
103 org-mode's default settings, but still inferior to file-local
104 settings. When TO-BUFFER is non-nil, create a buffer with that
105 name and export to that buffer. If TO-BUFFER is the symbol
106 `string', don't leave any buffer behind but just return the
107 resulting HTML as a string. When BODY-ONLY is set, don't produce
108 the file header and footer, simply return the content of
109 <body>...</body>, without even the body tags themselves. When
110 PUB-DIR is set, use this as the publishing directory."
112 (run-hooks 'org-export-first-hook
)
114 ;; Make sure we have a file name when we need it.
115 (when (and (not (or to-buffer body-only
))
116 (not buffer-file-name
))
117 (if (buffer-base-buffer)
118 (org-set-local 'buffer-file-name
119 (with-current-buffer (buffer-base-buffer)
121 (error "Need a file name to be able to export")))
123 (message "Exporting...")
124 (setq-default org-todo-line-regexp org-todo-line-regexp
)
125 (setq-default org-deadline-line-regexp org-deadline-line-regexp
)
126 (setq-default org-done-keywords org-done-keywords
)
127 (setq-default org-maybe-keyword-time-regexp org-maybe-keyword-time-regexp
)
129 (org-export-process-option-filters
130 (org-combine-plists (org-default-export-plist)
132 (org-infile-export-plist))))
133 (body-only (or body-only
(plist-get opt-plist
:body-only
)))
134 (style (concat (if (plist-get opt-plist
:style-include-default
)
135 org-export-html-style-default
)
136 (plist-get opt-plist
:style
)
137 (plist-get opt-plist
:style-extra
)
139 (if (plist-get opt-plist
:style-include-scripts
)
140 org-export-html-scripts
)))
141 (html-extension (plist-get opt-plist
:html-extension
))
142 (link-validate (plist-get opt-plist
:link-validation-function
))
143 valid thetoc have-headings first-heading-pos
144 (odd org-odd-levels-only
)
145 (region-p (org-region-active-p))
146 (rbeg (and region-p
(region-beginning)))
147 (rend (and region-p
(region-end)))
149 (if (plist-get opt-plist
:ignore-subtree-p
)
154 (and (org-at-heading-p)
155 (>= (org-end-of-subtree t t
) rend
))))))
156 (level-offset (if subtree-p
159 (+ (funcall outline-level
)
160 (if org-odd-levels-only
1 0)))
162 (opt-plist (setq org-export-opt-plist
164 (org-export-add-subtree-options opt-plist rbeg
)
166 ;; The following two are dynamically scoped into other
168 (org-current-export-dir
169 (or pub-dir
(org-export-directory :html opt-plist
)))
170 (org-current-export-file buffer-file-name
)
171 (level 0) (line "") (origline "") txt todo
174 (filename (if to-buffer nil
177 (file-name-sans-extension
179 (org-entry-get (region-beginning)
180 "EXPORT_FILE_NAME" t
))
181 (file-name-nondirectory buffer-file-name
)))
183 (file-name-as-directory
184 (or pub-dir
(org-export-directory :html opt-plist
))))))
185 (current-dir (if buffer-file-name
186 (file-name-directory buffer-file-name
)
188 (buffer (if to-buffer
190 ((eq to-buffer
'string
) (get-buffer-create "*Org HTML Export*"))
191 (t (get-buffer-create to-buffer
)))
192 (find-file-noselect filename
)))
193 (org-levels-open (make-vector org-level-max nil
))
194 (date (plist-get opt-plist
:date
))
195 (author (plist-get opt-plist
:author
))
196 (title (or (and subtree-p
(org-export-get-title-from-subtree))
197 (plist-get opt-plist
:title
)
200 (plist-get opt-plist
:skip-before-1st-heading
))
201 (org-export-grab-title-from-buffer))
202 (and buffer-file-name
203 (file-name-sans-extension
204 (file-name-nondirectory buffer-file-name
)))
206 (link-up (and (plist-get opt-plist
:link-up
)
207 (string-match "\\S-" (plist-get opt-plist
:link-up
))
208 (plist-get opt-plist
:link-up
)))
209 (link-home (and (plist-get opt-plist
:link-home
)
210 (string-match "\\S-" (plist-get opt-plist
:link-home
))
211 (plist-get opt-plist
:link-home
)))
212 (dummy (setq opt-plist
(plist-put opt-plist
:title title
)))
213 (html-table-tag (plist-get opt-plist
:html-table-tag
))
214 (quote-re0 (concat "^[ \t]*" org-quote-string
"\\>"))
215 (quote-re (concat "^\\(\\*+\\)\\([ \t]+" org-quote-string
"\\>\\)"))
220 (local-list-type nil
)
221 (local-list-indent nil
)
222 (llt org-plain-list-ordered-item-terminator
)
223 (email (plist-get opt-plist
:email
))
224 (language (plist-get opt-plist
:language
))
225 (keywords (plist-get opt-plist
:keywords
))
226 (description (plist-get opt-plist
:description
))
230 (coding-system (and (boundp 'buffer-file-coding-system
)
231 buffer-file-coding-system
))
232 (coding-system-for-write (or org-export-html-coding-system
234 (save-buffer-coding-system (or org-export-html-coding-system
236 (charset (and coding-system-for-write
237 (fboundp 'coding-system-get
)
238 (coding-system-get coding-system-for-write
242 (if region-p
(region-beginning) (point-min))
243 (if region-p
(region-end) (point-max))))
246 (org-export-preprocess-string
250 :skip-before-1st-heading
251 (plist-get opt-plist
:skip-before-1st-heading
)
252 :drawers
(plist-get opt-plist
:drawers
)
253 :todo-keywords
(plist-get opt-plist
:todo-keywords
)
254 :tags
(plist-get opt-plist
:tags
)
255 :priority
(plist-get opt-plist
:priority
)
256 :footnotes
(plist-get opt-plist
:footnotes
)
257 :timestamps
(plist-get opt-plist
:timestamps
)
259 (plist-get opt-plist
:archived-trees
)
260 :select-tags
(plist-get opt-plist
:select-tags
)
261 :exclude-tags
(plist-get opt-plist
:exclude-tags
)
263 (plist-get opt-plist
:text
)
265 (plist-get opt-plist
:LaTeX-fragments
))
268 table-buffer table-orig-buffer
269 ind item-type starter didclose
270 rpl path attr desc descp desc1 desc2 link
272 footnotes footref-seen
276 (let ((inhibit-read-only t
))
278 (remove-text-properties (point-min) (point-max)
279 '(:org-license-to-kill t
))))
281 (message "Exporting...")
283 (setq org-min-level
(org-get-min-level lines level-offset
))
284 (setq org-last-level org-min-level
)
285 (org-init-section-numbers)
288 ((and date
(string-match "%" date
))
289 (setq date
(format-time-string date
)))
291 (t (setq date
(format-time-string "%Y-%m-%d %T %Z"))))
293 ;; Get the language-dependent settings
294 (setq lang-words
(or (assoc language org-export-language-setup
)
295 (assoc "en" org-export-language-setup
)))
297 ;; Switch to the output buffer
299 (let ((inhibit-read-only t
)) (erase-buffer))
301 (org-install-letbind)
303 (and (fboundp 'set-buffer-file-coding-system
)
304 (set-buffer-file-coding-system coding-system-for-write
))
306 (let ((case-fold-search nil
)
307 (org-odd-levels-only odd
))
308 ;; create local variables for all options, to make sure all called
309 ;; functions get the correct information
311 (set (make-local-variable (nth 2 x
))
312 (plist-get opt-plist
(car x
))))
313 org-export-plist-vars
)
314 (setq umax
(if arg
(prefix-numeric-value arg
)
315 org-export-headline-levels
))
316 (setq umax-toc
(if (integerp org-export-with-toc
)
317 (min org-export-with-toc umax
)
323 <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
324 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
325 <html xmlns=\"http://www.w3.org/1999/xhtml\"
326 lang=\"%s\" xml:lang=\"%s\">
329 <meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>
330 <meta name=\"generator\" content=\"Org-mode\"/>
331 <meta name=\"generated\" content=\"%s\"/>
332 <meta name=\"author\" content=\"%s\"/>
333 <meta name=\"description\" content=\"%s\"/>
334 <meta name=\"keywords\" content=\"%s\"/>
342 (or (and (stringp org-export-html-xml-declaration
)
343 org-export-html-xml-declaration
)
344 (cdr (assoc html-extension org-export-html-xml-declaration
))
345 (cdr (assoc "html" org-export-html-xml-declaration
))
348 (or charset
"iso-8859-1"))
350 (org-html-expand title
)
351 (or charset
"iso-8859-1")
352 date author description keywords
354 (if (or link-up link-home
)
356 (format org-export-html-home
/up-format
357 (or link-up link-home
)
358 (or link-home link-up
))
362 (org-export-html-insert-plist-item opt-plist
:preamble opt-plist
)
364 (when (plist-get opt-plist
:auto-preamble
)
365 (if title
(insert (format org-export-html-title-format
366 (org-html-expand title
))))))
368 (if (and org-export-with-toc
(not body-only
))
370 (push (format "<h%d>%s</h%d>\n"
371 org-export-html-toplevel-hlevel
373 org-export-html-toplevel-hlevel
)
375 (push "<div id=\"text-table-of-contents\">\n" thetoc
)
376 (push "<ul>\n<li>" thetoc
)
378 (mapcar '(lambda (line)
379 (if (string-match org-todo-line-regexp line
)
380 ;; This is a headline
382 (setq have-headings t
)
383 (setq level
(- (match-end 1) (match-beginning 1)
385 level
(org-tr-level level
)
388 (org-export-cleanup-toc-line
389 (match-string 3 line
))))
391 (or (and org-export-mark-todo-in-toc
393 (not (member (match-string 2 line
)
396 (and org-export-mark-todo-in-toc
398 (org-search-todo-below
401 (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") txt
)
402 (setq txt
(replace-match " <span class=\"tag\"> \\1</span>" t nil txt
)))
403 (if (string-match quote-re0 txt
)
404 (setq txt
(replace-match "" t t txt
)))
405 (setq snumber
(org-section-number level
))
406 (if org-export-with-section-numbers
407 (setq txt
(concat snumber
" " txt
)))
408 (if (<= level
(max umax umax-toc
))
409 (setq head-count
(+ head-count
1)))
410 (if (<= level umax-toc
)
412 (if (> level org-last-level
)
414 (setq cnt
(- level org-last-level
))
415 (while (>= (setq cnt
(1- cnt
)) 0)
416 (push "\n<ul>\n<li>" thetoc
))
418 (if (< level org-last-level
)
420 (setq cnt
(- org-last-level level
))
421 (while (>= (setq cnt
(1- cnt
)) 0)
422 (push "</li>\n</ul>" thetoc
))
425 (while (string-match org-any-target-regexp line
)
426 (setq line
(replace-match
427 (concat "@<span class=\"target\">" (match-string 1 line
) "@</span> ")
429 (while (string-match "<\\(<\\)+\\|>\\(>\\)+" txt
)
430 (setq txt
(replace-match "" t t txt
)))
431 (setq href
(format "sec-%s" snumber
))
432 (setq href
(or (cdr (assoc href org-export-preferred-target-alist
)) href
))
436 "</li>\n<li><a href=\"#%s\"><span class=\"todo\">%s</span></a>"
437 "</li>\n<li><a href=\"#%s\">%s</a>")
440 (setq org-last-level level
))
444 (while (> org-last-level
(1- org-min-level
))
445 (setq org-last-level
(1- org-last-level
))
446 (push "</li>\n</ul>\n" thetoc
))
447 (push "</div>\n" thetoc
)
448 (setq thetoc
(if have-headings
(nreverse thetoc
) nil
))))
451 (org-init-section-numbers)
455 (while (setq line
(pop lines
) origline line
)
458 ;; end of quote section?
459 (when (and inquote
(string-match "^\\*+ " line
))
463 ;; inside a quote section?
465 (insert (org-html-protect line
) "\n")
466 (throw 'nextline nil
))
468 ;; Fixed-width, verbatim lines (examples)
469 (when (and org-export-with-fixed-width
470 (string-match "^[ \t]*:\\(\\([ \t]\\|$\\)\\(.*\\)\\)" line
))
473 (org-close-par-maybe)
475 (insert "<pre class=\"example\">\n"))
476 (insert (org-html-protect (match-string 3 line
)) "\n")
477 (when (or (not lines
)
478 (not (string-match "^[ \t]*:\\(\\([ \t]\\|$\\)\\(.*\\)\\)"
483 (throw 'nextline nil
))
485 (org-export-html-close-lists-maybe line
)
488 (when (get-text-property 0 'org-protected line
)
489 (let (par (ind (get-text-property 0 'original-indentation line
)))
490 (when (re-search-backward
491 "\\(<p>\\)\\([ \t\r\n]*\\)\\=" (- (point) 100) t
)
492 (setq par
(match-string 1))
493 (replace-match "\\2\n"))
496 (or (= (length (car lines
)) 0)
498 (equal ind
(get-text-property 0 'original-indentation
(car lines
))))
499 (or (= (length (car lines
)) 0)
500 (get-text-property 0 'org-protected
(car lines
))))
501 (insert (pop lines
) "\n"))
502 (and par
(insert "<p>\n")))
503 (throw 'nextline nil
))
505 ;; Blockquotes, verse, and center
506 (when (equal "ORG-BLOCKQUOTE-START" line
)
507 (org-close-par-maybe)
508 (insert "<blockquote>\n")
510 (throw 'nextline nil
))
511 (when (equal "ORG-BLOCKQUOTE-END" line
)
512 (org-close-par-maybe)
513 (insert "\n</blockquote>\n")
515 (throw 'nextline nil
))
516 (when (equal "ORG-VERSE-START" line
)
517 (org-close-par-maybe)
518 (insert "\n<p class=\"verse\">\n")
520 (throw 'nextline nil
))
521 (when (equal "ORG-VERSE-END" line
)
525 (throw 'nextline nil
))
526 (when (equal "ORG-CENTER-START" line
)
527 (org-close-par-maybe)
528 (insert "\n<div style=\"text-align: center\">")
530 (throw 'nextline nil
))
531 (when (equal "ORG-CENTER-END" line
)
532 (org-close-par-maybe)
535 (throw 'nextline nil
))
536 (run-hooks 'org-export-html-after-blockquotes-hook
)
538 (let ((i (org-get-string-indentation line
)))
540 (setq line
(concat (mapconcat 'identity
541 (make-list (* 2 i
) "\\nbsp") "")
542 " " (org-trim line
))))
543 (unless (string-match "\\\\\\\\[ \t]*$" line
)
544 (setq line
(concat line
"\\\\")))))
546 ;; make targets to anchors
549 "<<<?\\([^<>]*\\)>>>?\\((INVISIBLE)\\)?[ \t]*\n?" line start
)
551 ((get-text-property (match-beginning 1) 'org-protected line
)
552 (setq start
(match-end 1)))
554 (setq line
(replace-match
556 "@<a name=\"%s\" id=\"%s\">@</a>"
557 (org-solidify-link-text (match-string 1 line
))
558 (org-solidify-link-text (match-string 1 line
)))
560 ((and org-export-with-toc
(equal (string-to-char line
) ?
*))
561 ;; FIXME: NOT DEPENDENT on TOC?????????????????????
562 (setq line
(replace-match
563 (concat "@<span class=\"target\">"
564 (match-string 1 line
) "@</span> ")
565 ;; (concat "@<i>" (match-string 1 line) "@</i> ")
568 (setq line
(replace-match
569 (concat "@<a name=\""
570 (org-solidify-link-text (match-string 1 line
))
571 "\" class=\"target\">" (match-string 1 line
)
575 (setq line
(org-html-handle-time-stamps line
))
577 ;; replace "&" by "&", "<" and ">" by "<" and ">"
578 ;; handle @<..> HTML tags (replace "@>..<" by "<..>")
579 ;; Also handle sub_superscripts and checkboxes
580 (or (string-match org-table-hline-regexp line
)
581 (setq line
(org-html-expand line
)))
585 (while (string-match org-bracket-link-analytic-regexp
++ line start
)
586 (setq start
(match-beginning 0))
587 (setq path
(save-match-data (org-link-unescape
588 (match-string 3 line
))))
590 ((match-end 2) (match-string 2 line
))
592 (or (file-name-absolute-p path
)
593 (string-match "^\\.\\.?/" path
)))
596 (setq path
(org-extract-attributes (org-link-unescape path
)))
597 (setq attr
(get-text-property 0 'org-attributes path
))
598 (setq desc1
(if (match-end 5) (match-string 5 line
))
599 desc2
(if (match-end 2) (concat type
":" path
) path
)
600 descp
(and desc1
(not (equal desc1 desc2
)))
601 desc
(or desc1 desc2
))
602 ;; Make an image out of the description if that is so wanted
603 (when (and descp
(org-file-image-p
604 desc org-export-html-inline-image-extensions
))
606 (if (string-match "^file:" desc
)
607 (setq desc
(substring desc
(match-end 0)))))
608 (setq desc
(org-add-props
609 (concat "<img src=\"" desc
"\"/>")
610 '(org-protected t
))))
611 ;; FIXME: do we need to unescape here somewhere?
613 ((equal type
"internal")
614 ;;Replace this too. Never an image.
618 (if (= (string-to-char path
) ?
#) "" "#")
619 (org-solidify-link-text
620 (save-match-data (org-link-unescape path
)) nil
)
622 (org-export-html-format-desc desc
)
624 ((and (equal type
"id")
625 (setq id-file
(org-id-find-id-file path
)))
626 ;; This is an id: link to another file (if it was the same file,
627 ;; it would have become an internal link...)
629 (setq id-file
(file-relative-name
630 id-file
(file-name-directory org-current-export-file
)))
631 '(setq id-file
(concat (file-name-sans-extension id-file
)
634 (tehom-org-html-make-link
636 (concat (if (org-uuidgen-p path
) "ID-") path
)
637 (org-export-html-format-desc desc
)
641 ((member type
'("http" "https"))
644 ;; standard URL, just check if we need to inline an
647 (if (and (or (eq t org-export-html-inline-images
)
648 (and org-export-html-inline-images
(not descp
)))
650 path org-export-html-inline-image-extensions
))
651 (setq rpl
(org-export-html-format-image
652 (concat type
":" path
) org-par-open
))
653 (setq link
(concat type
":" path
))
654 (setq rpl
(concat "<a href=\""
655 (org-export-html-format-href link
)
657 (org-export-html-format-desc desc
)
660 (tehom-org-html-make-link
662 (org-export-html-format-desc desc
)
665 ;;But desc already becomes image.
667 ((member type
'("ftp" "mailto" "news"))
669 (setq link
(concat type
":" path
))
670 (setq rpl
(concat "<a href=\""
671 (org-export-html-format-href link
)
673 (org-export-html-format-desc desc
)
676 ((string= type
"coderef")
677 (setq rpl
(format "<a href=\"#coderef-%s\" class=\"coderef\" onmouseover=\"CodeHighlightOn(this, 'coderef-%s');\" onmouseout=\"CodeHighlightOff(this, 'coderef-%s');\">%s</a>"
679 (format (org-export-get-coderef-format path
(and descp desc
))
680 (cdr (assoc path org-export-code-refs
))))))
682 ((functionp (setq fnc
(nth 2 (assoc type org-link-protocols
))))
683 ;; The link protocol has a function for format the link
686 (funcall fnc
(org-link-unescape path
) desc1
'html
))))
688 ((string= type
"file")
693 (string-match "::\\(.*\\)" path
))
694 ;;Get the proper path
697 (replace-match "" t nil path
)
699 ;;Get the raw fragment
701 (match-string 1 filename
))
702 ;;Check the fragment. If it can't be used as
703 ;;target fragment we'll use nil instead.
707 (not (string-match "^[0-9]*$" fragment-0
))
708 (not (string-match "^\\*" fragment-0
))
709 (not (string-match "^/.*/$" fragment-0
)))
711 (org-solidify-link-text
712 (org-link-unescape fragment-0
))
715 (if (string-match "^file:" desc
)
717 ((desc-1 (replace-match "" t t desc
)))
718 (if (string-match "\\.org$" desc-1
)
719 (replace-match "" t t desc-1
)
726 (functionp link-validate
)
727 (not (funcall link-validate path-1 current-dir
)))
729 (tehom-org-html-make-link
730 "file" path-1 fragment-1 desc-2 descp
734 ;; just publish the path, as default
735 (setq rpl
(concat "<i><" type
":"
736 (save-match-data (org-link-unescape path
))
738 (setq line
(replace-match rpl t t line
)
739 start
(+ start
(length rpl
))))
742 (if (and (string-match org-todo-line-regexp line
)
746 (concat (substring line
0 (match-beginning 2))
748 (if (member (match-string 2 line
)
751 " " (match-string 2 line
)
752 "\"> " (org-export-html-get-todo-kwd-class-name
753 (match-string 2 line
))
754 "</span>" (substring line
(match-end 2)))))
756 ;; Does this contain a reference to a footnote?
757 (when org-export-with-footnotes
759 (while (string-match "\\([^* \t].*?\\)\\[\\([0-9]+\\)\\]" line start
)
760 (if (get-text-property (match-beginning 2) 'org-protected line
)
761 (setq start
(match-end 2))
762 (let ((n (match-string 2 line
)) extra a
)
763 (if (setq a
(assoc n footref-seen
))
765 (setcdr a
(1+ (cdr a
)))
766 (setq extra
(format ".%d" (cdr a
))))
768 (push (cons n
1) footref-seen
))
773 (format org-export-html-footnote-format
774 "<a class=\"footref\" name=\"fnr.%s%s\" href=\"#fn.%s\">%s</a>"))
775 (or (match-string 1 line
) "") n extra n n
)
779 ((string-match "^\\(\\*+\\)[ \t]+\\(.*\\)" line
)
780 ;; This is a headline
781 (setq level
(org-tr-level (- (match-end 1) (match-beginning 1)
783 txt
(match-string 2 line
))
784 (if (string-match quote-re0 txt
)
785 (setq txt
(replace-match "" t t txt
)))
786 (if (<= level
(max umax umax-toc
))
787 (setq head-count
(+ head-count
1)))
789 ;; Close any local lists before inserting a new header line
790 (while local-list-type
791 (org-close-li (car local-list-type
))
792 (insert (format "</%sl>\n" (car local-list-type
)))
793 (pop local-list-type
))
794 (setq local-list-indent nil
796 (setq first-heading-pos
(or first-heading-pos
(point)))
797 (org-html-level-start level txt umax
798 (and org-export-with-toc
(<= level umax
))
802 (when (string-match quote-re line
)
803 (org-close-par-maybe)
807 ((string-match "^[ \t]*- __+[ \t]*$" line
)
808 ;; Explicit list closure
809 (when local-list-type
810 (let ((ind (org-get-indentation line
)))
811 (while (and local-list-indent
812 (<= ind
(car local-list-indent
)))
813 (org-close-li (car local-list-type
))
814 (insert (format "</%sl>\n" (car local-list-type
)))
815 (pop local-list-type
)
816 (pop local-list-indent
))
817 (or local-list-indent
(setq in-local-list nil
))))
818 (throw 'nextline nil
))
820 ((and org-export-with-tables
821 (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line
))
822 (when (not table-open
)
824 (setq table-open t table-buffer nil table-orig-buffer nil
))
827 (setq table-buffer
(cons line table-buffer
)
828 table-orig-buffer
(cons origline table-orig-buffer
))
829 (when (or (not lines
)
830 (not (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)"
833 table-buffer
(nreverse table-buffer
)
834 table-orig-buffer
(nreverse table-orig-buffer
))
835 (org-close-par-maybe)
836 (insert (org-format-table-html table-buffer table-orig-buffer
))))
841 ((eq llt t
) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+[.)]\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
842 ((= llt ?.
) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+\\.\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
843 ((= llt ?\
)) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+)\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
844 (t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))
846 (setq ind
(or (get-text-property 0 'original-indentation line
)
847 (org-get-string-indentation line
))
848 item-type
(if (match-beginning 4) "o" "u")
849 starter
(if (match-beginning 2)
850 (substring (match-string 2 line
) 0 -
1))
851 line
(substring line
(match-beginning 5))
853 (if (and starter
(string-match "\\(.*?\\) ::[ \t]*" line
))
855 item-tag
(match-string 1 line
)
856 line
(substring line
(match-end 0))))
857 (when (and (not (equal item-type
"d"))
858 (not (string-match "[^ \t]" line
)))
859 ;; empty line. Pretend indentation is large.
860 (setq ind
(if org-empty-line-terminates-plain-lists
862 (1+ (or (car local-list-indent
) 1)))))
864 (while (and in-local-list
865 (or (and (= ind
(car local-list-indent
))
867 (< ind
(car local-list-indent
))))
869 (org-close-li (car local-list-type
))
870 (insert (format "</%sl>\n" (car local-list-type
)))
871 (pop local-list-type
) (pop local-list-indent
)
872 (setq in-local-list local-list-indent
))
875 (or (not in-local-list
)
876 (> ind
(car local-list-indent
))))
877 ;; Start new (level of) list
878 (org-close-par-maybe)
880 ((equal item-type
"u") "<ul>\n<li>\n")
881 ((equal item-type
"o") "<ol>\n<li>\n")
882 ((equal item-type
"d")
883 (format "<dl>\n<dt>%s</dt><dd>\n" item-tag
))))
884 (push item-type local-list-type
)
885 (push ind local-list-indent
)
886 (setq in-local-list t
))
888 ;; continue current list
889 (org-close-li (car local-list-type
))
891 ((equal (car local-list-type
) "d")
892 (format "<dt>%s</dt><dd>\n" (or item-tag
"???")))
895 ;; we did close a list, normal text follows: need <p>
897 (if (string-match "^[ \t]*\\[\\([X ]\\)\\]" line
)
900 (if (equal (match-string 1 line
) "X")
902 "<b>[<span style=\"visibility:hidden;\">X</span>]</b>")
906 (when (string-match "^[ \t]*-\\{5,\\}[ \t]*$" line
)
908 (insert "\n</p>\n<hr/>\n<p>\n")
909 (insert "\n<hr/>\n"))
910 (throw 'nextline nil
))
912 ;; Empty lines start a new paragraph. If hand-formatted lists
913 ;; are not fully interpreted, lines starting with "-", "+", "*"
914 ;; also start a new paragraph.
915 (if (string-match "^ [-+*]-\\|^[ \t]*$" line
) (org-open-par))
917 ;; Is this the start of a footnote?
918 (when org-export-with-footnotes
919 (when (and (boundp 'footnote-section-tag-regexp
)
920 (string-match (concat "^" footnote-section-tag-regexp
)
923 (throw 'nextline nil
))
924 (when (string-match "^[ \t]*\\[\\([0-9]+\\)\\]" line
)
925 (org-close-par-maybe)
926 (let ((n (match-string 1 line
)))
930 (concat "<p class=\"footnote\">"
931 (format org-export-html-footnote-format
932 "<a class=\"footnum\" name=\"fn.%s\" href=\"#fnr.%s\">%s</a>"))
934 ;; Check if the line break needs to be conserved
936 ((string-match "\\\\\\\\[ \t]*$" line
)
937 (setq line
(replace-match "<br/>" t t line
)))
938 (org-export-preserve-breaks
939 (setq line
(concat line
"<br/>"))))
941 ;; Check if a paragraph should be started
943 (while (and org-par-open
944 (string-match "\\\\par\\>" line start
))
945 ;; Leave a space in the </p> so that the footnote matcher
946 ;; does not see this.
947 (if (not (get-text-property (match-beginning 0)
948 'org-protected line
))
949 (setq line
(replace-match "</p ><p >" t t line
)))
950 (setq start
(match-end 0))))
952 (insert line
"\n")))))
954 ;; Properly close all local lists and other lists
959 ;; Close any local lists before inserting a new header line
960 (while local-list-type
961 (org-close-li (car local-list-type
))
962 (insert (format "</%sl>\n" (car local-list-type
)))
963 (pop local-list-type
))
964 (setq local-list-indent nil
966 (org-html-level-start 1 nil umax
967 (and org-export-with-toc
(<= level umax
))
969 ;; the </div> to close the last text-... div.
970 (when (and (> umax
0) first-heading-pos
) (insert "</div>\n"))
973 (goto-char (point-min))
974 (while (re-search-forward "<p class=\"footnote\">[^\000]*?\\(</p>\\|\\'\\)" nil t
)
975 (push (match-string 0) footnotes
)
976 (replace-match "" t t
)))
978 (insert (format org-export-html-footnotes-section
980 (mapconcat 'identity
(nreverse footnotes
) "\n"))
982 (let ((bib (org-export-html-get-bibliography)))
984 (insert "\n" bib
"\n")))
986 (when (plist-get opt-plist
:auto-postamble
)
987 (insert "<div id=\"postamble\">\n")
988 (when (and org-export-author-info author
)
989 (insert "<p class=\"author\"> "
990 (nth 1 lang-words
) ": " author
"\n")
992 (if (listp (split-string email
",+ *"))
994 (insert "<a href=\"mailto:" e
"\"><"
996 (split-string email
",+ *"))
997 (insert "<a href=\"mailto:" email
"\"><"
998 email
"></a>\n")))
1000 (when (and date org-export-time-stamp-file
)
1001 (insert "<p class=\"date\"> "
1002 (nth 2 lang-words
) ": "
1004 (when org-export-creator-info
1005 (insert (format "<p class=\"creator\">HTML generated by org-mode %s in emacs %s</p>\n"
1006 org-version emacs-major-version
)))
1007 (when org-export-html-validation-link
1008 (insert org-export-html-validation-link
"\n"))
1011 (if org-export-html-with-timestamp
1012 (insert org-export-html-html-helper-timestamp
))
1013 (org-export-html-insert-plist-item opt-plist
:postamble opt-plist
)
1014 (insert "\n</div>\n</body>\n</html>\n"))
1016 (unless (plist-get opt-plist
:buffer-will-be-killed
)
1018 (if (eq major-mode
(default-value 'major-mode
))
1021 ;; insert the table of contents
1022 (goto-char (point-min))
1024 (if (or (re-search-forward
1025 "<p>\\s-*\\[TABLE-OF-CONTENTS\\]\\s-*</p>" nil t
)
1027 "\\[TABLE-OF-CONTENTS\\]" nil t
))
1029 (goto-char (match-beginning 0))
1031 (goto-char first-heading-pos
)
1032 (when (looking-at "\\s-*</p>")
1033 (goto-char (match-end 0))
1035 (insert "<div id=\"table-of-contents\">\n")
1036 (mapc 'insert thetoc
)
1037 (insert "</div>\n"))
1038 ;; remove empty paragraphs and lists
1039 (goto-char (point-min))
1040 (while (re-search-forward "<p>[ \r\n\t]*</p>" nil t
)
1042 (goto-char (point-min))
1043 (while (re-search-forward "<li>[ \r\n\t]*</li>\n?" nil t
)
1045 (goto-char (point-min))
1046 (while (re-search-forward "</ul>\\s-*<ul>\n?" nil t
)
1048 ;; Convert whitespace place holders
1049 (goto-char (point-min))
1051 (while (setq beg
(next-single-property-change (point) 'org-whitespace
))
1052 (setq n
(get-text-property beg
'org-whitespace
)
1053 end
(next-single-property-change beg
'org-whitespace
))
1055 (delete-region beg end
)
1056 (insert (format "<span style=\"visibility:hidden;\">%s</span>"
1057 (make-string n ?x
)))))
1058 ;; Remove empty lines at the beginning of the file.
1059 (goto-char (point-min))
1060 (when (looking-at "\\s-+\n") (replace-match ""))
1061 ;; Remove display properties
1062 (remove-text-properties (point-min) (point-max) '(display t
))
1064 (run-hooks 'org-export-html-final-hook
)
1065 (or to-buffer
(save-buffer))
1066 (goto-char (point-min))
1067 (or (org-export-push-to-kill-ring "HTML")
1068 (message "Exporting... done"))
1069 (if (eq to-buffer
'string
)
1070 (prog1 (buffer-substring (point-min) (point-max))
1071 (kill-buffer (current-buffer)))
1072 (current-buffer)))))
1077 (provide 'org2blog
/for-org-html
)
1079 ;;;_ * Local emacs vars.
1080 ;;;_ + Local variables:
1085 ;;; org2blog/for-org-html.el ends here