org-export-generic.el 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387
  1. ;; org-export-generic.el --- Export frameworg with custom backends
  2. ;; Copyright (C) 2009 Free Software Foundation, Inc.
  3. ;; Author: Wes Hardaker <hardaker at users dot sourceforge dot net>
  4. ;; Keywords: outlines, hypermedia, calendar, wp, export
  5. ;; Homepage: http://orgmode.org
  6. ;; Version: 6.25trans
  7. ;; Acks: Much of this code was stolen form the ascii export from Carsten
  8. ;;
  9. ;; This file is not yet part of GNU Emacs.
  10. ;;
  11. ;; GNU Emacs is free software: you can redistribute it and/or modify
  12. ;; it under the terms of the GNU General Public License as published by
  13. ;; the Free Software Foundation, either version 3 of the License, or
  14. ;; (at your option) any later version.
  15. ;; GNU Emacs is distributed in the hope that it will be useful,
  16. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;; GNU General Public License for more details.
  19. ;; You should have received a copy of the GNU General Public License
  20. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  21. ;;
  22. ;; ----------------------------------------------------------------------
  23. ;;
  24. ;; OVERVIEW
  25. ;;
  26. ;; org-export-generic is basically a simple translation system that
  27. ;; knows how to parse at least most of a .org buffer and then add
  28. ;; various formatting prefixes before and after each section type. It
  29. ;; does this by examining a property list stored in org-generic-alist.
  30. ;; You can dynamically add propety lists of your own using the
  31. ;; org-set-generic-type function:
  32. ;;
  33. ;; (org-set-generic-type
  34. ;; "really-basic-text"
  35. ;; '(:file-suffix ".txt"
  36. ;; :key-binding ?R
  37. ;;
  38. ;; :title-format "=== %s ===\n"
  39. ;; :body-header-section-numbers t
  40. ;; :body-header-section-number-format "%s) "
  41. ;; :body-section-header-prefix "\n"
  42. ;; :body-section-header-suffix "\n"
  43. ;; :body-line-format " %s\n"
  44. ;; :body-line-wrap 75
  45. ;; ))
  46. ;;
  47. ;; Note: Upper case key-bindings are reserved for your use. Lower
  48. ;; case key bindings may conflict with future export-generic
  49. ;; publications.
  50. ;;
  51. ;; Then run org-export (ctrl-c ctrl-e) and select generic or run
  52. ;; org-export-generic. You'll then be prompted with a list of export
  53. ;; types to choose from which will include your new type assigned to
  54. ;; the key "r".
  55. ;;
  56. ;; ----------------------------------------------------------------------
  57. ;;
  58. ;; TODO (non-ordered)
  59. ;; * handle function references
  60. ;; * handle other types of multi-complex-listy-things to do
  61. ;; ideas: (t ?- "%s" ?-)
  62. ;; * handle indent specifiers better
  63. ;; ideas: (4 ?\ "%s")
  64. ;; * need flag to remove indents from body text
  65. ;; * handle links
  66. ;; * handle internationalization strings better
  67. ;; * date/author/etc needs improvment (internationalization too)
  68. ;; * allow specifying of section ordering
  69. ;; ideas: :ordering ("header" "toc" "body" "footer")
  70. ;; ^ matches current hard coded ordering
  71. ;; * err, actually *do* a footer
  72. ;; * deal with usage of org globals
  73. ;; *** should we even consider them, or let the per-section specifiers do it
  74. ;; *** answer: remove; mostly removed now
  75. ;; * deal with interactive support for picking a export specifier label
  76. ;; * char specifiers that need extra length because of formatting
  77. ;; idea: (?- 4) for 4-longer
  78. ;; * centering specifier
  79. ;; idea: ('center " -- %s -- ")
  80. ;; * remove more of the unneeded export-to-ascii copy code
  81. ;; * tags
  82. ;; *** supported now, but need separate format per tag
  83. ;; *** allow different open/closing prefixes
  84. ;; * properties
  85. ;; * drawers
  86. ;; * oh my
  87. ;; * optmization (many plist extracts should be in let vars)
  88. ;; * define defcustom spec for the specifier list
  89. ;; * fonts: at least monospace is not handled at all here.
  90. ;;
  91. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  92. ;;
  93. ;;; Commentary:
  94. (require 'org-exp)
  95. (require 'assoc)
  96. (defgroup org-export-generic nil
  97. "Options specific for ASCII export of Org-mode files."
  98. :tag "Org Export ASCII"
  99. :group 'org-export)
  100. (defcustom org-export-generic-links-to-notes t
  101. "Non-nil means convert links to notes before the next headline.
  102. When nil, the link will be exported in place. If the line becomes long
  103. in this way, it will be wrapped."
  104. :group 'org-export-generic
  105. :type 'boolean)
  106. (defvar org-generic-current-indentation nil) ; For communication
  107. (defvar org-generic-alist
  108. '(
  109. ;;
  110. ;; generic DEMO exporter
  111. ;;
  112. ;; (this tries to use every specifier for demo purposes)
  113. ;;
  114. ("demo"
  115. :file-suffix ".txt"
  116. :key-binding ?d
  117. :header-prefix "<header>\n"
  118. :header-suffix "</header>\n"
  119. :author-export t
  120. :tags-export t
  121. :drawers-export t
  122. :title-prefix ?=
  123. :title-format "<h1>%s</h1>\n"
  124. :title-suffix ?=
  125. :date-export t
  126. :date-prefix "<date>"
  127. :date-format "<br /><b>Date:</b> <i>%s</i><br />"
  128. :date-suffix "</date>\n\n"
  129. :toc-export t
  130. :toc-header-prefix "<tocname>\n"
  131. :toc-header-format "__%s__\n"
  132. :toc-header-suffix "</tocname>\n"
  133. :toc-prefix "<toc>\n"
  134. :toc-suffix "</toc>\n"
  135. :toc-section-numbers t
  136. :toc-section-number-format "\#(%s) "
  137. :toc-format "--%s--"
  138. :toc-format-with-todo "!!%s!!\n"
  139. :toc-indent-char ?\
  140. :toc-indent-depth 4
  141. :toc-tags-export t
  142. :toc-tags-prefix " <tags>"
  143. :toc-tags-format "*%s*"
  144. :toc-tags-suffix "</tags>\n"
  145. :toc-tags-none-string "\n"
  146. :body-header-section-numbers 3 ; t = all, nil = none
  147. ; lists indicate different things per level
  148. ; list contents or straight value can either be a
  149. ; ?x char reference for printing strings that match the header len
  150. ; "" string to print directly
  151. :body-section-header-prefix ("<h1>" "<h2>" "<h3>"
  152. "<h4>" "<h5>" "<h6>")
  153. :body-section-header-format "%s"
  154. :body-section-header-suffix ("</h1>\n" "</h2>\n" "</h3>\n"
  155. "</h4>\n" "</h5>\n" "</h6>\n")
  156. :timestamps-export t
  157. :priorities-export t
  158. :todo-keywords-export t
  159. :body-tags-export t
  160. :body-tags-prefix " <tags>"
  161. :body-tags-suffix "</tags>\n"
  162. ; section prefixes/suffixes can be direct strings or lists as well
  163. :body-section-prefix "<secprefix>\n"
  164. :body-section-suffix "</secsuffix>\n"
  165. ; :body-section-prefix ("<sec1>\n" "<sec2>\n" "<sec3>\n")
  166. ; :body-section-suffix ("</sec1>\n" "</sec2>\n" "</sec3>\n")
  167. ; if preformated text should be included (eg, : prefixed)
  168. :body-line-export-preformated t
  169. :body-line-fixed-prefix "<pre>\n"
  170. :body-line-fixed-suffix "\n</pre>\n"
  171. :body-line-fixed-format "%s\n"
  172. :body-list-prefix "<list>\n"
  173. :body-list-suffix "</list>\n"
  174. :body-list-format "<li>%s</li>\n"
  175. :body-number-list-prefix "<ol>\n"
  176. :body-number-list-suffix "</ol>\n"
  177. :body-number-list-format "<li>%s</li>\n"
  178. :body-number-list-leave-number t
  179. :body-list-checkbox-todo "<checkbox type=\"todo\">"
  180. :body-list-checkbox-todo-end "</checkbox (todo)>"
  181. :body-list-checkbox-done "<checkbox type=\"done\">"
  182. :body-list-checkbox-done-end "</checkbox (done)>"
  183. :body-list-checkbox-half "<checkbox type=\"half\">"
  184. :body-list-checkbox-half-end "</checkbox (half)>"
  185. ; other body lines
  186. :body-line-format "%s"
  187. :body-line-wrap 60 ; wrap at 60 chars
  188. ; print above and below all body parts
  189. :body-text-prefix "<p>\n"
  190. :body-text-suffix "</p>\n"
  191. )
  192. ;;
  193. ;; ascii exporter
  194. ;;
  195. ;; (close to the original ascii specifier)
  196. ;;
  197. ("ascii"
  198. :file-suffix ".txt"
  199. :key-binding ?a
  200. :header-prefix ""
  201. :header-suffix ""
  202. :title-prefix ?=
  203. :title-format "%s\n"
  204. :title-suffix ?=
  205. :date-export t
  206. :date-prefix ""
  207. :date-format "Date: %s\n"
  208. :date-suffix ""
  209. :toc-header-prefix ""
  210. :toc-header-format "%s\n"
  211. :toc-header-suffix ?=
  212. :toc-export t
  213. :toc-section-numbers t
  214. :toc-section-number-format "%s "
  215. :toc-format "%s\n"
  216. :toc-format-with-todo "%s (*)\n"
  217. :toc-indent-char ?\
  218. :toc-indent-depth 4
  219. :body-header-section-numbers 3
  220. :body-section-prefix "\n"
  221. ; :body-section-header-prefix "\n"
  222. ; :body-section-header-format "%s\n"
  223. ; :body-section-header-suffix (?\$ ?\# ?^ ?\~ ?\= ?\-)
  224. :body-section-header-prefix ("" "" "" "* " " + " " - ")
  225. :body-section-header-format "%s\n"
  226. :body-section-header-suffix (?~ ?= ?- "\n" "\n" "\n")
  227. ; :body-section-marker-prefix ""
  228. ; :body-section-marker-chars (?\$ ?\# ?^ ?\~ ?\= ?\-)
  229. ; :body-section-marker-suffix "\n"
  230. :body-line-export-preformated t
  231. :body-line-format "%s\n"
  232. :body-line-wrap 75
  233. ; :body-text-prefix "<t>\n"
  234. ; :body-text-suffix "</t>\n"
  235. :body-bullet-list-prefix (?* ?+ ?-)
  236. ; :body-bullet-list-suffix (?* ?+ ?-)
  237. )
  238. ;;
  239. ;; wikipedia
  240. ;;
  241. ("wikipedia"
  242. :file-suffix ".txt"
  243. :key-binding ?w
  244. :header-prefix ""
  245. :header-suffix ""
  246. :title-format "= %s =\n"
  247. :date-export nil
  248. :toc-export nil
  249. :body-header-section-numbers nil
  250. :body-section-prefix "\n"
  251. :body-section-header-prefix ("= " "== " "=== "
  252. "==== " "===== " "====== ")
  253. :body-section-header-suffix (" =\n\n" " ==\n\n" " ===\n\n"
  254. " ====\n\n" " =====\n\n" " ======\n\n")
  255. :body-line-export-preformated t ;; yes/no/maybe???
  256. :body-line-format "%s\n"
  257. :body-line-wrap 75
  258. :body-line-fixed-format " %s\n"
  259. :body-list-format "* %s\n"
  260. :body-number-list-format "# %s\n"
  261. :body-bullet-list-prefix ("* " "** " "*** " "**** " "***** ")
  262. )
  263. ;;
  264. ;; minimal html exporter
  265. ;;
  266. ("html"
  267. ;; simple html output
  268. :file-suffix ".html"
  269. :key-binding ?h
  270. :header-prefix "<body>"
  271. :title-format "<h1>%s</h1>\n\n"
  272. :date-export t
  273. :date-format "<br /><b>Date:</b> <i>%s</i><br />\n\n"
  274. :toc-export nil
  275. :body-header-section-numbers 3
  276. :body-section-header-prefix ("<h1>" "<h2>" "<h3>"
  277. "<h4>" "<h5>" "<h6>")
  278. :body-section-header-format "%s"
  279. :body-section-header-suffix ("</h1>\n" "</h2>\n" "</h3>\n"
  280. "</h4>\n" "</h5>\n" "</h6>\n")
  281. :body-section-prefix "<secprefix>\n"
  282. :body-section-suffix "</secsuffix>\n"
  283. ; :body-section-prefix ("<sec1>\n" "<sec2>\n" "<sec3>\n")
  284. ; :body-section-suffix ("</sec1>\n" "</sec2>\n" "</sec3>\n")
  285. :body-line-export-preformated t
  286. :body-line-format "%s\n"
  287. :body-text-prefix "<p>\n"
  288. :body-text-suffix "</p>\n"
  289. :body-bullet-list-prefix (?* ?+ ?-)
  290. ; :body-bullet-list-suffix (?* ?+ ?-)
  291. )
  292. ;;
  293. ;; internet-draft .xml for xml2rfc exporter
  294. ;;
  295. ("ietfid"
  296. ;; this tries to use every specifier for demo purposes
  297. :file-suffix ".xml"
  298. :key-binding ?i
  299. :title-prefix "<?xml version=\"1.0\"\?>
  300. <!DOCTYPE rfc SYSTEM \"rfc2629.dtd\" [
  301. <!ENTITY rfcs PUBLIC '' 'blah'>
  302. <?rfc strict=\"yes\" ?>
  303. <?rfc toc=\"yes\" ?>
  304. <?rfc tocdepth=\"4\" ?>
  305. <?rfc symrefs=\"yes\" ?>
  306. <?rfc compact=\"yes\" ?>
  307. <?rfc subcompact=\"no\" ?>
  308. <rfc category=\"std\" ipr=\"pre5378Trust200902\" docName=\"FILLME.txt\">
  309. <front>
  310. "
  311. :title-format "<title abbrev=\"ABBREV HERE\">\n%s\n</title>\n"
  312. :title-suffix "<author initials=\"A.A\" surname=\"LASTNAME\" fullname=\"FULL NAME\">
  313. <organization>Comany, Inc..</organization>
  314. <address>
  315. <postal>
  316. <street></street>
  317. <city></city>
  318. <region></region>
  319. <code></code>
  320. <country></country>
  321. </postal>
  322. <phone></phone>
  323. <email></email>
  324. </address>
  325. </author>
  326. <date month=\"FILLMONTH\" year=\"FILLYEAR\"/>
  327. <area>Operations and Management</area>
  328. <workgroup>FIXME</workgroup>
  329. <abstract>\n"
  330. :date-export nil
  331. :toc-export nil
  332. :body-header-section-numbers nil
  333. :body-section-header-format "<section title=\"%s\">\n"
  334. :body-section-suffix "</section>\n"
  335. ; if preformated text should be included (eg, : prefixed)
  336. :body-line-export-preformated t
  337. :body-line-fixed-prefix "<figure>\n<artwork>\n"
  338. :body-line-fixed-suffix "\n</artwork>\n</figure>\n"
  339. ; other body lines
  340. :body-line-format "%s"
  341. :body-line-wrap 75
  342. ; print above and below all body parts
  343. :body-text-prefix "<t>\n"
  344. :body-text-suffix "</t>\n"
  345. :body-list-prefix "<list style=\"symbols\">\n"
  346. :body-list-suffix "</list>\n"
  347. :body-list-format "<t>%s</t>\n"
  348. )
  349. )
  350. "A assoc list of property lists to specify export definitions"
  351. )
  352. (setq org-generic-export-type "demo")
  353. (defvar org-export-generic-section-type "")
  354. (defvar org-export-generic-section-suffix "")
  355. ;;;###autoload
  356. (defun org-set-generic-type (type definition)
  357. "Adds a TYPE and DEFINITION to the existing list of defined generic
  358. export definitions."
  359. (aput 'org-generic-alist type definition))
  360. ;;; helper functions for org-set-generic-type
  361. (defvar org-export-generic-keywords nil)
  362. (defmacro* def-org-export-generic-keyword (keyword
  363. &key documentation
  364. type)
  365. "Define KEYWORD as a legitimate element for inclusion in
  366. the body of an org-set-generic-type definition."
  367. `(progn
  368. (pushnew ,keyword org-export-generic-keywords)
  369. ;; TODO: push the documentation and type information
  370. ;; somewhere where it will do us some good.
  371. ))
  372. (def-org-export-generic-keyword :body-newline-paragraph
  373. :documentation "Bound either to NIL or to a pattern to be
  374. inserted in the output for every blank line in the input.
  375. The intention is to handle formats where text is flowed, and
  376. newlines are interpreted as significant \(e.g., as indicating
  377. preformatted text\). A common non-nil value for this keyword
  378. is \"\\n\". Should typically be combined with a value for
  379. :body-line-format that does NOT end with a newline."
  380. :type string)
  381. ;;; fontification keywords
  382. (def-org-export-generic-keyword :bold-format)
  383. (def-org-export-generic-keyword :italic-format)
  384. (def-org-export-generic-keyword :underline-format)
  385. (def-org-export-generic-keyword :strikethrough-format)
  386. (def-org-export-generic-keyword :code-format)
  387. (def-org-export-generic-keyword :verbatim-format)
  388. (defun org-export-generic-remember-section (type suffix &optional prefix)
  389. (setq org-export-generic-section-type type)
  390. (setq org-export-generic-section-suffix suffix)
  391. (if prefix
  392. (insert prefix))
  393. )
  394. (defun org-export-generic-check-section (type &optional prefix suffix)
  395. "checks to see if type is already in use, or we're switching parts
  396. If we're switching, then insert a potentially previously remembered
  397. suffix, and insert the current prefix immediately and then save the
  398. suffix a later change time."
  399. (when (not (equal type org-export-generic-section-type))
  400. (if org-export-generic-section-suffix
  401. (insert org-export-generic-section-suffix))
  402. (setq org-export-generic-section-type type)
  403. (setq org-export-generic-section-suffix suffix)
  404. (if prefix
  405. (insert prefix))))
  406. ;;;###autoload
  407. (defun org-export-generic (arg)
  408. "Export the outline as generic output.
  409. If there is an active region, export only the region.
  410. The prefix ARG specifies how many levels of the outline should become
  411. underlined headlines. The default is 3."
  412. (interactive "P")
  413. (setq-default org-todo-line-regexp org-todo-line-regexp)
  414. (let* ((opt-plist (org-combine-plists (org-default-export-plist)
  415. (org-infile-export-plist)))
  416. (region-p (org-region-active-p))
  417. (rbeg (and region-p (region-beginning)))
  418. (rend (and region-p (region-end)))
  419. (subtree-p
  420. (when region-p
  421. (save-excursion
  422. (goto-char rbeg)
  423. (and (org-at-heading-p)
  424. (>= (org-end-of-subtree t t) rend)))))
  425. (level-offset (if subtree-p
  426. (save-excursion
  427. (goto-char rbeg)
  428. (+ (funcall outline-level)
  429. (if org-odd-levels-only 1 0)))
  430. 0))
  431. (opt-plist (setq org-export-opt-plist
  432. (if subtree-p
  433. (org-export-add-subtree-options opt-plist rbeg)
  434. opt-plist)))
  435. helpstart
  436. (bogus (mapc (lambda (x)
  437. (setq helpstart
  438. (concat helpstart "\["
  439. (char-to-string
  440. (plist-get (cdr x) :key-binding))
  441. "] " (car x) "\n")))
  442. org-generic-alist))
  443. (help (concat helpstart "
  444. \[ ] the current setting of the org-generic-export-type variable
  445. "))
  446. (cmds
  447. (append
  448. (mapcar (lambda (x)
  449. (list
  450. (plist-get (cdr x) :key-binding)
  451. (car x)))
  452. org-generic-alist)
  453. (list (list ? "default"))))
  454. r1 r2 ass
  455. ;; read in the type to use
  456. (export-plist
  457. (progn
  458. (save-excursion
  459. (save-window-excursion
  460. (delete-other-windows)
  461. (with-output-to-temp-buffer "*Org Export/Generic Styles Help*"
  462. (princ help))
  463. (org-fit-window-to-buffer (get-buffer-window
  464. "*Org Export/Generic Styles Help*"))
  465. (message "Select command: ")
  466. (setq r1 (read-char-exclusive))))
  467. (setq r2 (if (< r1 27) (+ r1 96) r1))
  468. (unless (setq ass (cadr (assq r2 cmds)))
  469. (error "No command associated with key %c" r1))
  470. (cdr (assoc
  471. (if (equal ass "default") org-generic-export-type ass)
  472. org-generic-alist))))
  473. (custom-times org-display-custom-times)
  474. (org-generic-current-indentation '(0 . 0))
  475. (level 0) (old-level 0) line txt lastwastext
  476. (umax nil)
  477. (umax-toc nil)
  478. (case-fold-search nil)
  479. (bfname (buffer-file-name (or (buffer-base-buffer) (current-buffer))))
  480. (filesuffix (or (plist-get export-plist :file-suffix) ".foo"))
  481. (filename (concat (file-name-as-directory
  482. (org-export-directory :ascii opt-plist))
  483. (file-name-sans-extension
  484. (or (and subtree-p
  485. (org-entry-get (region-beginning)
  486. "EXPORT_FILE_NAME" t))
  487. (file-name-nondirectory bfname)))
  488. filesuffix))
  489. (filename (if (equal (file-truename filename)
  490. (file-truename bfname))
  491. (concat filename filesuffix)
  492. filename))
  493. (buffer (find-file-noselect filename))
  494. (org-levels-open (make-vector org-level-max nil))
  495. (odd org-odd-levels-only)
  496. (date (plist-get opt-plist :date))
  497. (author (plist-get opt-plist :author))
  498. (title (or (and subtree-p (org-export-get-title-from-subtree))
  499. (plist-get opt-plist :title)
  500. (and (not
  501. (plist-get opt-plist :skip-before-1st-heading))
  502. (org-export-grab-title-from-buffer))
  503. (file-name-sans-extension
  504. (file-name-nondirectory bfname))))
  505. (email (plist-get opt-plist :email))
  506. (language (plist-get opt-plist :language))
  507. (quote-re0 (concat "^[ \t]*" org-quote-string "\\>"))
  508. ; (quote-re (concat "^\\(\\*+\\)\\([ \t]*" org-quote-string "\\>\\)"))
  509. (todo nil)
  510. (lang-words nil)
  511. (region
  512. (buffer-substring
  513. (if (org-region-active-p) (region-beginning) (point-min))
  514. (if (org-region-active-p) (region-end) (point-max))))
  515. (lines (org-split-string
  516. (org-export-preprocess-string
  517. region
  518. :for-ascii t
  519. :skip-before-1st-heading
  520. (plist-get opt-plist :skip-before-1st-heading)
  521. :drawers (plist-get export-plist :drawers-export)
  522. :tags (plist-get export-plist :tags-export)
  523. :priority (plist-get export-plist :priority-export)
  524. :footnotes (plist-get export-plist :footnotes-export)
  525. :timestamps (plist-get export-plist :timestamps-export)
  526. :todo-keywords (plist-get export-plist :todo-keywords-export)
  527. :verbatim-multiline t
  528. :select-tags (plist-get export-plist :select-tags-export)
  529. :exclude-tags (plist-get export-plist :exclude-tags-export)
  530. :emph-multiline t
  531. :archived-trees
  532. (plist-get export-plist :archived-trees-export)
  533. :add-text (plist-get opt-plist :text))
  534. "\n"))
  535. ;; export-generic plist variables
  536. (withtags (plist-get export-plist :tags-export))
  537. (tagsintoc (plist-get export-plist :toc-tags-export))
  538. (tocnotagsstr (or (plist-get export-plist :toc-tags-none-string) ""))
  539. (tocdepth (plist-get export-plist :toc-indent-depth))
  540. (tocindentchar (plist-get export-plist :toc-indent-char))
  541. (tocsecnums (plist-get export-plist :toc-section-numbers))
  542. (tocsecnumform (plist-get export-plist :toc-section-number-format))
  543. (tocformat (plist-get export-plist :toc-format))
  544. (tocformtodo (plist-get export-plist :toc-format-with-todo))
  545. (tocprefix (plist-get export-plist :toc-prefix))
  546. (tocsuffix (plist-get export-plist :toc-suffix))
  547. (bodyfixedpre (plist-get export-plist :body-line-fixed-prefix))
  548. (bodyfixedsuf (plist-get export-plist :body-line-fixed-suffix))
  549. (bodyfixedform (or (plist-get export-plist :body-line-fixed-format)
  550. "%s"))
  551. (listprefix (plist-get export-plist :body-list-prefix))
  552. (listsuffix (plist-get export-plist :body-list-suffix))
  553. (listformat (or (plist-get export-plist :body-list-format) "%s\n"))
  554. (numlistleavenum
  555. (plist-get export-plist :body-number-list-leave-number))
  556. (numlistprefix (plist-get export-plist :body-number-list-prefix))
  557. (numlistsuffix (plist-get export-plist :body-number-list-suffix))
  558. (numlistformat
  559. (or (plist-get export-plist :body-number-list-format) "%s\n"))
  560. (listchecktodo
  561. (or (plist-get export-plist :body-list-checkbox-todo) "\\1"))
  562. (listcheckdone
  563. (or (plist-get export-plist :body-list-checkbox-done) "\\1"))
  564. (listcheckhalf
  565. (or (plist-get export-plist :body-list-checkbox-half) "\\1"))
  566. (listchecktodoend
  567. (or (plist-get export-plist :body-list-checkbox-todo-end) ""))
  568. (listcheckdoneend
  569. (or (plist-get export-plist :body-list-checkbox-done-end) ""))
  570. (listcheckhalfend
  571. (or (plist-get export-plist :body-list-checkbox-half-end) ""))
  572. (bodynewline-paragraph (plist-get export-plist :body-newline-paragraph))
  573. (bodytextpre (plist-get export-plist :body-text-prefix))
  574. (bodytextsuf (plist-get export-plist :body-text-suffix))
  575. (bodylinewrap (plist-get export-plist :body-line-wrap))
  576. (bodylineform (or (plist-get export-plist :body-line-format) "%s"))
  577. (blockquotestart (or (plist-get export-plist :blockquote-start) "\n\n\t"))
  578. (blockquoteend (or (plist-get export-plist :blockquote-end) "\n\n"))
  579. ;; dynamic variables used heinously in fontification
  580. ;; not referenced locally...
  581. (format-boldify (plist-get export-plist :bold-format))
  582. (format-italicize (plist-get export-plist :italic-format))
  583. (format-underline (plist-get export-plist :underline-format))
  584. (format-strikethrough (plist-get export-plist :strikethrough-format))
  585. (format-code (plist-get export-plist :code-format))
  586. (format-verbatim (plist-get export-plist :verbatim-format))
  587. thetoc toctags have-headings first-heading-pos
  588. table-open table-buffer link-buffer link desc desc0 rpl wrap)
  589. (let ((inhibit-read-only t))
  590. (org-unmodified
  591. (remove-text-properties (point-min) (point-max)
  592. '(:org-license-to-kill t))))
  593. (setq org-min-level (org-get-min-level lines level-offset))
  594. (setq org-last-level org-min-level)
  595. (org-init-section-numbers)
  596. (find-file-noselect filename)
  597. (setq lang-words (or (assoc language org-export-language-setup)
  598. (assoc "en" org-export-language-setup)))
  599. (switch-to-buffer-other-window buffer)
  600. (erase-buffer)
  601. (fundamental-mode)
  602. ;; create local variables for all options, to make sure all called
  603. ;; functions get the correct information
  604. (mapc (lambda (x)
  605. (set (make-local-variable (nth 2 x))
  606. (plist-get opt-plist (car x))))
  607. org-export-plist-vars)
  608. (org-set-local 'org-odd-levels-only odd)
  609. (setq umax (if arg (prefix-numeric-value arg)
  610. org-export-headline-levels))
  611. (setq umax-toc umax)
  612. ;; File header
  613. (if title
  614. (insert
  615. (org-export-generic-header title export-plist
  616. :title-prefix
  617. :title-format
  618. :title-suffix)))
  619. (if (and (or author email)
  620. (plist-get export-plist :author-export))
  621. (insert (concat (nth 1 lang-words) ": " (or author "")
  622. (if email (concat " <" email ">") "")
  623. "\n")))
  624. (cond
  625. ((and date (string-match "%" date))
  626. (setq date (format-time-string date)))
  627. (date)
  628. (t (setq date (format-time-string "%Y-%m-%d %T %Z"))))
  629. (if (and date (plist-get export-plist :date-export))
  630. (insert
  631. (org-export-generic-header date export-plist
  632. :date-prefix
  633. :date-format
  634. :date-suffix)))
  635. ;; export the table of contents first
  636. (if (plist-get export-plist :toc-export)
  637. (progn
  638. (push
  639. (org-export-generic-header (nth 3 lang-words) export-plist
  640. :toc-header-prefix
  641. :toc-header-format
  642. :toc-header-suffix)
  643. thetoc)
  644. (if tocprefix
  645. (push tocprefix thetoc))
  646. (mapc '(lambda (line)
  647. (if (string-match org-todo-line-regexp line)
  648. ;; This is a headline
  649. (progn
  650. (setq have-headings t)
  651. (setq level (- (match-end 1) (match-beginning 1)
  652. level-offset)
  653. level (org-tr-level level)
  654. txt (match-string 3 line)
  655. todo
  656. (or (and org-export-mark-todo-in-toc
  657. (match-beginning 2)
  658. (not (member (match-string 2 line)
  659. org-done-keywords)))
  660. ; TODO, not DONE
  661. (and org-export-mark-todo-in-toc
  662. (= level umax-toc)
  663. (org-search-todo-below
  664. line lines level))))
  665. (setq txt (org-html-expand-for-generic txt))
  666. (while (string-match org-bracket-link-regexp txt)
  667. (setq txt
  668. (replace-match
  669. (match-string (if (match-end 2) 3 1) txt)
  670. t t txt)))
  671. (if (and (not tagsintoc)
  672. (string-match
  673. (org-re "[ \t]+:[[:alnum:]_@:]+:[ \t]*$")
  674. txt))
  675. (setq txt (replace-match "" t t txt))
  676. ; include tags but formated
  677. (if (string-match
  678. (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$")
  679. txt)
  680. (progn
  681. (setq
  682. toctags
  683. (org-export-generic-header
  684. (match-string 1 txt)
  685. export-plist :toc-tags-prefix
  686. :toc-tags-format :toc-tags-suffix))
  687. (string-match
  688. (org-re "[ \t]+:[[:alnum:]_@:]+:[ \t]*$")
  689. txt)
  690. (setq txt (replace-match "" t t txt)))
  691. (setq toctags tocnotagsstr)))
  692. (if (string-match quote-re0 txt)
  693. (setq txt (replace-match "" t t txt)))
  694. (if (<= level umax-toc)
  695. (progn
  696. (push
  697. (concat
  698. (make-string
  699. (* (max 0 (- level org-min-level)) tocdepth)
  700. tocindentchar)
  701. (if tocsecnums
  702. (format tocsecnumform
  703. (org-section-number level))
  704. "")
  705. (format
  706. (if todo tocformtodo tocformat)
  707. txt)
  708. toctags)
  709. thetoc)
  710. (setq org-last-level level))
  711. ))))
  712. lines)
  713. (if tocsuffix
  714. (push tocsuffix thetoc))
  715. (setq thetoc (if have-headings (nreverse thetoc) nil))))
  716. (org-init-section-numbers)
  717. (org-export-generic-check-section "top")
  718. (while (setq line (pop lines))
  719. (when (and link-buffer (string-match "^\\*+ " line))
  720. (org-export-generic-push-links (nreverse link-buffer))
  721. (setq link-buffer nil))
  722. (setq wrap nil)
  723. ;; Remove the quoted HTML tags.
  724. ;; XXX
  725. (setq line (org-html-expand-for-generic line))
  726. ;; Replace links with the description when possible
  727. ;; XXX
  728. (while (string-match org-bracket-link-regexp line)
  729. (setq link (match-string 1 line)
  730. desc0 (match-string 3 line)
  731. desc (or desc0 (match-string 1 line)))
  732. (if (and (> (length link) 8)
  733. (equal (substring link 0 8) "coderef:"))
  734. (setq line (replace-match
  735. (format (org-export-get-coderef-format (substring link 8) desc)
  736. (cdr (assoc
  737. (substring link 8)
  738. org-export-code-refs)))
  739. t t line))
  740. (setq rpl (concat "["
  741. (or (match-string 3 line) (match-string 1 line))
  742. "]"))
  743. (when (and desc0 (not (equal desc0 link)))
  744. (if org-export-generic-links-to-notes
  745. (push (cons desc0 link) link-buffer)
  746. (setq rpl (concat rpl " (" link ")")
  747. wrap (+ (length line) (- (length (match-string 0 line)))
  748. (length desc)))))
  749. (setq line (replace-match rpl t t line))))
  750. (when custom-times
  751. (setq line (org-translate-time line)))
  752. (cond
  753. ((string-match "^\\(\\*+\\)[ \t]+\\(.*\\)" line)
  754. ;;
  755. ;; a Headline
  756. ;;
  757. (org-export-generic-check-section "headline")
  758. (setq first-heading-pos (or first-heading-pos (point)))
  759. (setq level (org-tr-level (- (match-end 1) (match-beginning 1)
  760. level-offset))
  761. txt (match-string 2 line))
  762. (org-generic-level-start level old-level txt umax export-plist lines)
  763. (setq old-level level))
  764. ((and org-export-with-tables
  765. (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line))
  766. ;;
  767. ;; a Table
  768. ;;
  769. (org-export-generic-check-section "table")
  770. (if (not table-open)
  771. ;; New table starts
  772. (setq table-open t table-buffer nil))
  773. ;; Accumulate table lines
  774. (setq table-buffer (cons line table-buffer))
  775. (when (or (not lines)
  776. (not (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)"
  777. (car lines))))
  778. (setq table-open nil
  779. table-buffer (nreverse table-buffer))
  780. (insert (mapconcat
  781. (lambda (x)
  782. (org-fix-indentation x org-generic-current-indentation))
  783. (org-format-table-generic table-buffer)
  784. "\n") "\n")))
  785. ((string-match "^\\([ \t]*\\)\\(:\\( \\|$\\)\\)" line)
  786. ;;
  787. ;; pre-formatted text
  788. ;;
  789. (setq line (replace-match "\\1" nil nil line))
  790. (org-export-generic-check-section "preformat" bodyfixedpre bodyfixedsuf)
  791. (insert (format bodyfixedform line)))
  792. ((or (string-match "^\\([ \t]*\\)\\([\-\+][ \t]*\\)" line)
  793. ;; if the bullet list item is an asterisk, the leading space is /mandatory/
  794. ;; [2010/02/02:rpg]
  795. (string-match "^\\([ \t]+\\)\\(\\*[ \t]*\\)" line))
  796. ;;
  797. ;; plain list item
  798. ;;
  799. ;; TODO: nested lists
  800. ;;
  801. ;; I believe this gets rid of leading whitespace.
  802. (setq line (replace-match "" nil nil line))
  803. ;; won't this insert the suffix /before/ the last line of the list?
  804. ;; also isn't it spoofed by bulleted lists that have a line skip between the list items
  805. ;; unless 'org-empty-line-terminates-plain-lists' is true?
  806. (org-export-generic-check-section "liststart" listprefix listsuffix)
  807. ;; deal with checkboxes
  808. (cond
  809. ((string-match "^\\(\\[ \\]\\)[ \t]*" line)
  810. (setq line (concat (replace-match listchecktodo nil nil line)
  811. listchecktodoend)))
  812. ((string-match "^\\(\\[X\\]\\)[ \t]*" line)
  813. (setq line (concat (replace-match listcheckdone nil nil line)
  814. listcheckdoneend)))
  815. ((string-match "^\\(\\[/\\]\\)[ \t]*" line)
  816. (setq line (concat (replace-match listcheckhalf nil nil line)
  817. listcheckhalfend)))
  818. )
  819. (insert (format listformat (org-export-generic-fontify line))))
  820. ((string-match "^\\([ \t]+\\)\\([0-9]+\\.[ \t]*\\)" line)
  821. ;;
  822. ;; numbered list item
  823. ;;
  824. ;; TODO: nested lists
  825. ;;
  826. (setq line (replace-match (if numlistleavenum "\\2" "") nil nil line))
  827. (org-export-generic-check-section "numliststart"
  828. numlistprefix numlistsuffix)
  829. ;; deal with checkboxes
  830. ;; TODO: whoops; leaving the numbers is a problem for ^ matching
  831. (cond
  832. ((string-match "\\(\\[ \\]\\)[ \t]*" line)
  833. (setq line (concat (replace-match listchecktodo nil nil line)
  834. listchecktodoend)))
  835. ((string-match "\\(\\[X\\]\\)[ \t]*" line)
  836. (setq line (concat (replace-match listcheckdone nil nil line)
  837. listcheckdoneend)))
  838. ((string-match "\\(\\[/\\]\\)[ \t]*" line)
  839. (setq line (concat (replace-match listcheckhalf nil nil line)
  840. listcheckhalfend)))
  841. )
  842. (insert (format numlistformat (org-export-generic-fontify line))))
  843. ((equal line "ORG-BLOCKQUOTE-START")
  844. (setq line blockquotestart))
  845. ((equal line "ORG-BLOCKQUOTE-END")
  846. (setq line blockquoteend))
  847. ((string-match "^\\s-*$" line)
  848. ;; blank line
  849. (if bodynewline-paragraph
  850. (insert bodynewline-paragraph)))
  851. (t
  852. ;;
  853. ;; body
  854. ;;
  855. (org-export-generic-check-section "body" bodytextpre bodytextsuf)
  856. (setq line
  857. (org-export-generic-fontify line))
  858. ;; XXX: properties? list?
  859. (if (string-match "^\\([ \t]*\\)\\([-+*][ \t]+\\)\\(.*?\\)\\( ::\\)" line)
  860. (setq line (replace-match "\\1\\3:" t nil line)))
  861. (setq line (org-fix-indentation line org-generic-current-indentation))
  862. ;; Remove forced line breaks
  863. (if (string-match "\\\\\\\\[ \t]*$" line)
  864. (setq line (replace-match "" t t line)))
  865. (if bodylinewrap
  866. ;; XXX: was dependent on wrap var which was calculated by???
  867. (if (> (length line) bodylinewrap)
  868. (setq line
  869. (org-export-generic-wrap line bodylinewrap))
  870. (setq line line)))
  871. (insert (format bodylineform line)))))
  872. ;; if we're at a level > 0; insert the closing body level stuff
  873. (let ((counter 0))
  874. (while (> (- level counter) 0)
  875. (insert
  876. (org-export-generic-format export-plist :body-section-suffix 0
  877. (- level counter)))
  878. (setq counter (1+ counter))))
  879. (org-export-generic-check-section "bottom")
  880. (org-export-generic-push-links (nreverse link-buffer))
  881. (normal-mode)
  882. ;; insert the table of contents
  883. (when thetoc
  884. (goto-char (point-min))
  885. (if (re-search-forward "^[ \t]*\\[TABLE-OF-CONTENTS\\][ \t]*$" nil t)
  886. (progn
  887. (goto-char (match-beginning 0))
  888. (replace-match ""))
  889. (goto-char first-heading-pos))
  890. (mapc 'insert thetoc)
  891. (or (looking-at "[ \t]*\n[ \t]*\n")
  892. (insert "\n\n")))
  893. ;; Convert whitespace place holders
  894. (goto-char (point-min))
  895. (let (beg end)
  896. (while (setq beg (next-single-property-change (point) 'org-whitespace))
  897. (setq end (next-single-property-change beg 'org-whitespace))
  898. (goto-char beg)
  899. (delete-region beg end)
  900. (insert (make-string (- end beg) ?\ ))))
  901. (save-buffer)
  902. ;; remove display and invisible chars
  903. (let (beg end)
  904. (goto-char (point-min))
  905. (while (setq beg (next-single-property-change (point) 'display))
  906. (setq end (next-single-property-change beg 'display))
  907. (delete-region beg end)
  908. (goto-char beg)
  909. (insert "=>"))
  910. (goto-char (point-min))
  911. (while (setq beg (next-single-property-change (point) 'org-cwidth))
  912. (setq end (next-single-property-change beg 'org-cwidth))
  913. (delete-region beg end)
  914. (goto-char beg)))
  915. (goto-char (point-min))))
  916. (defun org-export-generic-format (export-plist prop &optional len n reverse)
  917. "converts a property specification to a string given types of properties
  918. The EXPORT-PLIST should be defined as the lookup plist.
  919. The PROP should be the property name to search for in it.
  920. LEN is set to the length of multi-characters strings to generate (or 0)
  921. N is the tree depth
  922. REVERSE means to reverse the list if the plist match is a list
  923. "
  924. (let* ((prefixtype (plist-get export-plist prop))
  925. subtype)
  926. (cond
  927. ((null prefixtype) "")
  928. ((and len (char-or-string-p prefixtype) (not (stringp prefixtype)))
  929. ;; sequence of chars
  930. (concat (make-string len prefixtype) "\n"))
  931. ((stringp prefixtype)
  932. prefixtype)
  933. ((and n (listp prefixtype))
  934. (if reverse
  935. (setq prefixtype (reverse prefixtype)))
  936. (setq subtype (if (> n (length prefixtype))
  937. (car (last prefixtype))
  938. (nth (1- n) prefixtype)))
  939. (if (stringp subtype)
  940. subtype
  941. (concat (make-string len subtype) "\n")))
  942. (t ""))
  943. ))
  944. (defun org-export-generic-header (header export-plist
  945. prefixprop formatprop postfixprop
  946. &optional n reverse)
  947. "convert a header to an output string given formatting property names"
  948. (let* ((formatspec (plist-get export-plist formatprop))
  949. (len (length header)))
  950. (concat
  951. (org-export-generic-format export-plist prefixprop len n reverse)
  952. (format (or formatspec "%s") header)
  953. (org-export-generic-format export-plist postfixprop len n reverse))
  954. ))
  955. (defun org-export-generic-preprocess (parameters)
  956. "Do extra work for ASCII export"
  957. ;; Put quotes around verbatim text
  958. (goto-char (point-min))
  959. (while (re-search-forward org-verbatim-re nil t)
  960. (goto-char (match-end 2))
  961. (backward-delete-char 1) (insert "'")
  962. (goto-char (match-beginning 2))
  963. (delete-char 1) (insert "`")
  964. (goto-char (match-end 2)))
  965. ;; Remove target markers
  966. (goto-char (point-min))
  967. (while (re-search-forward "<<<?\\([^<>]*\\)>>>?\\([ \t]*\\)" nil t)
  968. (replace-match "\\1\\2")))
  969. (defun org-html-expand-for-generic (line)
  970. "Handle quoted HTML for ASCII export."
  971. (if org-export-html-expand
  972. (while (string-match "@<[^<>\n]*>" line)
  973. ;; We just remove the tags for now.
  974. (setq line (replace-match "" nil nil line))))
  975. line)
  976. (defun org-export-generic-wrap (line where)
  977. "Wrap LINE at or before WHERE."
  978. (let* ((ind (org-get-indentation line))
  979. (indstr (make-string ind ?\ ))
  980. (len (length line))
  981. (result "")
  982. pos didfirst)
  983. (while (> len where)
  984. (catch 'found
  985. (loop for i from where downto (/ where 2) do
  986. (and (equal (aref line i) ?\ )
  987. (setq pos i)
  988. (throw 'found t))))
  989. (if pos
  990. (progn
  991. (setq result
  992. (concat result
  993. (if didfirst indstr "")
  994. (substring line 0 pos)
  995. "\n"))
  996. (setq didfirst t)
  997. (setq line (substring line (1+ pos)))
  998. (setq len (length line)))
  999. (setq result (concat result line))
  1000. (setq len 0)))
  1001. (concat result indstr line)))
  1002. (defun org-export-generic-push-links (link-buffer)
  1003. "Push out links in the buffer."
  1004. (when link-buffer
  1005. ;; We still have links to push out.
  1006. (insert "\n")
  1007. (let ((ind ""))
  1008. (save-match-data
  1009. (if (save-excursion
  1010. (re-search-backward
  1011. "^\\(\\([ \t]*\\)\\|\\(\\*+ \\)\\)[^ \t\n]" nil t))
  1012. (setq ind (or (match-string 2)
  1013. (make-string (length (match-string 3)) ?\ )))))
  1014. (mapc (lambda (x) (insert ind "[" (car x) "]: " (cdr x) "\n"))
  1015. link-buffer))
  1016. (insert "\n")))
  1017. (defun org-generic-level-start (level old-level title umax export-plist
  1018. &optional lines)
  1019. "Insert a new level in a generic export."
  1020. (let ((n (- level umax 1))
  1021. (ind 0)
  1022. (diff (- level old-level)) (counter 0)
  1023. (secnums (plist-get export-plist :body-header-section-numbers))
  1024. (secnumformat
  1025. (plist-get export-plist :body-header-section-number-format))
  1026. char tagstring)
  1027. (unless org-export-with-tags
  1028. (if (string-match (org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title)
  1029. (setq title (replace-match "" t t title))))
  1030. (cond
  1031. ;; going deeper
  1032. ((> level old-level)
  1033. (while (< (+ old-level counter) (1- level))
  1034. (insert
  1035. (org-export-generic-format export-plist :body-section-prefix 0
  1036. (+ old-level counter)))
  1037. (setq counter (1+ counter))
  1038. ))
  1039. ;; going up
  1040. ((< level old-level)
  1041. (while (> (- old-level counter) (1- level))
  1042. (insert
  1043. (org-export-generic-format export-plist :body-section-suffix 0
  1044. (- old-level counter)))
  1045. (setq counter (1+ counter))
  1046. ))
  1047. ;; same level
  1048. ((= level old-level)
  1049. (insert
  1050. (org-export-generic-format export-plist :body-section-suffix 0 level))
  1051. )
  1052. )
  1053. (insert
  1054. (org-export-generic-format export-plist :body-section-prefix 0 level))
  1055. (if (and org-export-with-section-numbers
  1056. secnums
  1057. (or (not (numberp secnums))
  1058. (< level secnums)))
  1059. (setq title
  1060. (concat (format (or secnumformat "%s ")
  1061. (org-section-number level)) title)))
  1062. ;; handle tags and formatting
  1063. (if (string-match
  1064. (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") title)
  1065. (progn
  1066. (if (plist-get export-plist :body-tags-export)
  1067. (setq tagstring (org-export-generic-header (match-string 1 title)
  1068. export-plist
  1069. :body-tags-prefix
  1070. :body-tags-format
  1071. :body-tags-suffix)))
  1072. (string-match (org-re "[ \t]+:[[:alnum:]_@:]+:[ \t]*$") title)
  1073. (setq title (replace-match "" t t title)))
  1074. (setq tagstring (plist-get export-plist :body-tags-none-string)))
  1075. (insert
  1076. (org-export-generic-header title export-plist
  1077. :body-section-header-prefix
  1078. :body-section-header-format
  1079. :body-section-header-suffix
  1080. level))
  1081. (if tagstring
  1082. (insert tagstring))
  1083. (setq org-generic-current-indentation '(0 . 0))))
  1084. (defun org-insert-centered (s &optional underline)
  1085. "Insert the string S centered and underline it with character UNDERLINE."
  1086. (let ((ind (max (/ (- fill-column (string-width s)) 2) 0)))
  1087. (insert (make-string ind ?\ ) s "\n")
  1088. (if underline
  1089. (insert (make-string ind ?\ )
  1090. (make-string (string-width s) underline)
  1091. "\n"))))
  1092. (defvar org-table-colgroup-info nil)
  1093. (defun org-format-table-generic (lines)
  1094. "Format a table for ascii export."
  1095. (if (stringp lines)
  1096. (setq lines (org-split-string lines "\n")))
  1097. (if (not (string-match "^[ \t]*|" (car lines)))
  1098. ;; Table made by table.el - test for spanning
  1099. lines
  1100. ;; A normal org table
  1101. ;; Get rid of hlines at beginning and end
  1102. (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines)))
  1103. (setq lines (nreverse lines))
  1104. (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines)))
  1105. (setq lines (nreverse lines))
  1106. (when org-export-table-remove-special-lines
  1107. ;; Check if the table has a marking column. If yes remove the
  1108. ;; column and the special lines
  1109. (setq lines (org-table-clean-before-export lines)))
  1110. ;; Get rid of the vertical lines except for grouping
  1111. (let ((vl (org-colgroup-info-to-vline-list org-table-colgroup-info))
  1112. rtn line vl1 start)
  1113. (while (setq line (pop lines))
  1114. (if (string-match org-table-hline-regexp line)
  1115. (and (string-match "|\\(.*\\)|" line)
  1116. (setq line (replace-match " \\1" t nil line)))
  1117. (setq start 0 vl1 vl)
  1118. (while (string-match "|" line start)
  1119. (setq start (match-end 0))
  1120. (or (pop vl1) (setq line (replace-match " " t t line)))))
  1121. (push line rtn))
  1122. (nreverse rtn))))
  1123. (defun org-colgroup-info-to-vline-list (info)
  1124. (let (vl new last)
  1125. (while info
  1126. (setq last new new (pop info))
  1127. (if (or (memq last '(:end :startend))
  1128. (memq new '(:start :startend)))
  1129. (push t vl)
  1130. (push nil vl)))
  1131. (setq vl (nreverse vl))
  1132. (and vl (setcar vl nil))
  1133. vl))
  1134. ;;; FIXME: this should probably turn into a defconstant later [2010/05/20:rpg]
  1135. (defvar org-export-generic-emphasis-alist
  1136. '(("*" format-boldify nil)
  1137. ("/" format-italicize nil)
  1138. ("_" format-underline nil)
  1139. ("+" format-strikethrough nil)
  1140. ("=" format-code t)
  1141. ("~" format-verbatim t))
  1142. "Alist of org format -> formatting variables for fontification.
  1143. Each element of the list is a list of three elements.
  1144. The first element is the character used as a marker for fontification.
  1145. The second element is a variable name, set in org-export-generic. That
  1146. variable will be dereferenced to obtain a formatting string to wrap
  1147. fontified text with.
  1148. The third element decides whether to protect converted text from other
  1149. conversions.")
  1150. ;;; Cargo-culted from the latex translation. I couldn't figure out how
  1151. ;;; to keep the structure since the generic export operates on lines, rather
  1152. ;;; than on a buffer as in the latex export, meaning that none of the
  1153. ;;; search forward code could be kept. This led me to rewrite the
  1154. ;;; whole thing recursively. A huge lose for efficiency (potentially),
  1155. ;;; but I couldn't figure out how to make the looping work.
  1156. ;;; Worse, it's /doubly/ recursive, because this function calls
  1157. ;;; org-export-generic-emph-format, which can call it recursively...
  1158. ;;; [2010/05/20:rpg]
  1159. (defun org-export-generic-fontify (string)
  1160. "Convert fontification according to generic rules."
  1161. (if (string-match org-emph-re string)
  1162. ;; The match goes one char after the *string*, except at the end of a line
  1163. ;; as far as I can tell from cargo-culting the code from
  1164. ;; the latex translation, we have the following:
  1165. ;; (match-string 1) is the material BEFORE the match
  1166. ;; -- should be unchanged
  1167. ;; (match-string 3) is the actual markup character
  1168. ;; (match-string 4) is the material that is to be
  1169. ;; marked up
  1170. ;; (match-string 5) is the remainder
  1171. (let ((emph (assoc (match-string 3 string)
  1172. org-export-generic-emphasis-alist))
  1173. (beg (match-beginning 0)))
  1174. (unless emph
  1175. (message "`org-export-generic-emphasis-alist' has no entry for formatting triggered by \"%s\""
  1176. (match-string 3 string)))
  1177. ;; now we need to determine whether we have strikethrough or
  1178. ;; a list, which is a bit nasty
  1179. (if (and (equal (match-string 3 str) "+")
  1180. (save-match-data
  1181. (string-match "\\`-+\\'" (match-string 4 str))))
  1182. ;; a list --- skip this match and recurse
  1183. (concat (substring str 0 (match-beginning 3))
  1184. (org-export-generic-fontify (substring str (match-beginning 3))))
  1185. (concat (substring str 0 beg)
  1186. (match-string 1 string)
  1187. (org-export-generic-emph-format (second emph)
  1188. (match-string 4 string)
  1189. (third emph))
  1190. (org-export-generic-fontify (match-string 5 string)))))
  1191. string))
  1192. (defun org-export-generic-emph-format (format-varname string protect)
  1193. "Return a string that results from applying the markup indicated by
  1194. FORMAT-VARNAME to STRING."
  1195. (let ((format (symbol-value format-varname)))
  1196. (let ((string-to-emphasize
  1197. (if protect
  1198. string
  1199. (org-export-generic-fontify string))))
  1200. (if format
  1201. (format format string-to-emphasize)
  1202. string-to-emphasize))))
  1203. (provide 'org-generic)
  1204. (provide 'org-export-generic)
  1205. ;;; org-export-generic.el ends here