test-org-export.el 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  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. ;; Subtree with a code block calling another block outside.
  218. (org-test-with-temp-text "
  219. * Head1
  220. #+BEGIN_SRC emacs-lisp :noweb yes :exports results
  221. <<test>>
  222. #+END_SRC
  223. * Head2
  224. #+NAME: test
  225. #+BEGIN_SRC emacs-lisp
  226. \(+ 1 2)
  227. #+END_SRC"
  228. (org-test-with-backend "test"
  229. (forward-line 1)
  230. (should (equal (org-export-as 'test 'subtree) ": 3\n")))))
  231. (ert-deftest test-org-export/export-snippet ()
  232. "Test export snippets transcoding."
  233. (org-test-with-temp-text "@test{A}@t{B}"
  234. (org-test-with-backend "test"
  235. (flet ((org-test-export-snippet
  236. (snippet contents info)
  237. (when (eq (org-export-snippet-backend snippet) 'test)
  238. (org-element-property :value snippet))))
  239. (let ((org-export-snippet-translation-alist nil))
  240. (should (equal (org-export-as 'test) "A\n")))
  241. (let ((org-export-snippet-translation-alist '(("t" . "test"))))
  242. (should (equal (org-export-as 'test) "AB\n")))))))
  243. (ert-deftest test-org-export/expand-include ()
  244. "Test file inclusion in an Org buffer."
  245. ;; Full insertion with recursive inclusion.
  246. (org-test-with-temp-text
  247. (format "#+INCLUDE: \"%s/examples/include.org\"" org-test-dir)
  248. (org-export-expand-include-keyword)
  249. (should (equal (buffer-string)
  250. "Small Org file with an include keyword.
  251. #+BEGIN_SRC emacs-lisp :exports results\n(+ 2 1)\n#+END_SRC
  252. Success!
  253. * Heading
  254. body\n")))
  255. ;; Localized insertion.
  256. (org-test-with-temp-text
  257. (format "#+INCLUDE: \"%s/examples/include.org\" :lines \"1-2\""
  258. org-test-dir)
  259. (org-export-expand-include-keyword)
  260. (should (equal (buffer-string)
  261. "Small Org file with an include keyword.\n")))
  262. ;; Insertion with constraints on headlines level.
  263. (org-test-with-temp-text
  264. (format
  265. "* Top heading\n#+INCLUDE: \"%s/examples/include.org\" :lines \"9-\""
  266. org-test-dir)
  267. (org-export-expand-include-keyword)
  268. (should (equal (buffer-string) "* Top heading\n** Heading\nbody\n")))
  269. ;; Inclusion within an example block.
  270. (org-test-with-temp-text
  271. (format "#+INCLUDE: \"%s/examples/include.org\" :lines \"1-2\" example"
  272. org-test-dir)
  273. (org-export-expand-include-keyword)
  274. (should
  275. (equal
  276. (buffer-string)
  277. "#+BEGIN_EXAMPLE\nSmall Org file with an include keyword.\n#+END_EXAMPLE\n")))
  278. ;; Inclusion within a src-block.
  279. (org-test-with-temp-text
  280. (format
  281. "#+INCLUDE: \"%s/examples/include.org\" :lines \"4-5\" src emacs-lisp"
  282. org-test-dir)
  283. (org-export-expand-include-keyword)
  284. (should (equal (buffer-string)
  285. "#+BEGIN_SRC emacs-lisp\n(+ 2 1)\n#+END_SRC\n"))))
  286. (ert-deftest test-org-export/user-ignore-list ()
  287. "Test if `:ignore-list' accepts user input."
  288. (org-test-with-backend "test"
  289. (flet ((skip-note-head
  290. (data backend info)
  291. ;; Ignore headlines with the word "note" in their title.
  292. (org-element-map
  293. data 'headline
  294. (lambda (headline)
  295. (when (string-match "\\<note\\>"
  296. (org-element-property :raw-value headline))
  297. (org-export-ignore-element headline info)))
  298. info)
  299. data))
  300. ;; Install function in parse tree filters.
  301. (let ((org-export-filter-parse-tree-functions '(skip-note-head)))
  302. (org-test-with-temp-text "* Head1\n* Head2 (note)\n"
  303. (should (equal (org-export-as 'test) "* Head1\n")))))))
  304. ;; Footnotes
  305. (ert-deftest test-org-export/footnotes ()
  306. "Test footnotes specifications."
  307. (let ((org-footnote-section nil))
  308. ;; 1. Read every type of footnote.
  309. (org-test-with-temp-text
  310. "Text[fn:1] [1] [fn:label:C] [fn::D]\n\n[fn:1] A\n\n[1] B"
  311. (let* ((tree (org-element-parse-buffer))
  312. (info (org-export-store-footnote-definitions
  313. `(:parse-tree ,tree :with-footnotes t))))
  314. (should
  315. (equal
  316. '((1 . "A") (2 . "B") (3 . "C") (4 . "D"))
  317. (org-element-map
  318. tree 'footnote-reference
  319. (lambda (ref)
  320. (let ((def (org-export-get-footnote-definition ref info)))
  321. (cons (org-export-get-footnote-number ref info)
  322. (if (eq (org-element-property :type ref) 'inline) (car def)
  323. (car (org-element-contents
  324. (car (org-element-contents def))))))))
  325. info)))))
  326. ;; 2. Test nested footnotes order.
  327. (org-test-with-temp-text
  328. "Text[fn:1:A[fn:2]] [fn:3].\n\n[fn:2] B [fn:3] [fn::D].\n\n[fn:3] C."
  329. (let* ((tree (org-element-parse-buffer))
  330. (info (org-export-store-footnote-definitions
  331. `(:parse-tree ,tree :with-footnotes t))))
  332. (should
  333. (equal
  334. '((1 . "fn:1") (2 . "fn:2") (3 . "fn:3") (4))
  335. (org-element-map
  336. tree 'footnote-reference
  337. (lambda (ref)
  338. (when (org-export-footnote-first-reference-p ref info)
  339. (cons (org-export-get-footnote-number ref info)
  340. (org-element-property :label ref))))
  341. info)))))
  342. ;; 3. Test nested footnote in invisible definitions.
  343. (org-test-with-temp-text "Text[1]\n\n[1] B [2]\n\n[2] C."
  344. ;; Hide definitions.
  345. (narrow-to-region (point) (point-at-eol))
  346. (let* ((tree (org-element-parse-buffer))
  347. (info (org-export-store-footnote-definitions
  348. `(:parse-tree ,tree :with-footnotes t))))
  349. ;; Both footnotes should be seen.
  350. (should
  351. (= (length (org-export-collect-footnote-definitions tree info)) 2))))
  352. ;; 4. Test footnotes definitions collection.
  353. (org-test-with-temp-text "Text[fn:1:A[fn:2]] [fn:3].
  354. \[fn:2] B [fn:3] [fn::D].
  355. \[fn:3] C."
  356. (let* ((tree (org-element-parse-buffer))
  357. (info (org-export-store-footnote-definitions
  358. `(:parse-tree ,tree :with-footnotes t))))
  359. (should (= (length (org-export-collect-footnote-definitions tree info))
  360. 4))))
  361. ;; 5. Test export of footnotes defined outside parsing scope.
  362. (org-test-with-temp-text "[fn:1] Out of scope
  363. * Title
  364. Paragraph[fn:1]"
  365. (org-test-with-backend "test"
  366. (flet ((org-test-footnote-reference
  367. (fn-ref contents info)
  368. (org-element-interpret-data
  369. (org-export-get-footnote-definition fn-ref info))))
  370. (forward-line)
  371. (should (equal "ParagraphOut of scope\n"
  372. (org-export-as 'test 'subtree))))))))
  373. ;;; Links
  374. (ert-deftest test-org-export/fuzzy-links ()
  375. "Test fuzzy link export specifications."
  376. ;; 1. Links to invisible (keyword) targets should be ignored.
  377. (org-test-with-temp-text
  378. "Paragraph.\n#+TARGET: Test\n[[Test]]"
  379. (let* ((tree (org-element-parse-buffer))
  380. (info (org-export-collect-tree-properties tree nil 'test)))
  381. (should-not
  382. (org-element-map
  383. tree 'link
  384. (lambda (link)
  385. (org-export-get-ordinal
  386. (org-export-resolve-fuzzy-link link info) info)) info))))
  387. ;; 2. Link to an headline should return headline's number.
  388. (org-test-with-temp-text
  389. "Paragraph.\n* Head1\n* Head2\n* Head3\n[[Head2]]"
  390. (let* ((tree (org-element-parse-buffer))
  391. (info (org-export-collect-tree-properties tree nil 'test)))
  392. (should
  393. ;; Note: Headline's number is in fact a list of numbers.
  394. (equal '(2)
  395. (org-element-map
  396. tree 'link
  397. (lambda (link)
  398. (org-export-get-ordinal
  399. (org-export-resolve-fuzzy-link link info) info)) info t)))))
  400. ;; 3. Link to a target in an item should return item's number.
  401. (org-test-with-temp-text
  402. "- Item1\n - Item11\n - <<test>>Item12\n- Item2\n\n\n[[test]]"
  403. (let* ((tree (org-element-parse-buffer))
  404. (info (org-export-collect-tree-properties tree nil 'test)))
  405. (should
  406. ;; Note: Item's number is in fact a list of numbers.
  407. (equal '(1 2)
  408. (org-element-map
  409. tree 'link
  410. (lambda (link)
  411. (org-export-get-ordinal
  412. (org-export-resolve-fuzzy-link link info) info)) info t)))))
  413. ;; 4. Link to a target in a footnote should return footnote's
  414. ;; number.
  415. (org-test-with-temp-text
  416. "Paragraph[1][2][fn:lbl3:C<<target>>][[test]][[target]]\n[1] A\n\n[2] <<test>>B"
  417. (let* ((tree (org-element-parse-buffer))
  418. (info (org-export-collect-tree-properties tree nil 'test)))
  419. (should
  420. (equal '(2 3)
  421. (org-element-map
  422. tree 'link
  423. (lambda (link)
  424. (org-export-get-ordinal
  425. (org-export-resolve-fuzzy-link link info) info)) info)))))
  426. ;; 5. Link to a named element should return sequence number of that
  427. ;; element.
  428. (org-test-with-temp-text
  429. "#+NAME: tbl1\n|1|2|\n#+NAME: tbl2\n|3|4|\n#+NAME: tbl3\n|5|6|\n[[tbl2]]"
  430. (let* ((tree (org-element-parse-buffer))
  431. (info (org-export-collect-tree-properties tree nil 'test)))
  432. (should
  433. (= 2
  434. (org-element-map
  435. tree 'link
  436. (lambda (link)
  437. (org-export-get-ordinal
  438. (org-export-resolve-fuzzy-link link info) info)) info t)))))
  439. ;; 6. Link to a target not within an item, a table, a footnote
  440. ;; reference or definition should return section number.
  441. (org-test-with-temp-text
  442. "* Head1\n* Head2\nParagraph<<target>>\n* Head3\n[[target]]"
  443. (let* ((tree (org-element-parse-buffer))
  444. (info (org-export-collect-tree-properties tree nil 'test)))
  445. (should
  446. (equal '(2)
  447. (org-element-map
  448. tree 'link
  449. (lambda (link)
  450. (org-export-get-ordinal
  451. (org-export-resolve-fuzzy-link link info) info)) info t))))))
  452. (defun test-org-export/resolve-coderef ()
  453. "Test `org-export-resolve-coderef' specifications."
  454. (let ((org-coderef-label-format "(ref:%s)"))
  455. ;; 1. A link to a "-n -k -r" block returns line number.
  456. (org-test-with-temp-text
  457. "#+BEGIN_EXAMPLE -n -k -r\nText (ref:coderef)\n#+END_EXAMPLE"
  458. (let ((tree (org-element-parse-buffer)))
  459. (should
  460. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  461. (org-test-with-temp-text
  462. "#+BEGIN_SRC emacs-lisp -n -k -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  463. (let ((tree (org-element-parse-buffer)))
  464. (should
  465. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  466. ;; 2. A link to a "-n -r" block returns line number.
  467. (org-test-with-temp-text
  468. "#+BEGIN_EXAMPLE -n -r\nText (ref:coderef)\n#+END_EXAMPLE"
  469. (let ((tree (org-element-parse-buffer)))
  470. (should
  471. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  472. (org-test-with-temp-text
  473. "#+BEGIN_SRC emacs-lisp -n -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  474. (let ((tree (org-element-parse-buffer)))
  475. (should
  476. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  477. ;; 3. A link to a "-n" block returns coderef.
  478. (org-test-with-temp-text
  479. "#+BEGIN_SRC emacs-lisp -n\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  480. (let ((tree (org-element-parse-buffer)))
  481. (should
  482. (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
  483. "coderef"))))
  484. (org-test-with-temp-text
  485. "#+BEGIN_EXAMPLE -n\nText (ref:coderef)\n#+END_EXAMPLE"
  486. (let ((tree (org-element-parse-buffer)))
  487. (should
  488. (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
  489. "coderef"))))
  490. ;; 4. A link to a "-r" block returns line number.
  491. (org-test-with-temp-text
  492. "#+BEGIN_SRC emacs-lisp -r\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  493. (let ((tree (org-element-parse-buffer)))
  494. (should
  495. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  496. (org-test-with-temp-text
  497. "#+BEGIN_EXAMPLE -r\nText (ref:coderef)\n#+END_EXAMPLE"
  498. (let ((tree (org-element-parse-buffer)))
  499. (should
  500. (= (org-export-resolve-coderef "coderef" `(:parse-tree ,tree)) 1))))
  501. ;; 5. A link to a block without a switch returns coderef.
  502. (org-test-with-temp-text
  503. "#+BEGIN_SRC emacs-lisp\n(+ 1 1) (ref:coderef)\n#+END_SRC"
  504. (let ((tree (org-element-parse-buffer)))
  505. (should
  506. (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
  507. "coderef"))))
  508. (org-test-with-temp-text
  509. "#+BEGIN_EXAMPLE\nText (ref:coderef)\n#+END_EXAMPLE"
  510. (let ((tree (org-element-parse-buffer)))
  511. (should
  512. (equal (org-export-resolve-coderef "coderef" `(:parse-tree ,tree))
  513. "coderef"))))
  514. ;; 6. Correctly handle continued line numbers. A "+n" switch
  515. ;; should resume numbering from previous block with numbered
  516. ;; lines, ignoring blocks not numbering lines in the process.
  517. ;; A "-n" switch resets count.
  518. (org-test-with-temp-text "
  519. #+BEGIN_EXAMPLE -n
  520. Text.
  521. #+END_EXAMPLE
  522. #+BEGIN_SRC emacs-lisp
  523. \(- 1 1)
  524. #+END_SRC
  525. #+BEGIN_SRC emacs-lisp +n -r
  526. \(+ 1 1) (ref:addition)
  527. #+END_SRC
  528. #+BEGIN_EXAMPLE -n -r
  529. Another text. (ref:text)
  530. #+END_EXAMPLE"
  531. (let* ((tree (org-element-parse-buffer))
  532. (info `(:parse-tree ,tree)))
  533. (should (= (org-export-resolve-coderef "addition" info) 2))
  534. (should (= (org-export-resolve-coderef "text" info) 1))))
  535. ;; 7. Recognize coderef with user-specified syntax.
  536. (org-test-with-temp-text
  537. "#+BEGIN_EXAMPLE -l \"[ref:%s]\"\nText. [ref:text]\n#+END_EXAMPLE"
  538. (let ((tree (org-element-parse-buffer)))
  539. (should (equal (org-export-resolve-coderef "text" `(:parse-tree ,tree))
  540. "text"))))))
  541. ;;; Src-block and example-block
  542. (ert-deftest test-org-export/unravel-code ()
  543. "Test `org-export-unravel-code' function."
  544. (let ((org-coderef-label-format "(ref:%s)"))
  545. ;; 1. Code without reference.
  546. (org-test-with-temp-text "#+BEGIN_EXAMPLE\n(+ 1 1)\n#+END_EXAMPLE"
  547. (should (equal (org-export-unravel-code (org-element-current-element))
  548. '("(+ 1 1)\n"))))
  549. ;; 2. Code with reference.
  550. (org-test-with-temp-text
  551. "#+BEGIN_EXAMPLE\n(+ 1 1) (ref:test)\n#+END_EXAMPLE"
  552. (should (equal (org-export-unravel-code (org-element-current-element))
  553. '("(+ 1 1)\n" (1 . "test")))))
  554. ;; 3. Code with user-defined reference.
  555. (org-test-with-temp-text
  556. "#+BEGIN_EXAMPLE -l \"[ref:%s]\"\n(+ 1 1) [ref:test]\n#+END_EXAMPLE"
  557. (should (equal (org-export-unravel-code (org-element-current-element))
  558. '("(+ 1 1)\n" (1 . "test")))))
  559. ;; 4. Code references keys are relative to the current block.
  560. (org-test-with-temp-text "
  561. #+BEGIN_EXAMPLE -n
  562. \(+ 1 1)
  563. #+END_EXAMPLE
  564. #+BEGIN_EXAMPLE +n
  565. \(+ 2 2)
  566. \(+ 3 3) (ref:one)
  567. #+END_EXAMPLE"
  568. (goto-line 5)
  569. (should (equal (org-export-unravel-code (org-element-current-element))
  570. '("(+ 2 2)\n(+ 3 3)\n" (2 . "one")))))
  571. ;; 5. Free up comma-protected lines.
  572. ;;
  573. ;; 5.1. In an Org source block, every line is protected.
  574. (org-test-with-temp-text
  575. "#+BEGIN_SRC org\n,* Test\n,# comment\n,Text\n#+END_SRC"
  576. (should (equal (org-export-unravel-code (org-element-current-element))
  577. '("* Test\n# comment\nText\n"))))
  578. ;; 5.2. In other blocks, only headlines, comments and keywords are
  579. ;; protected.
  580. (org-test-with-temp-text
  581. "#+BEGIN_EXAMPLE\n,* Headline\n, * Not headline\n,Keep\n#+END_EXAMPLE"
  582. (should (equal (org-export-unravel-code (org-element-current-element))
  583. '("* Headline\n, * Not headline\n,Keep\n"))))))
  584. (provide 'test-org-export)
  585. ;;; test-org-export.el end here