org-export-generic.el 50 KB

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