org-export-generic.el 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232
  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. ;;
  90. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  91. ;;
  92. ;;; Commentary:
  93. (require 'org-exp)
  94. (defgroup org-export-generic nil
  95. "Options specific for ASCII export of Org-mode files."
  96. :tag "Org Export ASCII"
  97. :group 'org-export)
  98. (defcustom org-export-generic-links-to-notes t
  99. "Non-nil means, convert links to notes before the next headline.
  100. When nil, the link will be exported in place. If the line becomes long
  101. in this way, it will be wrapped."
  102. :group 'org-export-generic
  103. :type 'boolean)
  104. (defvar org-generic-current-indentation nil) ; For communication
  105. (defvar org-generic-alist
  106. '(
  107. ;;
  108. ;; generic DEMO exporter
  109. ;;
  110. ;; (this tries to use every specifier for demo purposes)
  111. ;;
  112. ("demo"
  113. :file-suffix ".txt"
  114. :key-binding ?d
  115. :header-prefix "<header>\n"
  116. :header-suffix "</header>\n"
  117. :author-export t
  118. :tags-export t
  119. :drawers-export t
  120. :title-prefix ?=
  121. :title-format "<h1>%s</h1>\n"
  122. :title-suffix ?=
  123. :date-export t
  124. :date-prefix "<date>"
  125. :date-format "<br /><b>Date:</b> <i>%s</i><br />"
  126. :date-suffix "</date>\n\n"
  127. :toc-export t
  128. :toc-header-prefix "<tocname>\n"
  129. :toc-header-format "__%s__\n"
  130. :toc-header-suffix "</tocname>\n"
  131. :toc-prefix "<toc>\n"
  132. :toc-suffix "</toc>\n"
  133. :toc-section-numbers t
  134. :toc-section-number-format "\#(%s) "
  135. :toc-format "--%s--"
  136. :toc-format-with-todo "!!%s!!\n"
  137. :toc-indent-char ?\
  138. :toc-indent-depth 4
  139. :toc-tags-export t
  140. :toc-tags-prefix " <tags>"
  141. :toc-tags-format "*%s*"
  142. :toc-tags-suffix "</tags>\n"
  143. :toc-tags-none-string "\n"
  144. :body-header-section-numbers 3 ; t = all, nil = none
  145. ; lists indicate different things per level
  146. ; list contents or straight value can either be a
  147. ; ?x char reference for printing strings that match the header len
  148. ; "" string to print directly
  149. :body-section-header-prefix ("<h1>" "<h2>" "<h3>"
  150. "<h4>" "<h5>" "<h6>")
  151. :body-section-header-format "%s"
  152. :body-section-header-suffix ("</h1>\n" "</h2>\n" "</h3>\n"
  153. "</h4>\n" "</h5>\n" "</h6>\n")
  154. :timestamps-export t
  155. :priorities-export t
  156. :todo-keywords-export t
  157. :body-tags-export t
  158. :body-tags-prefix " <tags>"
  159. :body-tags-suffix "</tags>\n"
  160. ; section prefixes/suffixes can be direct strings or lists as well
  161. :body-section-prefix "<secprefix>\n"
  162. :body-section-suffix "</secsuffix>\n"
  163. ; :body-section-prefix ("<sec1>\n" "<sec2>\n" "<sec3>\n")
  164. ; :body-section-suffix ("</sec1>\n" "</sec2>\n" "</sec3>\n")
  165. ; if preformated text should be included (eg, : prefixed)
  166. :body-line-export-preformated t
  167. :body-line-fixed-prefix "<pre>\n"
  168. :body-line-fixed-suffix "\n</pre>\n"
  169. :body-line-fixed-format "%s\n"
  170. :body-list-prefix "<list>\n"
  171. :body-list-suffix "</list>\n"
  172. :body-list-format "<li>%s</li>\n"
  173. :body-number-list-prefix "<ol>\n"
  174. :body-number-list-suffix "</ol>\n"
  175. :body-number-list-format "<li>%s</li>\n"
  176. :body-number-list-leave-number t
  177. :body-list-checkbox-todo "<checkbox type=\"todo\">"
  178. :body-list-checkbox-todo-end "</checkbox (todo)>"
  179. :body-list-checkbox-done "<checkbox type=\"done\">"
  180. :body-list-checkbox-done-end "</checkbox (done)>"
  181. :body-list-checkbox-half "<checkbox type=\"half\">"
  182. :body-list-checkbox-half-end "</checkbox (half)>"
  183. ; other body lines
  184. :body-line-format "%s"
  185. :body-line-wrap 60 ; wrap at 60 chars
  186. ; print above and below all body parts
  187. :body-text-prefix "<p>\n"
  188. :body-text-suffix "</p>\n"
  189. )
  190. ;;
  191. ;; ascii exporter
  192. ;;
  193. ;; (close to the original ascii specifier)
  194. ;;
  195. ("ascii"
  196. :file-suffix ".txt"
  197. :key-binding ?a
  198. :header-prefix ""
  199. :header-suffix ""
  200. :title-prefix ?=
  201. :title-format "%s\n"
  202. :title-suffix ?=
  203. :date-export t
  204. :date-prefix ""
  205. :date-format "Date: %s\n"
  206. :date-suffix ""
  207. :toc-header-prefix ""
  208. :toc-header-format "%s\n"
  209. :toc-header-suffix ?=
  210. :toc-export t
  211. :toc-section-numbers t
  212. :toc-section-number-format "%s "
  213. :toc-format "%s\n"
  214. :toc-format-with-todo "%s (*)\n"
  215. :toc-indent-char ?\
  216. :toc-indent-depth 4
  217. :body-header-section-numbers 3
  218. :body-section-prefix "\n"
  219. ; :body-section-header-prefix "\n"
  220. ; :body-section-header-format "%s\n"
  221. ; :body-section-header-suffix (?\$ ?\# ?^ ?\~ ?\= ?\-)
  222. :body-section-header-prefix ("" "" "" "* " " + " " - ")
  223. :body-section-header-format "%s\n"
  224. :body-section-header-suffix (?~ ?= ?- "\n" "\n" "\n")
  225. ; :body-section-marker-prefix ""
  226. ; :body-section-marker-chars (?\$ ?\# ?^ ?\~ ?\= ?\-)
  227. ; :body-section-marker-suffix "\n"
  228. :body-line-export-preformated t
  229. :body-line-format "%s\n"
  230. :body-line-wrap 75
  231. ; :body-text-prefix "<t>\n"
  232. ; :body-text-suffix "</t>\n"
  233. :body-bullet-list-prefix (?* ?+ ?-)
  234. ; :body-bullet-list-suffix (?* ?+ ?-)
  235. )
  236. ;;
  237. ;; wikipedia
  238. ;;
  239. ("wikipedia"
  240. :file-suffix ".txt"
  241. :key-binding ?w
  242. :header-prefix ""
  243. :header-suffix ""
  244. :title-format "= %s =\n"
  245. :date-export nil
  246. :toc-export nil
  247. :body-header-section-numbers nil
  248. :body-section-prefix "\n"
  249. :body-section-header-prefix ("= " "== " "=== "
  250. "==== " "===== " "====== ")
  251. :body-section-header-suffix (" =\n\n" " ==\n\n" " ===\n\n"
  252. " ====\n\n" " =====\n\n" " ======\n\n")
  253. :body-line-export-preformated t ;; yes/no/maybe???
  254. :body-line-format "%s\n"
  255. :body-line-wrap 75
  256. :body-line-fixed-format " %s\n"
  257. :body-list-format "* %s\n"
  258. :body-number-list-format "# %s\n"
  259. :body-bullet-list-prefix ("* " "** " "*** " "**** " "***** ")
  260. )
  261. ;;
  262. ;; minimal html exporter
  263. ;;
  264. ("html"
  265. ;; simple html output
  266. :file-suffix ".html"
  267. :key-binding ?h
  268. :header-prefix "<body>"
  269. :title-format "<h1>%s</h1>\n\n"
  270. :date-export t
  271. :date-format "<br /><b>Date:</b> <i>%s</i><br />\n\n"
  272. :toc-export nil
  273. :body-header-section-numbers 3
  274. :body-section-header-prefix ("<h1>" "<h2>" "<h3>"
  275. "<h4>" "<h5>" "<h6>")
  276. :body-section-header-format "%s"
  277. :body-section-header-suffix ("</h1>\n" "</h2>\n" "</h3>\n"
  278. "</h4>\n" "</h5>\n" "</h6>\n")
  279. :body-section-prefix "<secprefix>\n"
  280. :body-section-suffix "</secsuffix>\n"
  281. ; :body-section-prefix ("<sec1>\n" "<sec2>\n" "<sec3>\n")
  282. ; :body-section-suffix ("</sec1>\n" "</sec2>\n" "</sec3>\n")
  283. :body-line-export-preformated t
  284. :body-line-format "%s\n"
  285. :body-text-prefix "<p>\n"
  286. :body-text-suffix "</p>\n"
  287. :body-bullet-list-prefix (?* ?+ ?-)
  288. ; :body-bullet-list-suffix (?* ?+ ?-)
  289. )
  290. ;;
  291. ;; internet-draft .xml for xml2rfc exporter
  292. ;;
  293. ("ietfid"
  294. ;; this tries to use every specifier for demo purposes
  295. :file-suffix ".xml"
  296. :key-binding ?i
  297. :title-prefix "<?xml version=\"1.0\"\?>
  298. <!DOCTYPE rfc SYSTEM \"rfc2629.dtd\" [
  299. <!ENTITY rfcs PUBLIC '' 'blah'>
  300. <?rfc strict=\"yes\" ?>
  301. <?rfc toc=\"yes\" ?>
  302. <?rfc tocdepth=\"4\" ?>
  303. <?rfc symrefs=\"yes\" ?>
  304. <?rfc compact=\"yes\" ?>
  305. <?rfc subcompact=\"no\" ?>
  306. <rfc category=\"std\" ipr=\"pre5378Trust200902\" docName=\"FILLME.txt\">
  307. <front>
  308. "
  309. :title-format "<title abbrev=\"ABBREV HERE\">\n%s\n</title>\n"
  310. :title-suffix "<author initials=\"A.A\" surname=\"LASTNAME\" fullname=\"FULL NAME\">
  311. <organization>Comany, Inc..</organization>
  312. <address>
  313. <postal>
  314. <street></street>
  315. <city></city>
  316. <region></region>
  317. <code></code>
  318. <country></country>
  319. </postal>
  320. <phone></phone>
  321. <email></email>
  322. </address>
  323. </author>
  324. <date month=\"FILLMONTH\" year=\"FILLYEAR\"/>
  325. <area>Operations and Management</area>
  326. <workgroup>FIXME</workgroup>
  327. <abstract>\n"
  328. :date-export nil
  329. :toc-export nil
  330. :body-header-section-numbers nil
  331. :body-section-header-format "<section title=\"%s\">\n"
  332. :body-section-suffix "</section>\n"
  333. ; if preformated text should be included (eg, : prefixed)
  334. :body-line-export-preformated t
  335. :body-line-fixed-prefix "<figure>\n<artwork>\n"
  336. :body-line-fixed-suffix "\n</artwork>\n</figure>\n"
  337. ; other body lines
  338. :body-line-format "%s"
  339. :body-line-wrap 75
  340. ; print above and below all body parts
  341. :body-text-prefix "<t>\n"
  342. :body-text-suffix "</t>\n"
  343. :body-list-prefix "<list style=\"symbols\">\n"
  344. :body-list-suffix "</list>\n"
  345. :body-list-format "<t>%s</t>\n"
  346. )
  347. )
  348. "A assoc list of property lists to specify export definitions"
  349. )
  350. (setq org-generic-export-type "demo")
  351. (defvar org-export-generic-section-type "")
  352. (defvar org-export-generic-section-suffix "")
  353. ;;;###autoload
  354. (defun org-set-generic-type (type definition)
  355. "Adds a TYPE and DEFINITION to the existing list of defined generic
  356. export definitions."
  357. (set-alist 'org-generic-alist type definition))
  358. (defun org-export-generic-remember-section (type suffix &optional prefix)
  359. (setq org-export-generic-section-type type)
  360. (setq org-export-generic-section-suffix suffix)
  361. (if prefix
  362. (insert prefix))
  363. )
  364. (defun org-export-generic-check-section (type &optional prefix suffix)
  365. "checks to see if type is already in use, or we're switching parts
  366. If we're switching, then insert a potentially previously remembered
  367. suffix, and insert the current prefix immediately and then save the
  368. suffix a later change time."
  369. (when (not (equal type org-export-generic-section-type))
  370. (if org-export-generic-section-suffix
  371. (insert org-export-generic-section-suffix))
  372. (setq org-export-generic-section-type type)
  373. (setq org-export-generic-section-suffix suffix)
  374. (if prefix
  375. (insert prefix))))
  376. ;;;###autoload
  377. (defun org-export-generic (arg)
  378. "Export the outline as generic output.
  379. If there is an active region, export only the region.
  380. The prefix ARG specifies how many levels of the outline should become
  381. underlined headlines. The default is 3."
  382. (interactive "P")
  383. (setq-default org-todo-line-regexp org-todo-line-regexp)
  384. (let* ((opt-plist (org-combine-plists (org-default-export-plist)
  385. (org-infile-export-plist)))
  386. (region-p (org-region-active-p))
  387. (rbeg (and region-p (region-beginning)))
  388. (rend (and region-p (region-end)))
  389. (subtree-p
  390. (when region-p
  391. (save-excursion
  392. (goto-char rbeg)
  393. (and (org-at-heading-p)
  394. (>= (org-end-of-subtree t t) rend)))))
  395. (level-offset (if subtree-p
  396. (save-excursion
  397. (goto-char rbeg)
  398. (+ (funcall outline-level)
  399. (if org-odd-levels-only 1 0)))
  400. 0))
  401. (opt-plist (setq org-export-opt-plist
  402. (if subtree-p
  403. (org-export-add-subtree-options opt-plist rbeg)
  404. opt-plist)))
  405. helpstart
  406. (bogus (mapc (lambda (x)
  407. (setq helpstart
  408. (concat helpstart "\["
  409. (char-to-string
  410. (plist-get (cdr x) :key-binding))
  411. "] " (car x) "\n")))
  412. org-generic-alist))
  413. (help (concat helpstart "
  414. \[ ] the current setting of the org-generic-export-type variable
  415. "))
  416. (cmds
  417. (append
  418. (mapcar (lambda (x)
  419. (list
  420. (plist-get (cdr x) :key-binding)
  421. (car x)))
  422. org-generic-alist)
  423. (list (list ? "default"))))
  424. r1 r2 ass
  425. ;; read in the type to use
  426. (export-plist
  427. (progn
  428. (save-excursion
  429. (save-window-excursion
  430. (delete-other-windows)
  431. (with-output-to-temp-buffer "*Org Export/Generic Styles Help*"
  432. (princ help))
  433. (org-fit-window-to-buffer (get-buffer-window
  434. "*Org Export/Generic Styles Help*"))
  435. (message "Select command: ")
  436. (setq r1 (read-char-exclusive))))
  437. (setq r2 (if (< r1 27) (+ r1 96) r1))
  438. (unless (setq ass (cadr (assq r2 cmds)))
  439. (error "No command associated with key %c" r1))
  440. (cdr (assoc
  441. (if (equal ass "default") org-generic-export-type ass)
  442. org-generic-alist))))
  443. (custom-times org-display-custom-times)
  444. (org-generic-current-indentation '(0 . 0))
  445. (level 0) (old-level 0) line txt lastwastext
  446. (umax nil)
  447. (umax-toc nil)
  448. (case-fold-search nil)
  449. (bfname (buffer-file-name (or (buffer-base-buffer) (current-buffer))))
  450. (filesuffix (or (plist-get export-plist :file-suffix) ".foo"))
  451. (filename (concat (file-name-as-directory
  452. (org-export-directory :ascii opt-plist))
  453. (file-name-sans-extension
  454. (or (and subtree-p
  455. (org-entry-get (region-beginning)
  456. "EXPORT_FILE_NAME" t))
  457. (file-name-nondirectory bfname)))
  458. filesuffix))
  459. (filename (if (equal (file-truename filename)
  460. (file-truename bfname))
  461. (concat filename filesuffix)
  462. filename))
  463. (buffer (find-file-noselect filename))
  464. (org-levels-open (make-vector org-level-max nil))
  465. (odd org-odd-levels-only)
  466. (date (plist-get opt-plist :date))
  467. (author (plist-get opt-plist :author))
  468. (title (or (and subtree-p (org-export-get-title-from-subtree))
  469. (plist-get opt-plist :title)
  470. (and (not
  471. (plist-get opt-plist :skip-before-1st-heading))
  472. (org-export-grab-title-from-buffer))
  473. (file-name-sans-extension
  474. (file-name-nondirectory bfname))))
  475. (email (plist-get opt-plist :email))
  476. (language (plist-get opt-plist :language))
  477. (quote-re0 (concat "^[ \t]*" org-quote-string "\\>"))
  478. ; (quote-re (concat "^\\(\\*+\\)\\([ \t]*" org-quote-string "\\>\\)"))
  479. (todo nil)
  480. (lang-words nil)
  481. (region
  482. (buffer-substring
  483. (if (org-region-active-p) (region-beginning) (point-min))
  484. (if (org-region-active-p) (region-end) (point-max))))
  485. (lines (org-split-string
  486. (org-export-preprocess-string
  487. region
  488. :for-ascii t
  489. :skip-before-1st-heading
  490. (plist-get opt-plist :skip-before-1st-heading)
  491. :drawers (plist-get export-plist :drawers-export)
  492. :tags (plist-get export-plist :tags-export)
  493. :priority (plist-get export-plist :priority-export)
  494. :footnotes (plist-get export-plist :footnotes-export)
  495. :timestamps (plist-get export-plist :timestamps-export)
  496. :todo-keywords (plist-get export-plist :todo-keywords-export)
  497. :verbatim-multiline t
  498. :select-tags (plist-get export-plist :select-tags-export)
  499. :exclude-tags (plist-get export-plist :exclude-tags-export)
  500. :archived-trees
  501. (plist-get export-plist :archived-trees-export)
  502. :add-text (plist-get opt-plist :text))
  503. "\n"))
  504. ;; export-generic plist variables
  505. (withtags (plist-get export-plist :tags-export))
  506. (tagsintoc (plist-get export-plist :toc-tags-export))
  507. (tocnotagsstr (or (plist-get export-plist :toc-tags-none-string) ""))
  508. (tocdepth (plist-get export-plist :toc-indent-depth))
  509. (tocindentchar (plist-get export-plist :toc-indent-char))
  510. (tocsecnums (plist-get export-plist :toc-section-numbers))
  511. (tocsecnumform (plist-get export-plist :toc-section-number-format))
  512. (tocformat (plist-get export-plist :toc-format))
  513. (tocformtodo (plist-get export-plist :toc-format-with-todo))
  514. (tocprefix (plist-get export-plist :toc-prefix))
  515. (tocsuffix (plist-get export-plist :toc-suffix))
  516. (bodyfixedpre (plist-get export-plist :body-line-fixed-prefix))
  517. (bodyfixedsuf (plist-get export-plist :body-line-fixed-suffix))
  518. (bodyfixedform (or (plist-get export-plist :body-line-fixed-format)
  519. "%s"))
  520. (listprefix (plist-get export-plist :body-list-prefix))
  521. (listsuffix (plist-get export-plist :body-list-suffix))
  522. (listformat (or (plist-get export-plist :body-list-format) "%s\n"))
  523. (numlistleavenum
  524. (plist-get export-plist :body-number-list-leave-number))
  525. (numlistprefix (plist-get export-plist :body-number-list-prefix))
  526. (numlistsuffix (plist-get export-plist :body-number-list-suffix))
  527. (numlistformat
  528. (or (plist-get export-plist :body-number-list-format) "%s\n"))
  529. (listchecktodo
  530. (or (plist-get export-plist :body-list-checkbox-todo) "\\1"))
  531. (listcheckdone
  532. (or (plist-get export-plist :body-list-checkbox-done) "\\1"))
  533. (listcheckhalf
  534. (or (plist-get export-plist :body-list-checkbox-half) "\\1"))
  535. (listchecktodoend
  536. (or (plist-get export-plist :body-list-checkbox-todo-end) ""))
  537. (listcheckdoneend
  538. (or (plist-get export-plist :body-list-checkbox-done-end) ""))
  539. (listcheckhalfend
  540. (or (plist-get export-plist :body-list-checkbox-half-end) ""))
  541. (bodytextpre (plist-get export-plist :body-text-prefix))
  542. (bodytextsuf (plist-get export-plist :body-text-suffix))
  543. (bodylinewrap (plist-get export-plist :body-line-wrap))
  544. (bodylineform (or (plist-get export-plist :body-line-format) "%s"))
  545. thetoc toctags have-headings first-heading-pos
  546. table-open table-buffer link-buffer link desc desc0 rpl wrap)
  547. (let ((inhibit-read-only t))
  548. (org-unmodified
  549. (remove-text-properties (point-min) (point-max)
  550. '(:org-license-to-kill t))))
  551. (setq org-min-level (org-get-min-level lines level-offset))
  552. (setq org-last-level org-min-level)
  553. (org-init-section-numbers)
  554. (find-file-noselect filename)
  555. (setq lang-words (or (assoc language org-export-language-setup)
  556. (assoc "en" org-export-language-setup)))
  557. (switch-to-buffer-other-window buffer)
  558. (erase-buffer)
  559. (fundamental-mode)
  560. ;; create local variables for all options, to make sure all called
  561. ;; functions get the correct information
  562. (mapc (lambda (x)
  563. (set (make-local-variable (nth 2 x))
  564. (plist-get opt-plist (car x))))
  565. org-export-plist-vars)
  566. (org-set-local 'org-odd-levels-only odd)
  567. (setq umax (if arg (prefix-numeric-value arg)
  568. org-export-headline-levels))
  569. (setq umax-toc umax)
  570. ;; File header
  571. (if title
  572. (insert
  573. (org-export-generic-header title export-plist
  574. :title-prefix
  575. :title-format
  576. :title-suffix)))
  577. (if (and (or author email)
  578. (plist-get export-plist :author-export))
  579. (insert (concat (nth 1 lang-words) ": " (or author "")
  580. (if email (concat " <" email ">") "")
  581. "\n")))
  582. (cond
  583. ((and date (string-match "%" date))
  584. (setq date (format-time-string date)))
  585. (date)
  586. (t (setq date (format-time-string "%Y-%m-%d %T %Z"))))
  587. (if (and date (plist-get export-plist :date-export))
  588. (insert
  589. (org-export-generic-header date export-plist
  590. :date-prefix
  591. :date-format
  592. :date-suffix)))
  593. ;; export the table of contents first
  594. (if (plist-get export-plist :toc-export)
  595. (progn
  596. (push
  597. (org-export-generic-header (nth 3 lang-words) export-plist
  598. :toc-header-prefix
  599. :toc-header-format
  600. :toc-header-suffix)
  601. thetoc)
  602. (if tocprefix
  603. (push tocprefix thetoc))
  604. (mapc '(lambda (line)
  605. (if (string-match org-todo-line-regexp line)
  606. ;; This is a headline
  607. (progn
  608. (setq have-headings t)
  609. (setq level (- (match-end 1) (match-beginning 1)
  610. level-offset)
  611. level (org-tr-level level)
  612. txt (match-string 3 line)
  613. todo
  614. (or (and org-export-mark-todo-in-toc
  615. (match-beginning 2)
  616. (not (member (match-string 2 line)
  617. org-done-keywords)))
  618. ; TODO, not DONE
  619. (and org-export-mark-todo-in-toc
  620. (= level umax-toc)
  621. (org-search-todo-below
  622. line lines level))))
  623. (setq txt (org-html-expand-for-generic txt))
  624. (while (string-match org-bracket-link-regexp txt)
  625. (setq txt
  626. (replace-match
  627. (match-string (if (match-end 2) 3 1) txt)
  628. t t txt)))
  629. (if (and (not tagsintoc)
  630. (string-match
  631. (org-re "[ \t]+:[[:alnum:]_@:]+:[ \t]*$")
  632. txt))
  633. (setq txt (replace-match "" t t txt))
  634. ; include tags but formated
  635. (if (string-match
  636. (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$")
  637. txt)
  638. (progn
  639. (setq
  640. toctags
  641. (org-export-generic-header
  642. (match-string 1 txt)
  643. export-plist :toc-tags-prefix
  644. :toc-tags-format :toc-tags-suffix))
  645. (string-match
  646. (org-re "[ \t]+:[[:alnum:]_@:]+:[ \t]*$")
  647. txt)
  648. (setq txt (replace-match "" t t txt)))
  649. (setq toctags tocnotagsstr)))
  650. (if (string-match quote-re0 txt)
  651. (setq txt (replace-match "" t t txt)))
  652. (if (<= level umax-toc)
  653. (progn
  654. (push
  655. (concat
  656. (make-string
  657. (* (max 0 (- level org-min-level)) tocdepth)
  658. tocindentchar)
  659. (if tocsecnums
  660. (format tocsecnumform
  661. (org-section-number level))
  662. "")
  663. (format
  664. (if todo tocformtodo tocformat)
  665. txt)
  666. toctags)
  667. thetoc)
  668. (setq org-last-level level))
  669. ))))
  670. lines)
  671. (if tocsuffix
  672. (push tocsuffix thetoc))
  673. (setq thetoc (if have-headings (nreverse thetoc) nil))))
  674. (org-init-section-numbers)
  675. (org-export-generic-check-section "top")
  676. (while (setq line (pop lines))
  677. (when (and link-buffer (string-match "^\\*+ " line))
  678. (org-export-generic-push-links (nreverse link-buffer))
  679. (setq link-buffer nil))
  680. (setq wrap nil)
  681. ;; Remove the quoted HTML tags.
  682. ;; XXX
  683. (setq line (org-html-expand-for-generic line))
  684. ;; Replace links with the description when possible
  685. ;; XXX
  686. (while (string-match org-bracket-link-regexp line)
  687. (setq link (match-string 1 line)
  688. desc0 (match-string 3 line)
  689. desc (or desc0 (match-string 1 line)))
  690. (if (and (> (length link) 8)
  691. (equal (substring link 0 8) "coderef:"))
  692. (setq line (replace-match
  693. (format (org-export-get-coderef-format (substring link 8) desc)
  694. (cdr (assoc
  695. (substring link 8)
  696. org-export-code-refs)))
  697. t t line))
  698. (setq rpl (concat "["
  699. (or (match-string 3 line) (match-string 1 line))
  700. "]"))
  701. (when (and desc0 (not (equal desc0 link)))
  702. (if org-export-generic-links-to-notes
  703. (push (cons desc0 link) link-buffer)
  704. (setq rpl (concat rpl " (" link ")")
  705. wrap (+ (length line) (- (length (match-string 0)))
  706. (length desc)))))
  707. (setq line (replace-match rpl t t line))))
  708. (when custom-times
  709. (setq line (org-translate-time line)))
  710. (cond
  711. ((string-match "^\\(\\*+\\)[ \t]+\\(.*\\)" line)
  712. ;;
  713. ;; a Headline
  714. ;;
  715. (org-export-generic-check-section "headline")
  716. (setq first-heading-pos (or first-heading-pos (point)))
  717. (setq level (org-tr-level (- (match-end 1) (match-beginning 1)
  718. level-offset))
  719. txt (match-string 2 line))
  720. (org-generic-level-start level old-level txt umax export-plist lines)
  721. (setq old-level level))
  722. ((and org-export-with-tables
  723. (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)" line))
  724. ;;
  725. ;; a Table
  726. ;;
  727. (org-export-generic-check-section "table")
  728. (if (not table-open)
  729. ;; New table starts
  730. (setq table-open t table-buffer nil))
  731. ;; Accumulate table lines
  732. (setq table-buffer (cons line table-buffer))
  733. (when (or (not lines)
  734. (not (string-match "^\\([ \t]*\\)\\(|\\|\\+-+\\+\\)"
  735. (car lines))))
  736. (setq table-open nil
  737. table-buffer (nreverse table-buffer))
  738. (insert (mapconcat
  739. (lambda (x)
  740. (org-fix-indentation x org-generic-current-indentation))
  741. (org-format-table-generic table-buffer)
  742. "\n") "\n")))
  743. ((string-match "^\\([ \t]*\\)\\(:\\( \\|$\\)\\)" line)
  744. ;;
  745. ;; pre-formated text
  746. ;;
  747. (setq line (replace-match "\\1" nil nil line))
  748. (org-export-generic-check-section "preformat" bodyfixedpre bodyfixedsuf)
  749. (insert (format bodyfixedform line)))
  750. ((string-match "^\\([ \t]+\\)\\([-+*][ \t]*\\)" line)
  751. ;;
  752. ;; plain list item
  753. ;;
  754. ;; TODO: nested lists
  755. ;;
  756. (setq line (replace-match "" nil nil line))
  757. (org-export-generic-check-section "liststart" listprefix listsuffix)
  758. ;; deal with checkboxes
  759. (cond
  760. ((string-match "^\\(\\[ \\]\\)[ \t]*" line)
  761. (setq line (concat (replace-match listchecktodo nil nil line)
  762. listchecktodoend)))
  763. ((string-match "^\\(\\[X\\]\\)[ \t]*" line)
  764. (setq line (concat (replace-match listcheckdone nil nil line)
  765. listcheckdoneend)))
  766. ((string-match "^\\(\\[/\\]\\)[ \t]*" line)
  767. (setq line (concat (replace-match listcheckhalf nil nil line)
  768. listcheckhalfend)))
  769. )
  770. (insert (format listformat line)))
  771. ((string-match "^\\([ \t]+\\)\\([0-9]+\\.[ \t]*\\)" line)
  772. ;;
  773. ;; numbered list item
  774. ;;
  775. ;; TODO: nested lists
  776. ;;
  777. (setq line (replace-match (if numlistleavenum "\\2" "") nil nil line))
  778. (org-export-generic-check-section "numliststart"
  779. numlistprefix numlistsuffix)
  780. ;; deal with checkboxes
  781. ;; TODO: whoops; leaving the numbers is a problem for ^ matching
  782. (cond
  783. ((string-match "\\(\\[ \\]\\)[ \t]*" line)
  784. (setq line (concat (replace-match listchecktodo nil nil line)
  785. listchecktodoend)))
  786. ((string-match "\\(\\[X\\]\\)[ \t]*" line)
  787. (setq line (concat (replace-match listcheckdone nil nil line)
  788. listcheckdoneend)))
  789. ((string-match "\\(\\[/\\]\\)[ \t]*" line)
  790. (setq line (concat (replace-match listcheckhalf nil nil line)
  791. listcheckhalfend)))
  792. )
  793. (insert (format numlistformat line)))
  794. (t
  795. ;;
  796. ;; body
  797. ;;
  798. (org-export-generic-check-section "body" bodytextpre bodytextsuf)
  799. ;; XXX: properties? list?
  800. (if (string-match "^\\([ \t]*\\)\\([-+*][ \t]+\\)\\(.*?\\)\\( ::\\)" line)
  801. (setq line (replace-match "\\1\\3:" t nil line)))
  802. (setq line (org-fix-indentation line org-generic-current-indentation))
  803. ;; Remove forced line breaks
  804. (if (string-match "\\\\\\\\[ \t]*$" line)
  805. (setq line (replace-match "" t t line)))
  806. (if bodylinewrap
  807. ;; XXX: was dependent on wrap var which was calculated by???
  808. (if (> (length line) bodylinewrap)
  809. (setq line
  810. (org-export-generic-wrap line bodylinewrap))
  811. (setq line line)))
  812. (insert (format bodylineform line)))))
  813. (org-export-generic-check-section "bottom")
  814. (org-export-generic-push-links (nreverse link-buffer))
  815. (normal-mode)
  816. ;; insert the table of contents
  817. (when thetoc
  818. (goto-char (point-min))
  819. (if (re-search-forward "^[ \t]*\\[TABLE-OF-CONTENTS\\][ \t]*$" nil t)
  820. (progn
  821. (goto-char (match-beginning 0))
  822. (replace-match ""))
  823. (goto-char first-heading-pos))
  824. (mapc 'insert thetoc)
  825. (or (looking-at "[ \t]*\n[ \t]*\n")
  826. (insert "\n\n")))
  827. ;; Convert whitespace place holders
  828. (goto-char (point-min))
  829. (let (beg end)
  830. (while (setq beg (next-single-property-change (point) 'org-whitespace))
  831. (setq end (next-single-property-change beg 'org-whitespace))
  832. (goto-char beg)
  833. (delete-region beg end)
  834. (insert (make-string (- end beg) ?\ ))))
  835. (save-buffer)
  836. ;; remove display and invisible chars
  837. (let (beg end)
  838. (goto-char (point-min))
  839. (while (setq beg (next-single-property-change (point) 'display))
  840. (setq end (next-single-property-change beg 'display))
  841. (delete-region beg end)
  842. (goto-char beg)
  843. (insert "=>"))
  844. (goto-char (point-min))
  845. (while (setq beg (next-single-property-change (point) 'org-cwidth))
  846. (setq end (next-single-property-change beg 'org-cwidth))
  847. (delete-region beg end)
  848. (goto-char beg)))
  849. (goto-char (point-min))))
  850. (defun org-export-generic-format (export-plist prop &optional len n reverse)
  851. "converts a property specification to a string given types of properties
  852. The EXPORT-PLIST should be defined as the lookup plist.
  853. The PROP should be the property name to search for in it.
  854. LEN is set to the length of multi-characters strings to generate (or 0)
  855. N is the tree depth
  856. REVERSE means to reverse the list if the plist match is a list
  857. "
  858. (let* ((prefixtype (plist-get export-plist prop))
  859. subtype)
  860. (cond
  861. ((null prefixtype) "")
  862. ((and len (characterp prefixtype))
  863. ;; sequence of chars
  864. (concat (make-string len prefixtype) "\n"))
  865. ((stringp prefixtype)
  866. prefixtype)
  867. ((and n (listp prefixtype))
  868. (if reverse
  869. (setq prefixtype (reverse prefixtype)))
  870. (setq subtype (if (> n (length prefixtype))
  871. (car (last prefixtype))
  872. (nth (1- n) prefixtype)))
  873. (if (stringp subtype)
  874. subtype
  875. (concat (make-string len subtype) "\n")))
  876. (t ""))
  877. ))
  878. (defun org-export-generic-header (header export-plist
  879. prefixprop formatprop postfixprop
  880. &optional n reverse)
  881. "convert a header to an output string given formatting property names"
  882. (let* ((formatspec (plist-get export-plist formatprop))
  883. (len (length header)))
  884. (concat
  885. (org-export-generic-format export-plist prefixprop len n reverse)
  886. (format (or formatspec "%s") header)
  887. (org-export-generic-format export-plist postfixprop len n reverse))
  888. ))
  889. (defun org-export-generic-preprocess (parameters)
  890. "Do extra work for ASCII export"
  891. ;; Put quotes around verbatim text
  892. (goto-char (point-min))
  893. (while (re-search-forward org-verbatim-re nil t)
  894. (goto-char (match-end 2))
  895. (backward-delete-char 1) (insert "'")
  896. (goto-char (match-beginning 2))
  897. (delete-char 1) (insert "`")
  898. (goto-char (match-end 2)))
  899. ;; Remove target markers
  900. (goto-char (point-min))
  901. (while (re-search-forward "<<<?\\([^<>]*\\)>>>?\\([ \t]*\\)" nil t)
  902. (replace-match "\\1\\2")))
  903. (defun org-html-expand-for-generic (line)
  904. "Handle quoted HTML for ASCII export."
  905. (if org-export-html-expand
  906. (while (string-match "@<[^<>\n]*>" line)
  907. ;; We just remove the tags for now.
  908. (setq line (replace-match "" nil nil line))))
  909. line)
  910. (defun org-export-generic-wrap (line where)
  911. "Wrap LINE at or before WHERE."
  912. (let* ((ind (org-get-indentation line))
  913. (indstr (make-string ind ?\ ))
  914. (len (length line))
  915. (result "")
  916. pos didfirst)
  917. (while (> len where)
  918. (catch 'found
  919. (loop for i from where downto (/ where 2) do
  920. (and (equal (aref line i) ?\ )
  921. (setq pos i)
  922. (throw 'found t))))
  923. (if pos
  924. (progn
  925. (setq result
  926. (concat result
  927. (if didfirst indstr "")
  928. (substring line 0 pos)
  929. "\n"))
  930. (setq didfirst t)
  931. (setq line (substring line (1+ pos)))
  932. (setq len (length line)))
  933. (setq result (concat result line))
  934. (setq len 0)))
  935. (concat result indstr line)))
  936. (defun org-export-generic-push-links (link-buffer)
  937. "Push out links in the buffer."
  938. (when link-buffer
  939. ;; We still have links to push out.
  940. (insert "\n")
  941. (let ((ind ""))
  942. (save-match-data
  943. (if (save-excursion
  944. (re-search-backward
  945. "^\\(\\([ \t]*\\)\\|\\(\\*+ \\)\\)[^ \t\n]" nil t))
  946. (setq ind (or (match-string 2)
  947. (make-string (length (match-string 3)) ?\ )))))
  948. (mapc (lambda (x) (insert ind "[" (car x) "]: " (cdr x) "\n"))
  949. link-buffer))
  950. (insert "\n")))
  951. (defun org-generic-level-start (level old-level title umax export-plist
  952. &optional lines)
  953. "Insert a new level in a generic export."
  954. (let ((n (- level umax 1))
  955. (ind 0)
  956. (diff (- level old-level)) (counter 0)
  957. (secnums (plist-get export-plist :body-header-section-numbers))
  958. (secnumformat
  959. (plist-get export-plist :body-header-section-number-format))
  960. char tagstring)
  961. (unless org-export-with-tags
  962. (if (string-match (org-re "[ \t]+\\(:[[:alnum:]_@:]+:\\)[ \t]*$") title)
  963. (setq title (replace-match "" t t title))))
  964. (cond
  965. ;; going deeper
  966. ((> level old-level)
  967. (while (< (+ old-level counter) (1- level))
  968. (insert
  969. (org-export-generic-format export-plist :body-section-prefix 0
  970. (+ old-level counter)))
  971. (setq counter (1+ counter))
  972. ))
  973. ;; going up
  974. ((< level old-level)
  975. (while (> (- old-level counter) (1- level))
  976. (insert
  977. (org-export-generic-format export-plist :body-section-suffix 0
  978. (- old-level counter)))
  979. (setq counter (1+ counter))
  980. ))
  981. ;; same level
  982. ((= level old-level)
  983. (insert
  984. (org-export-generic-format export-plist :body-section-suffix 0 level))
  985. )
  986. )
  987. (insert
  988. (org-export-generic-format export-plist :body-section-prefix 0 level))
  989. (if (and org-export-with-section-numbers
  990. secnums
  991. (or (not (numberp secnums))
  992. (< level secnums)))
  993. (setq title
  994. (concat (format (or secnumformat "%s ")
  995. (org-section-number level)) title)))
  996. ;; handle tags and formatting
  997. (if (string-match
  998. (org-re "[ \t]+:\\([[:alnum:]_@:]+\\):[ \t]*$") title)
  999. (progn
  1000. (if (plist-get export-plist :body-tags-export)
  1001. (setq tagstring (org-export-generic-header (match-string 1 title)
  1002. export-plist
  1003. :body-tags-prefix
  1004. :body-tags-format
  1005. :body-tags-suffix)))
  1006. (string-match (org-re "[ \t]+:[[:alnum:]_@:]+:[ \t]*$") title)
  1007. (setq title (replace-match "" t t title)))
  1008. (setq tagstring (plist-get export-plist :body-tags-none-string)))
  1009. (insert
  1010. (org-export-generic-header title export-plist
  1011. :body-section-header-prefix
  1012. :body-section-header-format
  1013. :body-section-header-suffix
  1014. level))
  1015. (if tagstring
  1016. (insert tagstring))
  1017. (setq org-generic-current-indentation '(0 . 0))))
  1018. (defun org-insert-centered (s &optional underline)
  1019. "Insert the string S centered and underline it with character UNDERLINE."
  1020. (let ((ind (max (/ (- fill-column (string-width s)) 2) 0)))
  1021. (insert (make-string ind ?\ ) s "\n")
  1022. (if underline
  1023. (insert (make-string ind ?\ )
  1024. (make-string (string-width s) underline)
  1025. "\n"))))
  1026. (defvar org-table-colgroup-info nil)
  1027. (defun org-format-table-generic (lines)
  1028. "Format a table for ascii export."
  1029. (if (stringp lines)
  1030. (setq lines (org-split-string lines "\n")))
  1031. (if (not (string-match "^[ \t]*|" (car lines)))
  1032. ;; Table made by table.el - test for spanning
  1033. lines
  1034. ;; A normal org table
  1035. ;; Get rid of hlines at beginning and end
  1036. (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines)))
  1037. (setq lines (nreverse lines))
  1038. (if (string-match "^[ \t]*|-" (car lines)) (setq lines (cdr lines)))
  1039. (setq lines (nreverse lines))
  1040. (when org-export-table-remove-special-lines
  1041. ;; Check if the table has a marking column. If yes remove the
  1042. ;; column and the special lines
  1043. (setq lines (org-table-clean-before-export lines)))
  1044. ;; Get rid of the vertical lines except for grouping
  1045. (let ((vl (org-colgroup-info-to-vline-list org-table-colgroup-info))
  1046. rtn line vl1 start)
  1047. (while (setq line (pop lines))
  1048. (if (string-match org-table-hline-regexp line)
  1049. (and (string-match "|\\(.*\\)|" line)
  1050. (setq line (replace-match " \\1" t nil line)))
  1051. (setq start 0 vl1 vl)
  1052. (while (string-match "|" line start)
  1053. (setq start (match-end 0))
  1054. (or (pop vl1) (setq line (replace-match " " t t line)))))
  1055. (push line rtn))
  1056. (nreverse rtn))))
  1057. (defun org-colgroup-info-to-vline-list (info)
  1058. (let (vl new last)
  1059. (while info
  1060. (setq last new new (pop info))
  1061. (if (or (memq last '(:end :startend))
  1062. (memq new '(:start :startend)))
  1063. (push t vl)
  1064. (push nil vl)))
  1065. (setq vl (nreverse vl))
  1066. (and vl (setcar vl nil))
  1067. vl))
  1068. (provide 'org-generic)
  1069. ;;; org-export-generic.el ends here