1 ;;File adding and overriding parts of org-html
4 ;;;_ , General: make HTML links
5 ;;;_ . org-html-cvt-link-fn
6 (defconst org-html-cvt-link-fn
7 ;;In the future this might change to take more args: type + path +
10 "Function to convert link URLs to exportable URLs.
11 Takes one argument, PATH.
12 Returns exportable URL.
13 Intended for remote exporting." )
15 ;;Special variables seen:
16 ;;`html-extension' -- From plist
17 ;;`org-par-open' is a special variable so it's not in the arglist.
20 ;;;_ . org-html-make-link
21 ;;Adapted from `org-export-as-html'
22 (defun org-html-make-link (type path fragment desc descp attr
25 TYPE is the device-type of the link (And isn't used yet) (THIS://foo.html)
26 PATH is the path of the link (http://THIS)
27 FRAGMENT is the fragment part of the link, if any (The foo.html#THIS part)
28 DESC is the link description, if any.
29 DESCP is whether there originally was a description.
30 ATTR is a string of other attributes of the a element.
31 MAY-INLINE-P allows inlining it as an image."
33 (declare (special html-extension org-par-open
))
37 ;;First pass. Mostly deals with treating local files. TYPE
40 ((string= type
"file")
41 ;;Substitute just if original path was absolute.
42 ;;(Otherwise path must remain relative)
44 (if (file-name-absolute-p filename
)
45 (expand-file-name filename
)
48 (when (and org-export-html-link-org-files-as-html
49 (string-match "\\.org$" thefile
))
51 (setq thefile
(concat (substring thefile
0
53 "." html-extension
))))
54 (t (setq thefile filename
)))
56 ;;If applicable, convert local path to remote URL
59 (funcall org-html-cvt-link-fn thefile
)
62 ;;Second pass. Build final link except for leading type
63 ;;spec. Now TYPE is final.
67 (string= type
"https"))
69 (setq thefile
(concat thefile
"#" fragment
))))
73 ;;Final URL-build, for all types.
75 (concat type
":" (org-export-html-format-href thefile
)))
79 ;;Can't inline a URL with a fragment.
82 (eq t org-export-html-inline-images
)
84 org-export-html-inline-images
87 filename org-export-html-inline-image-extensions
))
90 (message "image %s %s" thefile org-par-open
)
91 (org-export-html-format-image thefile org-par-open
))
93 "<a href=\"" thefile
"\"" attr
">"
94 (org-export-html-format-desc desc
)
97 ;;;_ . Borrowed from org-html
99 (defun org-export-as-html (arg &optional hidden ext-plist
100 to-buffer body-only pub-dir
)
101 "Export the outline as a pretty HTML file.
102 If there is an active region, export only the region. The prefix
103 ARG specifies how many levels of the outline should become
104 headlines. The default is 3. Lower levels will become bulleted
105 lists. HIDDEN is obsolete and does nothing.
106 EXT-PLIST is a property list with external parameters overriding
107 org-mode's default settings, but still inferior to file-local
108 settings. When TO-BUFFER is non-nil, create a buffer with that
109 name and export to that buffer. If TO-BUFFER is the symbol
110 `string', don't leave any buffer behind but just return the
111 resulting HTML as a string. When BODY-ONLY is set, don't produce
112 the file header and footer, simply return the content of
113 <body>...</body>, without even the body tags themselves. When
114 PUB-DIR is set, use this as the publishing directory."
116 (run-hooks 'org-export-first-hook
)
118 ;; Make sure we have a file name when we need it.
119 (when (and (not (or to-buffer body-only
))
120 (not buffer-file-name
))
121 (if (buffer-base-buffer)
122 (org-set-local 'buffer-file-name
123 (with-current-buffer (buffer-base-buffer)
125 (error "Need a file name to be able to export")))
127 (message "Exporting...")
128 (setq-default org-todo-line-regexp org-todo-line-regexp
)
129 (setq-default org-deadline-line-regexp org-deadline-line-regexp
)
130 (setq-default org-done-keywords org-done-keywords
)
131 (setq-default org-maybe-keyword-time-regexp org-maybe-keyword-time-regexp
)
133 (org-export-process-option-filters
134 (org-combine-plists (org-default-export-plist)
136 (org-infile-export-plist))))
137 (body-only (or body-only
(plist-get opt-plist
:body-only
)))
138 (style (concat (if (plist-get opt-plist
:style-include-default
)
139 org-export-html-style-default
)
140 (plist-get opt-plist
:style
)
141 (plist-get opt-plist
:style-extra
)
143 (if (plist-get opt-plist
:style-include-scripts
)
144 org-export-html-scripts
)))
145 (html-extension (plist-get opt-plist
:html-extension
))
146 (link-validate (plist-get opt-plist
:link-validation-function
))
147 valid thetoc have-headings first-heading-pos
148 (odd org-odd-levels-only
)
149 (region-p (org-region-active-p))
150 (rbeg (and region-p
(region-beginning)))
151 (rend (and region-p
(region-end)))
153 (if (plist-get opt-plist
:ignore-subtree-p
)
158 (and (org-at-heading-p)
159 (>= (org-end-of-subtree t t
) rend
))))))
160 (level-offset (if subtree-p
163 (+ (funcall outline-level
)
164 (if org-odd-levels-only
1 0)))
166 (opt-plist (setq org-export-opt-plist
168 (org-export-add-subtree-options opt-plist rbeg
)
170 ;; The following two are dynamically scoped into other
172 (org-current-export-dir
173 (or pub-dir
(org-export-directory :html opt-plist
)))
174 (org-current-export-file buffer-file-name
)
175 (level 0) (line "") (origline "") txt todo
178 (filename (if to-buffer nil
181 (file-name-sans-extension
183 (org-entry-get (region-beginning)
184 "EXPORT_FILE_NAME" t
))
185 (file-name-nondirectory buffer-file-name
)))
187 (file-name-as-directory
188 (or pub-dir
(org-export-directory :html opt-plist
))))))
189 (current-dir (if buffer-file-name
190 (file-name-directory buffer-file-name
)
192 (buffer (if to-buffer
194 ((eq to-buffer
'string
) (get-buffer-create "*Org HTML Export*"))
195 (t (get-buffer-create to-buffer
)))
196 (find-file-noselect filename
)))
197 (org-levels-open (make-vector org-level-max nil
))
198 (date (plist-get opt-plist
:date
))
199 (author (plist-get opt-plist
:author
))
200 (title (or (and subtree-p
(org-export-get-title-from-subtree))
201 (plist-get opt-plist
:title
)
204 (plist-get opt-plist
:skip-before-1st-heading
))
205 (org-export-grab-title-from-buffer))
206 (and buffer-file-name
207 (file-name-sans-extension
208 (file-name-nondirectory buffer-file-name
)))
210 (link-up (and (plist-get opt-plist
:link-up
)
211 (string-match "\\S-" (plist-get opt-plist
:link-up
))
212 (plist-get opt-plist
:link-up
)))
213 (link-home (and (plist-get opt-plist
:link-home
)
214 (string-match "\\S-" (plist-get opt-plist
:link-home
))
215 (plist-get opt-plist
:link-home
)))
216 (dummy (setq opt-plist
(plist-put opt-plist
:title title
)))
217 (html-table-tag (plist-get opt-plist
:html-table-tag
))
218 (quote-re0 (concat "^[ \t]*" org-quote-string
"\\>"))
219 (quote-re (concat "^\\(\\*+\\)\\([ \t]+" org-quote-string
"\\>\\)"))
224 (local-list-type nil
)
225 (local-list-indent nil
)
226 (llt org-plain-list-ordered-item-terminator
)
227 (email (plist-get opt-plist
:email
))
228 (language (plist-get opt-plist
:language
))
229 (keywords (plist-get opt-plist
:keywords
))
230 (description (plist-get opt-plist
:description
))
234 (coding-system (and (boundp 'buffer-file-coding-system
)
235 buffer-file-coding-system
))
236 (coding-system-for-write (or org-export-html-coding-system
238 (save-buffer-coding-system (or org-export-html-coding-system
240 (charset (and coding-system-for-write
241 (fboundp 'coding-system-get
)
242 (coding-system-get coding-system-for-write
246 (if region-p
(region-beginning) (point-min))
247 (if region-p
(region-end) (point-max))))
250 (org-export-preprocess-string
254 :skip-before-1st-heading
255 (plist-get opt-plist
:skip-before-1st-heading
)
256 :drawers
(plist-get opt-plist
:drawers
)
257 :todo-keywords
(plist-get opt-plist
:todo-keywords
)
258 :tags
(plist-get opt-plist
:tags
)
259 :priority
(plist-get opt-plist
:priority
)
260 :footnotes
(plist-get opt-plist
:footnotes
)
261 :timestamps
(plist-get opt-plist
:timestamps
)
263 (plist-get opt-plist
:archived-trees
)
264 :select-tags
(plist-get opt-plist
:select-tags
)
265 :exclude-tags
(plist-get opt-plist
:exclude-tags
)
267 (plist-get opt-plist
:text
)
269 (plist-get opt-plist
:LaTeX-fragments
))
272 table-buffer table-orig-buffer
273 ind item-type starter didclose
274 rpl path attr desc descp desc1 desc2 link
276 footnotes footref-seen
280 (let ((inhibit-read-only t
))
282 (remove-text-properties (point-min) (point-max)
283 '(:org-license-to-kill t
))))
285 (message "Exporting...")
287 (setq org-min-level
(org-get-min-level lines level-offset
))
288 (setq org-last-level org-min-level
)
289 (org-init-section-numbers)
292 ((and date
(string-match "%" date
))
293 (setq date
(format-time-string date
)))
295 (t (setq date
(format-time-string "%Y-%m-%d %T %Z"))))
297 ;; Get the language-dependent settings
298 (setq lang-words
(or (assoc language org-export-language-setup
)
299 (assoc "en" org-export-language-setup
)))
301 ;; Switch to the output buffer
303 (let ((inhibit-read-only t
)) (erase-buffer))
305 (org-install-letbind)
307 (and (fboundp 'set-buffer-file-coding-system
)
308 (set-buffer-file-coding-system coding-system-for-write
))
310 (let ((case-fold-search nil
)
311 (org-odd-levels-only odd
))
312 ;; create local variables for all options, to make sure all called
313 ;; functions get the correct information
315 (set (make-local-variable (nth 2 x
))
316 (plist-get opt-plist
(car x
))))
317 org-export-plist-vars
)
318 (setq umax
(if arg
(prefix-numeric-value arg
)
319 org-export-headline-levels
))
320 (setq umax-toc
(if (integerp org-export-with-toc
)
321 (min org-export-with-toc umax
)
327 <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"
328 \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
329 <html xmlns=\"http://www.w3.org/1999/xhtml\"
330 lang=\"%s\" xml:lang=\"%s\">
333 <meta http-equiv=\"Content-Type\" content=\"text/html;charset=%s\"/>
334 <meta name=\"generator\" content=\"Org-mode\"/>
335 <meta name=\"generated\" content=\"%s\"/>
336 <meta name=\"author\" content=\"%s\"/>
337 <meta name=\"description\" content=\"%s\"/>
338 <meta name=\"keywords\" content=\"%s\"/>
346 (or (and (stringp org-export-html-xml-declaration
)
347 org-export-html-xml-declaration
)
348 (cdr (assoc html-extension org-export-html-xml-declaration
))
349 (cdr (assoc "html" org-export-html-xml-declaration
))
352 (or charset
"iso-8859-1"))
354 (org-html-expand title
)
355 (or charset
"iso-8859-1")
356 date author description keywords
358 (if (or link-up link-home
)
360 (format org-export-html-home
/up-format
361 (or link-up link-home
)
362 (or link-home link-up
))
366 (org-export-html-insert-plist-item opt-plist
:preamble opt-plist
)
368 (when (plist-get opt-plist
:auto-preamble
)
369 (if title
(insert (format org-export-html-title-format
370 (org-html-expand title
))))))
372 (if (and org-export-with-toc
(not body-only
))
374 (push (format "<h%d>%s</h%d>\n"
375 org-export-html-toplevel-hlevel
377 org-export-html-toplevel-hlevel
)
379 (push "<div id=\"text-table-of-contents\">\n" thetoc
)
380 (push "<ul>\n<li>" thetoc
)
382 (mapcar '(lambda (line)
383 (if (and (string-match org-todo-line-regexp line
)
384 (not (get-text-property 0 'org-protected line
)))
385 ;; This is a headline
387 (setq have-headings t
)
388 (setq level
(- (match-end 1) (match-beginning 1)
390 level
(org-tr-level level
)
393 (org-export-cleanup-toc-line
394 (match-string 3 line
))))
396 (or (and org-export-mark-todo-in-toc
398 (not (member (match-string 2 line
)
401 (and org-export-mark-todo-in-toc
403 (org-search-todo-below
406 (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") txt
)
407 (setq txt
(replace-match " <span class=\"tag\"> \\1</span>" t nil txt
)))
408 (if (string-match quote-re0 txt
)
409 (setq txt
(replace-match "" t t txt
)))
410 (setq snumber
(org-section-number level
))
411 (if org-export-with-section-numbers
412 (setq txt
(concat snumber
" " txt
)))
413 (if (<= level
(max umax umax-toc
))
414 (setq head-count
(+ head-count
1)))
415 (if (<= level umax-toc
)
417 (if (> level org-last-level
)
419 (setq cnt
(- level org-last-level
))
420 (while (>= (setq cnt
(1- cnt
)) 0)
421 (push "\n<ul>\n<li>" thetoc
))
423 (if (< level org-last-level
)
425 (setq cnt
(- org-last-level level
))
426 (while (>= (setq cnt
(1- cnt
)) 0)
427 (push "</li>\n</ul>" thetoc
))
430 (while (string-match org-any-target-regexp line
)
431 (setq line
(replace-match
432 (concat "@<span class=\"target\">" (match-string 1 line
) "@</span> ")
434 (while (string-match "<\\(<\\)+\\|>\\(>\\)+" txt
)
435 (setq txt
(replace-match "" t t txt
)))
436 (setq href
(format "sec-%s" snumber
))
437 (setq href
(or (cdr (assoc href org-export-preferred-target-alist
)) href
))
441 "</li>\n<li><a href=\"#%s\"><span class=\"todo\">%s</span></a>"
442 "</li>\n<li><a href=\"#%s\">%s</a>")
445 (setq org-last-level level
))
449 (while (> org-last-level
(1- org-min-level
))
450 (setq org-last-level
(1- org-last-level
))
451 (push "</li>\n</ul>\n" thetoc
))
452 (push "</div>\n" thetoc
)
453 (setq thetoc
(if have-headings
(nreverse thetoc
) nil
))))
456 (org-init-section-numbers)
460 (while (setq line
(pop lines
) origline line
)
463 ;; end of quote section?
464 (when (and inquote
(string-match "^\\*+ " line
))
468 ;; inside a quote section?
470 (insert (org-html-protect line
) "\n")
471 (throw 'nextline nil
))
473 ;; Fixed-width, verbatim lines (examples)
474 (when (and org-export-with-fixed-width
475 (string-match "^[ \t]*:\\(\\([ \t]\\|$\\)\\(.*\\)\\)" line
))
478 (org-close-par-maybe)
480 (insert "<pre class=\"example\">\n"))
481 (insert (org-html-protect (match-string 3 line
)) "\n")
482 (when (or (not lines
)
483 (not (string-match "^[ \t]*:\\(\\([ \t]\\|$\\)\\(.*\\)\\)"
488 (throw 'nextline nil
))
490 (org-export-html-close-lists-maybe line
)
493 (when (get-text-property 0 'org-protected line
)
494 (let (par (ind (get-text-property 0 'original-indentation line
)))
495 (when (re-search-backward
496 "\\(<p>\\)\\([ \t\r\n]*\\)\\=" (- (point) 100) t
)
497 (setq par
(match-string 1))
498 (replace-match "\\2\n"))
501 (or (= (length (car lines
)) 0)
503 (equal ind
(get-text-property 0 'original-indentation
(car lines
))))
504 (or (= (length (car lines
)) 0)
505 (get-text-property 0 'org-protected
(car lines
))))
506 (insert (pop lines
) "\n"))
507 (and par
(insert "<p>\n")))
508 (throw 'nextline nil
))
510 ;; Blockquotes, verse, and center
511 (when (equal "ORG-BLOCKQUOTE-START" line
)
512 (org-close-par-maybe)
513 (insert "<blockquote>\n")
515 (throw 'nextline nil
))
516 (when (equal "ORG-BLOCKQUOTE-END" line
)
517 (org-close-par-maybe)
518 (insert "\n</blockquote>\n")
520 (throw 'nextline nil
))
521 (when (equal "ORG-VERSE-START" line
)
522 (org-close-par-maybe)
523 (insert "\n<p class=\"verse\">\n")
525 (throw 'nextline nil
))
526 (when (equal "ORG-VERSE-END" line
)
530 (throw 'nextline nil
))
531 (when (equal "ORG-CENTER-START" line
)
532 (org-close-par-maybe)
533 (insert "\n<div style=\"text-align: center\">")
535 (throw 'nextline nil
))
536 (when (equal "ORG-CENTER-END" line
)
537 (org-close-par-maybe)
540 (throw 'nextline nil
))
541 (run-hooks 'org-export-html-after-blockquotes-hook
)
543 (let ((i (org-get-string-indentation line
)))
545 (setq line
(concat (mapconcat 'identity
546 (make-list (* 2 i
) "\\nbsp") "")
547 " " (org-trim line
))))
548 (unless (string-match "\\\\\\\\[ \t]*$" line
)
549 (setq line
(concat line
"\\\\")))))
551 ;; make targets to anchors
554 "<<<?\\([^<>]*\\)>>>?\\((INVISIBLE)\\)?[ \t]*\n?" line start
)
556 ((get-text-property (match-beginning 1) 'org-protected line
)
557 (setq start
(match-end 1)))
559 (setq line
(replace-match
561 "@<a name=\"%s\" id=\"%s\">@</a>"
562 (org-solidify-link-text (match-string 1 line
))
563 (org-solidify-link-text (match-string 1 line
)))
565 ((and org-export-with-toc
(equal (string-to-char line
) ?
*))
566 ;; FIXME: NOT DEPENDENT on TOC?????????????????????
567 (setq line
(replace-match
568 (concat "@<span class=\"target\">"
569 (match-string 1 line
) "@</span> ")
570 ;; (concat "@<i>" (match-string 1 line) "@</i> ")
573 (setq line
(replace-match
574 (concat "@<a name=\""
575 (org-solidify-link-text (match-string 1 line
))
576 "\" class=\"target\">" (match-string 1 line
)
580 (setq line
(org-html-handle-time-stamps line
))
582 ;; replace "&" by "&", "<" and ">" by "<" and ">"
583 ;; handle @<..> HTML tags (replace "@>..<" by "<..>")
584 ;; Also handle sub_superscripts and checkboxes
585 (or (string-match org-table-hline-regexp line
)
586 (setq line
(org-html-expand line
)))
590 (while (string-match org-bracket-link-analytic-regexp
++ line start
)
591 (setq start
(match-beginning 0))
592 (setq path
(save-match-data (org-link-unescape
593 (match-string 3 line
))))
595 ((match-end 2) (match-string 2 line
))
597 (or (file-name-absolute-p path
)
598 (string-match "^\\.\\.?/" path
)))
601 (setq path
(org-extract-attributes (org-link-unescape path
)))
602 (setq attr
(get-text-property 0 'org-attributes path
))
603 (setq desc1
(if (match-end 5) (match-string 5 line
))
604 desc2
(if (match-end 2) (concat type
":" path
) path
)
605 descp
(and desc1
(not (equal desc1 desc2
)))
606 desc
(or desc1 desc2
))
607 ;; Make an image out of the description if that is so wanted
608 (when (and descp
(org-file-image-p
609 desc org-export-html-inline-image-extensions
))
611 (if (string-match "^file:" desc
)
612 (setq desc
(substring desc
(match-end 0)))))
613 (setq desc
(org-add-props
614 (concat "<img src=\"" desc
"\"/>")
615 '(org-protected t
))))
616 ;; FIXME: do we need to unescape here somewhere?
618 ((equal type
"internal")
622 (if (= (string-to-char path
) ?
#) "" "#")
623 (org-solidify-link-text
624 (save-match-data (org-link-unescape path
)) nil
)
626 (org-export-html-format-desc desc
)
628 ((and (equal type
"id")
629 (setq id-file
(org-id-find-id-file path
)))
630 ;; This is an id: link to another file (if it was the same file,
631 ;; it would have become an internal link...)
633 (setq id-file
(file-relative-name
634 id-file
(file-name-directory org-current-export-file
)))
638 (concat (if (org-uuidgen-p path
) "ID-") path
)
639 (org-export-html-format-desc desc
)
643 ((member type
'("http" "https"))
644 ;; standard URL, just check if we need to inline an
649 (org-export-html-format-desc desc
)
652 ;;But desc already becomes image.
654 ((member type
'("ftp" "mailto" "news"))
656 (setq link
(concat type
":" path
))
657 (setq rpl
(concat "<a href=\""
658 (org-export-html-format-href link
)
660 (org-export-html-format-desc desc
)
663 ((string= type
"coderef")
664 (setq rpl
(format "<a href=\"#coderef-%s\" class=\"coderef\" onmouseover=\"CodeHighlightOn(this, 'coderef-%s');\" onmouseout=\"CodeHighlightOff(this, 'coderef-%s');\">%s</a>"
666 (format (org-export-get-coderef-format path
(and descp desc
))
667 (cdr (assoc path org-export-code-refs
))))))
669 ((functionp (setq fnc
(nth 2 (assoc type org-link-protocols
))))
670 ;; The link protocol has a function for format the link
673 (funcall fnc
(org-link-unescape path
) desc1
'html
))))
675 ((string= type
"file")
680 (string-match "::\\(.*\\)" path
))
681 ;;Get the proper path
684 (replace-match "" t nil path
)
686 ;;Get the raw fragment
688 (match-string 1 filename
))
689 ;;Check the fragment. If it can't be used as
690 ;;target fragment we'll use nil instead.
694 (not (string-match "^[0-9]*$" fragment-0
))
695 (not (string-match "^\\*" fragment-0
))
696 (not (string-match "^/.*/$" fragment-0
)))
698 (org-solidify-link-text
699 (org-link-unescape fragment-0
))
702 (if (string-match "^file:" desc
)
704 ((desc-1 (replace-match "" t t desc
)))
705 (if (string-match "\\.org$" desc-1
)
706 (replace-match "" t t desc-1
)
713 (functionp link-validate
)
714 (not (funcall link-validate path-1 current-dir
)))
717 "file" path-1 fragment-1 desc-2 descp
721 ;; just publish the path, as default
722 (setq rpl
(concat "<i><" type
":"
723 (save-match-data (org-link-unescape path
))
725 (setq line
(replace-match rpl t t line
)
726 start
(+ start
(length rpl
))))
729 (if (and (string-match org-todo-line-regexp line
)
733 (concat (substring line
0 (match-beginning 2))
735 (if (member (match-string 2 line
)
738 " " (match-string 2 line
)
739 "\"> " (org-export-html-get-todo-kwd-class-name
740 (match-string 2 line
))
741 "</span>" (substring line
(match-end 2)))))
743 ;; Does this contain a reference to a footnote?
744 (when org-export-with-footnotes
746 (while (string-match "\\([^* \t].*?\\)\\[\\([0-9]+\\)\\]" line start
)
747 (if (get-text-property (match-beginning 2) 'org-protected line
)
748 (setq start
(match-end 2))
749 (let ((n (match-string 2 line
)) extra a
)
750 (if (setq a
(assoc n footref-seen
))
752 (setcdr a
(1+ (cdr a
)))
753 (setq extra
(format ".%d" (cdr a
))))
755 (push (cons n
1) footref-seen
))
760 (format org-export-html-footnote-format
761 "<a class=\"footref\" name=\"fnr.%s%s\" href=\"#fn.%s\">%s</a>"))
762 (or (match-string 1 line
) "") n extra n n
)
766 ((string-match "^\\(\\*+\\)[ \t]+\\(.*\\)" line
)
767 ;; This is a headline
768 (setq level
(org-tr-level (- (match-end 1) (match-beginning 1)
770 txt
(match-string 2 line
))
771 (if (string-match quote-re0 txt
)
772 (setq txt
(replace-match "" t t txt
)))
773 (if (<= level
(max umax umax-toc
))
774 (setq head-count
(+ head-count
1)))
776 ;; Close any local lists before inserting a new header line
777 (while local-list-type
778 (org-close-li (car local-list-type
))
779 (insert (format "</%sl>\n" (car local-list-type
)))
780 (pop local-list-type
))
781 (setq local-list-indent nil
783 (setq first-heading-pos
(or first-heading-pos
(point)))
784 (org-html-level-start level txt umax
785 (and org-export-with-toc
(<= level umax
))
789 (when (string-match quote-re line
)
790 (org-close-par-maybe)
794 ((string-match "^[ \t]*- __+[ \t]*$" line
)
795 ;; Explicit list closure
796 (when local-list-type
797 (let ((ind (org-get-indentation line
)))
798 (while (and local-list-indent
799 (<= ind
(car local-list-indent
)))
800 (org-close-li (car local-list-type
))
801 (insert (format "</%sl>\n" (car local-list-type
)))
802 (pop local-list-type
)
803 (pop local-list-indent
))
804 (or local-list-indent
(setq in-local-list nil
))))
805 (throw 'nextline nil
))
807 ((and org-export-with-tables
808 (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line
))
809 (when (not table-open
)
811 (setq table-open t table-buffer nil table-orig-buffer nil
))
814 (setq table-buffer
(cons line table-buffer
)
815 table-orig-buffer
(cons origline table-orig-buffer
))
816 (when (or (not lines
)
817 (not (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)"
820 table-buffer
(nreverse table-buffer
)
821 table-orig-buffer
(nreverse table-orig-buffer
))
822 (org-close-par-maybe)
823 (insert (org-format-table-html table-buffer table-orig-buffer
))))
828 ((eq llt t
) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+[.)]\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
829 ((= llt ?.
) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+\\.\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
830 ((= llt ?\
)) "^\\([ \t]*\\)\\(\\([-+*] \\)\\|\\([0-9]+)\\) \\)?\\( *[^ \t\n\r]\\|[ \t]*$\\)")
831 (t (error "Invalid value of `org-plain-list-ordered-item-terminator'")))
833 (setq ind
(or (get-text-property 0 'original-indentation line
)
834 (org-get-string-indentation line
))
835 item-type
(if (match-beginning 4) "o" "u")
836 starter
(if (match-beginning 2)
837 (substring (match-string 2 line
) 0 -
1))
838 line
(substring line
(match-beginning 5))
840 (if (and starter
(string-match "\\(.*?\\) ::[ \t]*" line
))
842 item-tag
(match-string 1 line
)
843 line
(substring line
(match-end 0))))
844 (when (and (not (equal item-type
"d"))
845 (not (string-match "[^ \t]" line
)))
846 ;; empty line. Pretend indentation is large.
847 (setq ind
(if org-empty-line-terminates-plain-lists
849 (1+ (or (car local-list-indent
) 1)))))
851 (while (and in-local-list
852 (or (and (= ind
(car local-list-indent
))
854 (< ind
(car local-list-indent
))))
856 (org-close-li (car local-list-type
))
857 (insert (format "</%sl>\n" (car local-list-type
)))
858 (pop local-list-type
) (pop local-list-indent
)
859 (setq in-local-list local-list-indent
))
862 (or (not in-local-list
)
863 (> ind
(car local-list-indent
))))
864 ;; Start new (level of) list
865 (org-close-par-maybe)
867 ((equal item-type
"u") "<ul>\n<li>\n")
868 ((equal item-type
"o") "<ol>\n<li>\n")
869 ((equal item-type
"d")
870 (format "<dl>\n<dt>%s</dt><dd>\n" item-tag
))))
871 (push item-type local-list-type
)
872 (push ind local-list-indent
)
873 (setq in-local-list t
))
875 ;; continue current list
876 (org-close-li (car local-list-type
))
878 ((equal (car local-list-type
) "d")
879 (format "<dt>%s</dt><dd>\n" (or item-tag
"???")))
882 ;; we did close a list, normal text follows: need <p>
884 (if (string-match "^[ \t]*\\[\\([X ]\\)\\]" line
)
887 (if (equal (match-string 1 line
) "X")
889 "<b>[<span style=\"visibility:hidden;\">X</span>]</b>")
893 (when (string-match "^[ \t]*-\\{5,\\}[ \t]*$" line
)
895 (insert "\n</p>\n<hr/>\n<p>\n")
896 (insert "\n<hr/>\n"))
897 (throw 'nextline nil
))
899 ;; Empty lines start a new paragraph. If hand-formatted lists
900 ;; are not fully interpreted, lines starting with "-", "+", "*"
901 ;; also start a new paragraph.
902 (if (string-match "^ [-+*]-\\|^[ \t]*$" line
) (org-open-par))
904 ;; Is this the start of a footnote?
905 (when org-export-with-footnotes
906 (when (and (boundp 'footnote-section-tag-regexp
)
907 (string-match (concat "^" footnote-section-tag-regexp
)
910 (throw 'nextline nil
))
911 (when (string-match "^[ \t]*\\[\\([0-9]+\\)\\]" line
)
912 (org-close-par-maybe)
913 (let ((n (match-string 1 line
)))
917 (concat "<p class=\"footnote\">"
918 (format org-export-html-footnote-format
919 "<a class=\"footnum\" name=\"fn.%s\" href=\"#fnr.%s\">%s</a>"))
921 ;; Check if the line break needs to be conserved
923 ((string-match "\\\\\\\\[ \t]*$" line
)
924 (setq line
(replace-match "<br/>" t t line
)))
925 (org-export-preserve-breaks
926 (setq line
(concat line
"<br/>"))))
928 ;; Check if a paragraph should be started
930 (while (and org-par-open
931 (string-match "\\\\par\\>" line start
))
932 ;; Leave a space in the </p> so that the footnote matcher
933 ;; does not see this.
934 (if (not (get-text-property (match-beginning 0)
935 'org-protected line
))
936 (setq line
(replace-match "</p ><p >" t t line
)))
937 (setq start
(match-end 0))))
939 (insert line
"\n")))))
941 ;; Properly close all local lists and other lists
946 ;; Close any local lists before inserting a new header line
947 (while local-list-type
948 (org-close-li (car local-list-type
))
949 (insert (format "</%sl>\n" (car local-list-type
)))
950 (pop local-list-type
))
951 (setq local-list-indent nil
953 (org-html-level-start 1 nil umax
954 (and org-export-with-toc
(<= level umax
))
956 ;; the </div> to close the last text-... div.
957 (when (and (> umax
0) first-heading-pos
) (insert "</div>\n"))
960 (goto-char (point-min))
961 (while (re-search-forward "<p class=\"footnote\">[^\000]*?\\(</p>\\|\\'\\)" nil t
)
962 (push (match-string 0) footnotes
)
963 (replace-match "" t t
)))
965 (insert (format org-export-html-footnotes-section
967 (mapconcat 'identity
(nreverse footnotes
) "\n"))
969 (let ((bib (org-export-html-get-bibliography)))
971 (insert "\n" bib
"\n")))
973 (when (plist-get opt-plist
:auto-postamble
)
974 (insert "<div id=\"postamble\">\n")
975 (when (and org-export-author-info author
)
976 (insert "<p class=\"author\"> "
977 (nth 1 lang-words
) ": " author
"\n")
978 (when (and org-export-email-info email
(string-match "\\S-" email
))
979 (if (listp (split-string email
",+ *"))
981 (insert "<a href=\"mailto:" e
"\"><"
983 (split-string email
",+ *"))
984 (insert "<a href=\"mailto:" email
"\"><"
985 email
"></a>\n")))
987 (when (and date org-export-time-stamp-file
)
988 (insert "<p class=\"date\"> "
989 (nth 2 lang-words
) ": "
991 (when org-export-creator-info
992 (insert (format "<p class=\"creator\">HTML generated by org-mode %s in emacs %s</p>\n"
993 org-version emacs-major-version
)))
994 (when org-export-html-validation-link
995 (insert org-export-html-validation-link
"\n"))
998 (if org-export-html-with-timestamp
999 (insert org-export-html-html-helper-timestamp
))
1000 (org-export-html-insert-plist-item opt-plist
:postamble opt-plist
)
1001 (insert "\n</div>\n</body>\n</html>\n"))
1003 (unless (plist-get opt-plist
:buffer-will-be-killed
)
1005 (if (eq major-mode
(default-value 'major-mode
))
1008 ;; insert the table of contents
1009 (goto-char (point-min))
1011 (if (or (re-search-forward
1012 "<p>\\s-*\\[TABLE-OF-CONTENTS\\]\\s-*</p>" nil t
)
1014 "\\[TABLE-OF-CONTENTS\\]" nil t
))
1016 (goto-char (match-beginning 0))
1018 (goto-char first-heading-pos
)
1019 (when (looking-at "\\s-*</p>")
1020 (goto-char (match-end 0))
1022 (insert "<div id=\"table-of-contents\">\n")
1023 (mapc 'insert thetoc
)
1024 (insert "</div>\n"))
1025 ;; remove empty paragraphs and lists
1026 (goto-char (point-min))
1027 (while (re-search-forward "<p>[ \r\n\t]*</p>" nil t
)
1029 (goto-char (point-min))
1030 (while (re-search-forward "<li>[ \r\n\t]*</li>\n?" nil t
)
1032 (goto-char (point-min))
1033 (while (re-search-forward "</ul>\\s-*<ul>\n?" nil t
)
1035 ;; Convert whitespace place holders
1036 (goto-char (point-min))
1038 (while (setq beg
(next-single-property-change (point) 'org-whitespace
))
1039 (setq n
(get-text-property beg
'org-whitespace
)
1040 end
(next-single-property-change beg
'org-whitespace
))
1042 (delete-region beg end
)
1043 (insert (format "<span style=\"visibility:hidden;\">%s</span>"
1044 (make-string n ?x
)))))
1045 ;; Remove empty lines at the beginning of the file.
1046 (goto-char (point-min))
1047 (when (looking-at "\\s-+\n") (replace-match ""))
1048 ;; Remove display properties
1049 (remove-text-properties (point-min) (point-max) '(display t
))
1051 (run-hooks 'org-export-html-final-hook
)
1052 (or to-buffer
(save-buffer))
1053 (goto-char (point-min))
1054 (or (org-export-push-to-kill-ring "HTML")
1055 (message "Exporting... done"))
1056 (if (eq to-buffer
'string
)
1057 (prog1 (buffer-substring (point-min) (point-max))
1058 (kill-buffer (current-buffer)))
1059 (current-buffer)))))
1064 (provide 'org2blog
/for-org-html
)
1066 ;;;_ * Local emacs vars.
1067 ;;;_ + Local variables:
1072 ;;; org2blog/for-org-html.el ends here