test-org-export.el 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. ;;; test-org-export.el --- Tests for org-export.el
  2. ;; Copyright (C) 2012 Nicolas Goaziou
  3. ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
  4. ;; Released under the GNU General Public License version 3
  5. ;; see: http://www.gnu.org/licenses/gpl-3.0.html
  6. ;;;; Comments
  7. ;;; Code:
  8. (unless (featurep 'org-export)
  9. (signal 'missing-test-dependency "org-export"))
  10. ;;; Tests
  11. (defmacro org-test-with-backend (backend &rest body)
  12. "Execute body with an export back-end defined.
  13. BACKEND is the name, as a string, of the back-end. BODY is the
  14. body to execute. The defined back-end simply returns parsed data
  15. as Org syntax."
  16. (declare (debug (form body)) (indent 1))
  17. `(flet ,(let (transcoders)
  18. (dolist (type (append org-element-all-elements
  19. org-element-all-objects)
  20. transcoders)
  21. (push `(,(intern (format "org-%s-%s" backend type))
  22. (obj contents info)
  23. (,(intern (format "org-element-%s-interpreter" type))
  24. obj contents))
  25. transcoders)))
  26. ,@body))
  27. (ert-deftest test-org-export/parse-option-keyword ()
  28. "Test reading all standard #+OPTIONS: items."
  29. (should
  30. (equal
  31. (org-export-parse-option-keyword
  32. "H:1 num:t \\n:t timestamp:t arch:t author:t creator:t d:t email:t
  33. *:t e:t ::t f:t pri:t -:t ^:t toc:t |:t tags:t tasks:t <:t todo:t")
  34. '(:headline-levels
  35. 1 :preserve-breaks t :section-numbers t :time-stamp-file t
  36. :with-archived-trees t :with-author t :with-creator t :with-drawers t
  37. :with-email t :with-emphasize t :with-entities t :with-fixed-width t
  38. :with-footnotes t :with-priority t :with-special-strings t
  39. :with-sub-superscript t :with-toc t :with-tables t :with-tags t
  40. :with-tasks t :with-timestamps t :with-todo-keywords t)))
  41. ;; Test some special values.
  42. (should
  43. (equal
  44. (org-export-parse-option-keyword
  45. "arch:headline creator:comment d:(\"TEST\")
  46. ^:{} toc:1 tags:not-in-toc tasks:todo num:2")
  47. '( :section-numbers
  48. 2
  49. :with-archived-trees headline :with-creator comment
  50. :with-drawers ("TEST") :with-sub-superscript {} :with-toc 1
  51. :with-tags not-in-toc :with-tasks todo))))
  52. (ert-deftest test-org-export/get-inbuffer-options ()
  53. "Test reading all standard export keywords."
  54. (should
  55. (equal
  56. (org-test-with-temp-text "#+AUTHOR: Me, Myself and I
  57. #+CREATOR: Idem
  58. #+DATE: Today
  59. #+DESCRIPTION: Testing
  60. #+DESCRIPTION: with two lines
  61. #+EMAIL: some@email.org
  62. #+EXPORT_EXCLUDE_TAGS: noexport invisible
  63. #+KEYWORDS: test
  64. #+LANGUAGE: en
  65. #+EXPORT_SELECT_TAGS: export
  66. #+TITLE: Some title
  67. #+TITLE: with spaces"
  68. (org-export-get-inbuffer-options))
  69. '(:author
  70. "Me, Myself and I" :creator "Idem" :date "Today"
  71. :description "Testing\nwith two lines" :email "some@email.org"
  72. :exclude-tags ("noexport" "invisible") :keywords "test" :language "en"
  73. :select-tags ("export") :title "Some title with spaces"))))
  74. (ert-deftest test-org-export/define-macro ()
  75. "Try defining various Org macro using in-buffer #+MACRO: keyword."
  76. ;; Parsed macro.
  77. (should (equal (org-test-with-temp-text "#+MACRO: one 1"
  78. (org-export-get-inbuffer-options))
  79. '(:macro-one ("1"))))
  80. ;; Evaled macro.
  81. (should (equal (org-test-with-temp-text "#+MACRO: two (eval (+ 1 1))"
  82. (org-export-get-inbuffer-options))
  83. '(:macro-two "(eval (+ 1 1))")))
  84. ;; Incomplete macro.
  85. (should-not (org-test-with-temp-text "#+MACRO: three"
  86. (org-export-get-inbuffer-options)))
  87. ;; Macro with newline character.
  88. (should (equal (org-test-with-temp-text "#+MACRO: four a\\nb"
  89. (org-export-get-inbuffer-options))
  90. '(:macro-four ("a\nb"))))
  91. ;; Macro with protected newline character.
  92. (should (equal (org-test-with-temp-text "#+MACRO: five a\\\\nb"
  93. (org-export-get-inbuffer-options))
  94. '(:macro-five ("a\\nb"))))
  95. ;; Recursive macro.
  96. (org-test-with-temp-text "#+MACRO: six 6\n#+MACRO: seven 1 + {{{six}}}"
  97. (should
  98. (equal
  99. (org-export-get-inbuffer-options)
  100. '(:macro-six
  101. ("6")
  102. :macro-seven
  103. ("1 + " (macro (:key "six" :value "{{{six}}}" :args nil :begin 5 :end 14
  104. :post-blank 0))))))))
  105. (ert-deftest test-org-export/handle-options ()
  106. "Test if export options have an impact on output."
  107. ;; Test exclude tags.
  108. (org-test-with-temp-text "* Head1 :noexport:"
  109. (org-test-with-backend "test"
  110. (should
  111. (equal (org-export-as 'test nil nil nil '(:exclude-tags ("noexport")))
  112. ""))))
  113. ;; Test include tags.
  114. (org-test-with-temp-text "
  115. * Head1
  116. ** Sub-Head1.1 :export:
  117. *** Sub-Head1.1.1
  118. * Head2"
  119. (org-test-with-backend "test"
  120. (should
  121. (string-match
  122. "\\* Head1\n\\*\\* Sub-Head1.1[ \t]+:export:\n\\*\\*\\* Sub-Head1.1.1\n"
  123. (org-export-as 'test nil nil nil '(:select-tags ("export")))))))
  124. ;; Test mixing include tags and exclude tags.
  125. (org-test-with-temp-text "
  126. * Head1 :export:
  127. ** Sub-Head1 :noexport:
  128. ** Sub-Head2
  129. * Head2 :noexport:
  130. ** Sub-Head1 :export:"
  131. (org-test-with-backend "test"
  132. (should
  133. (string-match
  134. "\\* Head1[ \t]+:export:\n\\*\\* Sub-Head2\n"
  135. (org-export-as
  136. 'test nil nil nil
  137. '(:select-tags ("export") :exclude-tags ("noexport")))))))
  138. ;; Ignore tasks.
  139. (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
  140. (org-test-with-temp-text "* TODO Head1"
  141. (org-test-with-backend "test"
  142. (should (equal (org-export-as 'test nil nil nil '(:with-tasks nil))
  143. "")))))
  144. (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
  145. (org-test-with-temp-text "* TODO Head1"
  146. (org-test-with-backend "test"
  147. (should (equal (org-export-as 'test nil nil nil '(:with-tasks t))
  148. "* TODO Head1\n")))))
  149. ;; Archived tree.
  150. (org-test-with-temp-text "* Head1 :archive:"
  151. (let ((org-archive-tag "archive"))
  152. (org-test-with-backend "test"
  153. (should
  154. (equal (org-export-as 'test nil nil nil '(:with-archived-trees nil))
  155. "")))))
  156. (org-test-with-temp-text "* Head1 :archive:\nbody\n** Sub-head 2"
  157. (let ((org-archive-tag "archive"))
  158. (org-test-with-backend "test"
  159. (should
  160. (string-match
  161. "\\* Head1[ \t]+:archive:"
  162. (org-export-as 'test nil nil nil
  163. '(:with-archived-trees headline)))))))
  164. (org-test-with-temp-text "* Head1 :archive:"
  165. (let ((org-archive-tag "archive"))
  166. (org-test-with-backend "test"
  167. (should
  168. (string-match
  169. "\\`\\* Head1[ \t]+:archive:\n\\'"
  170. (org-export-as 'test nil nil nil '(:with-archived-trees t)))))))
  171. ;; Drawers.
  172. (let ((org-drawers '("TEST")))
  173. (org-test-with-temp-text ":TEST:\ncontents\n:END:"
  174. (org-test-with-backend "test"
  175. (should (equal (org-export-as 'test nil nil nil '(:with-drawers nil))
  176. "")))))
  177. (let ((org-drawers '("TEST")))
  178. (org-test-with-temp-text ":TEST:\ncontents\n:END:"
  179. (org-test-with-backend "test"
  180. (should (equal (org-export-as 'test nil nil nil '(:with-drawers t))
  181. ":TEST:\ncontents\n:END:\n"))))))
  182. (ert-deftest test-org-export/comment-tree ()
  183. "Test if export process ignores commented trees."
  184. (let ((org-comment-string "COMMENT"))
  185. (org-test-with-temp-text "* COMMENT Head1"
  186. (org-test-with-backend "test"
  187. (should (equal (org-export-as 'test) ""))))))
  188. (ert-deftest test-org-export/export-scope ()
  189. "Test all export scopes."
  190. (org-test-with-temp-text "
  191. * Head1
  192. ** Head2
  193. text
  194. *** Head3"
  195. (org-test-with-backend "test"
  196. ;; Subtree.
  197. (forward-line 3)
  198. (should (equal (org-export-as 'test 'subtree) "text\n*** Head3\n"))
  199. ;; Visible.
  200. (goto-char (point-min))
  201. (forward-line)
  202. (org-cycle)
  203. (should (equal (org-export-as 'test nil 'visible) "* Head1\n"))
  204. ;; Body only.
  205. (flet ((org-test-template (body info) (format "BEGIN\n%sEND" body)))
  206. (should (equal (org-export-as 'test nil nil 'body-only)
  207. "* Head1\n** Head2\ntext\n*** Head3\n"))
  208. (should (equal (org-export-as 'test)
  209. "BEGIN\n* Head1\n** Head2\ntext\n*** Head3\nEND")))
  210. ;; Region.
  211. (goto-char (point-min))
  212. (forward-line 3)
  213. (transient-mark-mode 1)
  214. (push-mark (point) t t)
  215. (goto-char (point-at-eol))
  216. (should (equal (org-export-as 'test) "text\n")))))
  217. (ert-deftest test-org-export/export-snippet ()
  218. "Test export snippets transcoding."
  219. (org-test-with-temp-text "@test{A}@t{B}"
  220. (org-test-with-backend "test"
  221. (flet ((org-test-export-snippet
  222. (snippet contents info)
  223. (when (eq (org-export-snippet-backend snippet) 'test)
  224. (org-element-property :value snippet))))
  225. (let ((org-export-snippet-translation-alist nil))
  226. (should (equal (org-export-as 'test) "A\n")))
  227. (let ((org-export-snippet-translation-alist '(("t" . "test"))))
  228. (should (equal (org-export-as 'test) "AB\n")))))))
  229. (ert-deftest test-org-export/expand-include ()
  230. "Test file inclusion in an Org buffer."
  231. ;; Full insertion with recursive inclusion.
  232. (org-test-with-temp-text
  233. (format "#+INCLUDE: \"%s/examples/include.org\"" org-test-dir)
  234. (org-export-expand-include-keyword)
  235. (should (equal (buffer-string)
  236. "Small Org file with an include keyword.
  237. #+BEGIN_SRC emacs-lisp :exports results\n(+ 2 1)\n#+END_SRC
  238. Success!
  239. * Heading
  240. body\n")))
  241. ;; Localized insertion.
  242. (org-test-with-temp-text
  243. (format "#+INCLUDE: \"%s/examples/include.org\" :lines \"1-2\""
  244. org-test-dir)
  245. (org-export-expand-include-keyword)
  246. (should (equal (buffer-string)
  247. "Small Org file with an include keyword.\n")))
  248. ;; Insertion with constraints on headlines level.
  249. (org-test-with-temp-text
  250. (format
  251. "* Top heading\n#+INCLUDE: \"%s/examples/include.org\" :lines \"9-\""
  252. org-test-dir)
  253. (org-export-expand-include-keyword)
  254. (should (equal (buffer-string) "* Top heading\n** Heading\nbody\n")))
  255. ;; Inclusion within an example block.
  256. (org-test-with-temp-text
  257. (format "#+INCLUDE: \"%s/examples/include.org\" :lines \"1-2\" example"
  258. org-test-dir)
  259. (org-export-expand-include-keyword)
  260. (should
  261. (equal
  262. (buffer-string)
  263. "#+BEGIN_EXAMPLE\nSmall Org file with an include keyword.\n#+END_EXAMPLE\n")))
  264. ;; Inclusion within a src-block.
  265. (org-test-with-temp-text
  266. (format
  267. "#+INCLUDE: \"%s/examples/include.org\" :lines \"4-5\" src emacs-lisp"
  268. org-test-dir)
  269. (org-export-expand-include-keyword)
  270. (should (equal (buffer-string)
  271. "#+BEGIN_SRC emacs-lisp\n(+ 2 1)\n#+END_SRC\n"))))
  272. (ert-deftest test-org-export/user-ignore-list ()
  273. "Test if `:ignore-list' accepts user input."
  274. (org-test-with-backend "test"
  275. (flet ((skip-note-head
  276. (data backend info)
  277. ;; Ignore headlines with the word "note" in their title.
  278. (org-element-map
  279. data 'headline
  280. (lambda (headline)
  281. (when (string-match "\\<note\\>"
  282. (org-element-property :raw-value headline))
  283. (org-export-ignore-element headline info)))
  284. info)
  285. data))
  286. ;; Install function in parse tree filters.
  287. (let ((org-export-filter-parse-tree-functions '(skip-note-head)))
  288. (org-test-with-temp-text "* Head1\n* Head2 (note)\n"
  289. (should (equal (org-export-as 'test) "* Head1\n")))))))
  290. ;; Footnotes
  291. (ert-deftest test-org-export/footnotes ()
  292. "Test footnotes specifications."
  293. (let ((org-footnote-section nil))
  294. ;; 1. Read every type of footnote.
  295. (org-test-with-temp-text
  296. "Text[fn:1] [1] [fn:label:C] [fn::D]\n\n[fn:1] A\n\n[1] B"
  297. (let* ((tree (org-element-parse-buffer))
  298. (info (org-combine-plists
  299. (org-export-initial-options) '(:with-footnotes t))))
  300. (setq info (org-combine-plists
  301. info (org-export-collect-tree-properties tree info 'test)))
  302. (should
  303. (equal
  304. '((1 . "A") (2 . "B") (3 . "C") (4 . "D"))
  305. (org-element-map
  306. tree 'footnote-reference
  307. (lambda (ref)
  308. (let ((def (org-export-get-footnote-definition ref info)))
  309. (cons (org-export-get-footnote-number ref info)
  310. (if (eq (org-element-property :type ref) 'inline) (car def)
  311. (car (org-element-contents
  312. (car (org-element-contents def))))))))
  313. info)))))
  314. ;; 2. Test nested footnotes order.
  315. (org-test-with-temp-text
  316. "Text[fn:1:A[fn:2]] [fn:3].\n\n[fn:2] B [fn:3] [fn::D].\n\n[fn:3] C."
  317. (let* ((tree (org-element-parse-buffer))
  318. (info (org-combine-plists
  319. (org-export-initial-options) '(:with-footnotes t))))
  320. (setq info (org-combine-plists
  321. info (org-export-collect-tree-properties tree info 'test)))
  322. (should
  323. (equal
  324. '((1 . "fn:1") (2 . "fn:2") (3 . "fn:3") (4))
  325. (org-element-map
  326. tree 'footnote-reference
  327. (lambda (ref)
  328. (when (org-export-footnote-first-reference-p ref info)
  329. (cons (org-export-get-footnote-number ref info)
  330. (org-element-property :label ref))))
  331. info)))))
  332. ;; 3. Test nested footnote in invisible definitions.
  333. (org-test-with-temp-text "Text[1]\n\n[1] B [2]\n\n[2] C."
  334. ;; Hide definitions.
  335. (narrow-to-region (point) (point-at-eol))
  336. (let* ((tree (org-element-parse-buffer))
  337. (info (org-combine-plists
  338. (org-export-initial-options) '(:with-footnotes t))))
  339. (setq info (org-combine-plists
  340. info (org-export-collect-tree-properties tree info 'test)))
  341. ;; Both footnotes should be seen.
  342. (should
  343. (= (length (org-export-collect-footnote-definitions tree info)) 2))))
  344. ;; 4. Test footnotes definitions collection.
  345. (org-test-with-temp-text "Text[fn:1:A[fn:2]] [fn:3].
  346. \[fn:2] B [fn:3] [fn::D].
  347. \[fn:3] C."
  348. (let ((tree (org-element-parse-buffer))
  349. (info (org-combine-plists
  350. (org-export-initial-options) '(:with-footnotes t))))
  351. (setq info (org-combine-plists
  352. info (org-export-collect-tree-properties tree info 'test)))
  353. (should (= (length (org-export-collect-footnote-definitions tree info))
  354. 4))))))
  355. ;;; Links
  356. (ert-deftest test-org-export/fuzzy-links ()
  357. "Test fuzz link export specifications."
  358. ;; 1. Links to invisible (keyword) targets should be ignored.
  359. (org-test-with-temp-text
  360. "Paragraph.\n#+TARGET: Test\n[[Test]]"
  361. (let* ((tree (org-element-parse-buffer))
  362. (info (org-combine-plists (org-export-initial-options))))
  363. (setq info (org-combine-plists
  364. info (org-export-collect-tree-properties tree info 'test)))
  365. (should-not
  366. (org-element-map
  367. tree 'link
  368. (lambda (link)
  369. (org-export-get-ordinal
  370. (org-export-resolve-fuzzy-link link info) info)) info))))
  371. ;; 2. Link to an headline should return headline's number.
  372. (org-test-with-temp-text
  373. "Paragraph.\n* Head1\n* Head2\n* Head3\n[[Head2]]"
  374. (let* ((tree (org-element-parse-buffer))
  375. (info (org-combine-plists (org-export-initial-options))))
  376. (setq info (org-combine-plists
  377. info (org-export-collect-tree-properties tree info 'test)))
  378. (should
  379. ;; Note: Headline's number is in fact a list of numbers.
  380. (equal '(2)
  381. (org-element-map
  382. tree 'link
  383. (lambda (link)
  384. (org-export-get-ordinal
  385. (org-export-resolve-fuzzy-link link info) info)) info t)))))
  386. ;; 3. Link to a target in an item should return item's number.
  387. (org-test-with-temp-text
  388. "- Item1\n - Item11\n - <<test>>Item12\n- Item2\n\n\n[[test]]"
  389. (let* ((tree (org-element-parse-buffer))
  390. (info (org-combine-plists (org-export-initial-options))))
  391. (setq info (org-combine-plists
  392. info (org-export-collect-tree-properties tree info 'test)))
  393. (should
  394. ;; Note: Item's number is in fact a list of numbers.
  395. (equal '(1 2)
  396. (org-element-map
  397. tree 'link
  398. (lambda (link)
  399. (org-export-get-ordinal
  400. (org-export-resolve-fuzzy-link link info) info)) info t)))))
  401. ;; 4. Link to a target in a footnote should return footnote's
  402. ;; number.
  403. (org-test-with-temp-text
  404. "Paragraph[1][2][fn:lbl3:C<<target>>][[test]][[target]]\n[1] A\n\n[2] <<test>>B"
  405. (let* ((tree (org-element-parse-buffer))
  406. (info (org-combine-plists (org-export-initial-options))))
  407. (setq info (org-combine-plists
  408. info (org-export-collect-tree-properties tree info 'test)))
  409. (should
  410. (equal '(2 3)
  411. (org-element-map
  412. tree 'link
  413. (lambda (link)
  414. (org-export-get-ordinal
  415. (org-export-resolve-fuzzy-link link info) info)) info)))))
  416. ;; 5. Link to a named element should return sequence number of that
  417. ;; element.
  418. (org-test-with-temp-text
  419. "#+NAME: tbl1\n|1|2|\n#+NAME: tbl2\n|3|4|\n#+NAME: tbl3\n|5|6|\n[[tbl2]]"
  420. (let* ((tree (org-element-parse-buffer))
  421. (info (org-combine-plists (org-export-initial-options))))
  422. (setq info (org-combine-plists
  423. info (org-export-collect-tree-properties tree info 'test)))
  424. (should
  425. (= 2
  426. (org-element-map
  427. tree 'link
  428. (lambda (link)
  429. (org-export-get-ordinal
  430. (org-export-resolve-fuzzy-link link info) info)) info t)))))
  431. ;; 6. Link to a target not within an item, a table, a footnote
  432. ;; reference or definition should return section number.
  433. (org-test-with-temp-text
  434. "* Head1\n* Head2\nParagraph<<target>>\n* Head3\n[[target]]"
  435. (let* ((tree (org-element-parse-buffer))
  436. (info (org-combine-plists (org-export-initial-options))))
  437. (setq info (org-combine-plists
  438. info (org-export-collect-tree-properties tree info 'test)))
  439. (should
  440. (equal '(2)
  441. (org-element-map
  442. tree 'link
  443. (lambda (link)
  444. (org-export-get-ordinal
  445. (org-export-resolve-fuzzy-link link info) info)) info t))))))
  446. (defun test-org-export/resolve-coderef ()
  447. "Test `org-export-resolve-coderef' specifications."
  448. (let ((org-coderef-label-format "(ref:%s)"))
  449. ;; 1. A link to a "-n -k -r" block returns line number.
  450. (org-test-with-temp-text
  451. "#+BEGIN_EXAMPLE -n -k -r\nText (ref:coderef)\n#+END_EXAMPLE"
  452. (let ((tree (org-element-parse-buffer)))
  453. (should
  454. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  455. (org-test-with-temp-text
  456. "#+BEGIN_SRC emacs-lisp -n -k -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  457. (let ((tree (org-element-parse-buffer)))
  458. (should
  459. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  460. ;; 2. A link to a "-n -r" block returns line number.
  461. (org-test-with-temp-text
  462. "#+BEGIN_EXAMPLE -n -r\nText (ref:coderef)\n#+END_EXAMPLE"
  463. (let ((tree (org-element-parse-buffer)))
  464. (should
  465. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  466. (org-test-with-temp-text
  467. "#+BEGIN_SRC emacs-lisp -n -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  468. (let ((tree (org-element-parse-buffer)))
  469. (should
  470. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  471. ;; 3. A link to a "-n" block returns coderef.
  472. (org-test-with-temp-text
  473. "#+BEGIN_SRC emacs-lisp -n\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  474. (let ((tree (org-element-parse-buffer)))
  475. (should
  476. (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
  477. "coderef"))))
  478. (org-test-with-temp-text
  479. "#+BEGIN_EXAMPLE -n\nText (ref:coderef)\n#+END_EXAMPLE"
  480. (let ((tree (org-element-parse-buffer)))
  481. (should
  482. (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
  483. "coderef"))))
  484. ;; 4. A link to a "-r" block returns line number.
  485. (org-test-with-temp-text
  486. "#+BEGIN_SRC emacs-lisp -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  487. (let ((tree (org-element-parse-buffer)))
  488. (should
  489. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  490. (org-test-with-temp-text
  491. "#+BEGIN_EXAMPLE -r\nText (ref:coderef)\n#+END_EXAMPLE"
  492. (let ((tree (org-element-parse-buffer)))
  493. (should
  494. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  495. ;; 5. A link to a block without a switch returns coderef.
  496. (org-test-with-temp-text
  497. "#+BEGIN_SRC emacs-lisp\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  498. (let ((tree (org-element-parse-buffer)))
  499. (should
  500. (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
  501. "coderef"))))
  502. (org-test-with-temp-text
  503. "#+BEGIN_EXAMPLE\nText (ref:coderef)\n#+END_EXAMPLE"
  504. (let ((tree (org-element-parse-buffer)))
  505. (should
  506. (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
  507. "coderef"))))
  508. ;; 6. Correctly handle continued line numbers. A "+n" switch
  509. ;; should resume numbering from previous block with numbered
  510. ;; lines, ignoring blocks not numbering lines in the process.
  511. ;; A "-n" switch resets count.
  512. (org-test-with-temp-text "
  513. #+BEGIN_EXAMPLE -n
  514. Text.
  515. #+END_EXAMPLE
  516. #+BEGIN_SRC emacs-lisp
  517. \(- 1 1)
  518. #+END_SRC
  519. #+BEGIN_SRC emacs-lisp +n -r
  520. \(+ 1 1) (ref:addition)
  521. #+END_SRC
  522. #+BEGIN_EXAMPLE -n -r
  523. Another text. (ref:text)
  524. #+END_EXAMPLE"
  525. (let* ((tree (org-element-parse-buffer))
  526. (info `(:parse-tree ,tree)))
  527. (should (= (org-export-resolve-coderef "addition" info) 2))
  528. (should (= (org-export-resolve-coderef "text" info) 1))))
  529. ;; 7. Recognize coderef with user-specified syntax.
  530. (org-test-with-temp-text
  531. "#+BEGIN_EXAMPLE -l \"[ref:%s]\"\nText. [ref:text]\n#+END_EXAMPLE"
  532. (let ((tree (org-element-parse-buffer)))
  533. (should (equal (org-export-resolve-coderef "text" `(:parse-tree ,tree))
  534. "text"))))))
  535. ;;; Src-block and example-block
  536. (ert-deftest test-org-export/unravel-code ()
  537. "Test `org-export-unravel-code' function."
  538. (let ((org-coderef-label-format "(ref:%s)"))
  539. ;; 1. Code without reference.
  540. (org-test-with-temp-text "#+BEGIN_EXAMPLE\n(+ 1 1)\n#+END_EXAMPLE"
  541. (should (equal (org-export-unravel-code (org-element-current-element))
  542. '("(+ 1 1)\n"))))
  543. ;; 2. Code with reference.
  544. (org-test-with-temp-text
  545. "#+BEGIN_EXAMPLE\n(+ 1 1) (ref:test)\n#+END_EXAMPLE"
  546. (should (equal (org-export-unravel-code (org-element-current-element))
  547. '("(+ 1 1)\n" (1 . "test")))))
  548. ;; 3. Code with user-defined reference.
  549. (org-test-with-temp-text
  550. "#+BEGIN_EXAMPLE -l \"[ref:%s]\"\n(+ 1 1) [ref:test]\n#+END_EXAMPLE"
  551. (should (equal (org-export-unravel-code (org-element-current-element))
  552. '("(+ 1 1)\n" (1 . "test")))))
  553. ;; 4. Code references keys are relative to the current block.
  554. (org-test-with-temp-text "
  555. #+BEGIN_EXAMPLE -n
  556. \(+ 1 1)
  557. #+END_EXAMPLE
  558. #+BEGIN_EXAMPLE +n
  559. \(+ 2 2)
  560. \(+ 3 3) (ref:one)
  561. #+END_EXAMPLE"
  562. (goto-line 5)
  563. (should (equal (org-export-unravel-code (org-element-current-element))
  564. '("(+ 2 2)\n(+ 3 3)\n" (2 . "one")))))
  565. ;; 5. Free up comma-protected lines.
  566. ;;
  567. ;; 5.1. In an Org source block, every line is protected.
  568. (org-test-with-temp-text
  569. "#+BEGIN_SRC org\n,* Test\n,# comment\n,Text\n#+END_SRC"
  570. (should (equal (org-export-unravel-code (org-element-current-element))
  571. '("* Test\n# comment\nText\n"))))
  572. ;; 5.2. In other blocks, only headlines, comments and keywords are
  573. ;; protected.
  574. (org-test-with-temp-text
  575. "#+BEGIN_EXAMPLE\n,* Headline\n, * Not headline\n,Keep\n#+END_EXAMPLE"
  576. (should (equal (org-export-unravel-code (org-element-current-element))
  577. '("* Headline\n, * Not headline\n,Keep\n"))))))
  578. (provide 'test-org-export)
  579. ;;; test-org-export.el end here