reftex-parse.el 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139
  1. ;;; reftex-parse.el --- parser functions for RefTeX
  2. ;; Copyright (C) 1997-2017 Free Software Foundation, Inc.
  3. ;; Author: Carsten Dominik <dominik@science.uva.nl>
  4. ;; Maintainer: auctex-devel@gnu.org
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;;; Code:
  18. (eval-when-compile (require 'cl-lib))
  19. (require 'reftex)
  20. (defmacro reftex-with-special-syntax (&rest body)
  21. `(let ((saved-syntax (syntax-table)))
  22. (unwind-protect
  23. (progn
  24. (set-syntax-table reftex-syntax-table)
  25. (let ((case-fold-search nil))
  26. ,@body))
  27. (set-syntax-table saved-syntax))))
  28. ;;;###autoload
  29. (defun reftex-parse-one ()
  30. "Re-parse this file."
  31. (interactive)
  32. (let ((reftex-enable-partial-scans t))
  33. (reftex-access-scan-info '(4))))
  34. ;;;###autoload
  35. (defun reftex-parse-all ()
  36. "Re-parse entire document."
  37. (interactive)
  38. (reftex-access-scan-info '(16)))
  39. (defvar reftex--index-tags)
  40. ;;;###autoload
  41. (defun reftex-do-parse (rescan &optional file)
  42. "Do a document rescan.
  43. When allowed, do only a partial scan from FILE."
  44. ;; Normalize the rescan argument
  45. (setq rescan (cond ((eq rescan t) t)
  46. ((eq rescan 1) 1)
  47. ((equal rescan '(4)) t)
  48. ((equal rescan '(16)) 1)
  49. (t 1)))
  50. ;; Partial scans only when allowed
  51. (unless reftex-enable-partial-scans
  52. (setq rescan 1))
  53. ;; Do the scanning.
  54. (let* ((old-list (symbol-value reftex-docstruct-symbol))
  55. (master (reftex-TeX-master-file))
  56. (true-master (file-truename master))
  57. (master-dir (file-name-as-directory (file-name-directory master)))
  58. (file (or file (buffer-file-name)))
  59. (true-file (file-truename file))
  60. (bibview-cache (assq 'bibview-cache old-list))
  61. (reftex--index-tags (cdr (assq 'index-tags old-list)))
  62. from-file appendix docstruct tmp)
  63. ;; Make sure replacement is really an option here
  64. (when (and (eq rescan t)
  65. (not (and (member (list 'bof file) old-list)
  66. (member (list 'eof file) old-list))))
  67. ;; Scan whole document because no such file section exists
  68. (setq rescan 1))
  69. (when (string= true-file true-master)
  70. ;; Scan whole document because this file is the master
  71. (setq rescan 1))
  72. ;; From which file do we start?
  73. (setq from-file
  74. (cond ((eq rescan t) (or file master))
  75. ((eq rescan 1) master)
  76. (t (error "This should not happen (reftex-do-parse)"))))
  77. ;; Reset index-tags if we scan everything
  78. (if (equal rescan 1) (setq reftex--index-tags nil))
  79. ;; Find active toc entry and initialize section-numbers
  80. (setq reftex-active-toc (reftex-last-assoc-before-elt
  81. 'toc (list 'bof from-file) old-list)
  82. appendix (reftex-last-assoc-before-elt
  83. 'appendix (list 'bof from-file) old-list))
  84. (reftex-init-section-numbers reftex-active-toc appendix)
  85. (if (eq rescan 1)
  86. (message "Scanning entire document...")
  87. (message "Scanning document from %s..." from-file))
  88. (reftex-with-special-syntax
  89. (save-window-excursion
  90. (save-excursion
  91. (unwind-protect
  92. (setq docstruct
  93. (reftex-parse-from-file
  94. from-file docstruct master-dir))
  95. (reftex-kill-temporary-buffers)))))
  96. (message "Scanning document... done")
  97. ;; Turn the list around.
  98. (setq docstruct (nreverse docstruct))
  99. ;; Set or insert
  100. (setq docstruct (reftex-replace-label-list-segment
  101. old-list docstruct (eq rescan 1)))
  102. ;; Add all missing information
  103. (unless (assq 'label-numbers docstruct)
  104. (push (cons 'label-numbers nil) docstruct))
  105. (unless (assq 'master-dir docstruct)
  106. (push (cons 'master-dir master-dir) docstruct))
  107. (unless (assq 'bibview-cache docstruct)
  108. (push (cons 'bibview-cache (cdr bibview-cache)) docstruct))
  109. (let* ((bof1 (memq (assq 'bof docstruct) docstruct))
  110. (bof2 (assq 'bof (cdr bof1)))
  111. (is-multi (not (not (and bof1 bof2))))
  112. (entry (or (assq 'is-multi docstruct)
  113. (car (push (list 'is-multi is-multi) docstruct)))))
  114. (setcdr entry (cons is-multi nil)))
  115. (and reftex--index-tags
  116. (setq reftex--index-tags (sort reftex--index-tags 'string<)))
  117. (let ((index-tag-cell (assq 'index-tags docstruct)))
  118. (if index-tag-cell
  119. (setcdr index-tag-cell reftex--index-tags)
  120. (push (cons 'index-tags reftex--index-tags) docstruct)))
  121. (unless (assq 'xr docstruct)
  122. (let* ((allxr (reftex-all-assq 'xr-doc docstruct))
  123. (alist (mapcar
  124. (lambda (x)
  125. (if (setq tmp (reftex-locate-file (nth 2 x) "tex"
  126. master-dir))
  127. (cons (nth 1 x) tmp)
  128. (message "Can't find external document %s"
  129. (nth 2 x))
  130. nil))
  131. allxr))
  132. (alist (delq nil alist))
  133. (allprefix (delq nil (mapcar 'car alist)))
  134. (regexp (if allprefix
  135. (concat "\\`\\("
  136. (mapconcat 'identity allprefix "\\|")
  137. "\\)")
  138. "\\\\\\\\\\\\"))) ; this will never match
  139. (push (list 'xr alist regexp) docstruct)))
  140. (set reftex-docstruct-symbol docstruct)
  141. (put reftex-docstruct-symbol 'modified t)))
  142. ;;;###autoload
  143. (defun reftex-everything-regexp ()
  144. (if reftex-support-index
  145. reftex-everything-regexp
  146. reftex-everything-regexp-no-index))
  147. ;; NB this is a global autoload - see reftex.el.
  148. ;;;###autoload
  149. (defun reftex-all-document-files (&optional relative)
  150. "Return a list of all files belonging to the current document.
  151. When RELATIVE is non-nil, give file names relative to directory
  152. of master file."
  153. (let* ((all (symbol-value reftex-docstruct-symbol))
  154. (master-dir (file-name-directory (reftex-TeX-master-file)))
  155. (re (concat "\\`" (regexp-quote master-dir)))
  156. file-list tmp file)
  157. (while (setq tmp (assoc 'bof all))
  158. (setq file (nth 1 tmp)
  159. all (cdr (memq tmp all)))
  160. (and relative
  161. (string-match re file)
  162. (setq file (substring file (match-end 0))))
  163. (push file file-list))
  164. (nreverse file-list)))
  165. ;; Bound in the caller, reftex-do-parse.
  166. (defun reftex-parse-from-file (file docstruct master-dir)
  167. "Scan the buffer for labels and save them in a list."
  168. (let ((regexp (reftex-everything-regexp))
  169. (bound 0)
  170. file-found tmp include-file
  171. (level 1)
  172. (highest-level 100)
  173. toc-entry index-entry next-buf buf)
  174. (catch 'exit
  175. (setq file-found (reftex-locate-file file "tex" master-dir))
  176. (if (and (not file-found)
  177. (setq buf (reftex-get-buffer-visiting file)))
  178. (setq file-found (buffer-file-name buf)))
  179. (unless file-found
  180. (push (list 'file-error file) docstruct)
  181. (throw 'exit nil))
  182. (save-excursion
  183. (message "Scanning file %s" file)
  184. (set-buffer
  185. (setq next-buf
  186. (reftex-get-file-buffer-force
  187. file-found
  188. (not (eq t reftex-keep-temporary-buffers)))))
  189. ;; Begin of file mark
  190. (setq file (buffer-file-name))
  191. (push (list 'bof file) docstruct)
  192. (reftex-with-special-syntax
  193. (save-excursion
  194. (save-restriction
  195. (widen)
  196. (goto-char 1)
  197. (while (re-search-forward regexp nil t)
  198. (cond
  199. ((match-end 1)
  200. ;; It is a label
  201. (when (or (null reftex-label-ignored-macros-and-environments)
  202. ;; \label{} defs should always be honored,
  203. ;; just no keyval style [label=foo] defs.
  204. (string-equal "\\label{" (substring (reftex-match-string 0) 0 7))
  205. (if (and (fboundp 'TeX-current-macro)
  206. (fboundp 'LaTeX-current-environment))
  207. (not (or (member (save-match-data (TeX-current-macro))
  208. reftex-label-ignored-macros-and-environments)
  209. (member (save-match-data (LaTeX-current-environment))
  210. reftex-label-ignored-macros-and-environments)))
  211. t))
  212. (push (reftex-label-info (reftex-match-string 1) file bound)
  213. docstruct)))
  214. ((match-end 3)
  215. ;; It is a section
  216. ;; Use the beginning as bound and not the end
  217. ;; (i.e. (point)) because the section command might
  218. ;; be the start of the current environment to be
  219. ;; found by `reftex-label-info'.
  220. (setq bound (match-beginning 0))
  221. ;; The section regexp matches a character at the end
  222. ;; we are not interested in. Especially if it is the
  223. ;; backslash of a following macro we want to find in
  224. ;; the next parsing iteration.
  225. (when (eq (char-before) ?\\) (backward-char))
  226. ;; Insert in List
  227. (setq toc-entry (funcall reftex-section-info-function file))
  228. (when (and toc-entry
  229. (eq ;; Either both are t or both are nil.
  230. (= (char-after bound) ?%)
  231. (string-suffix-p ".dtx" file)))
  232. ;; It can happen that section info returns nil
  233. (setq level (nth 5 toc-entry))
  234. (setq highest-level (min highest-level level))
  235. (if (= level highest-level)
  236. (message
  237. "Scanning %s %s ..."
  238. (car (rassoc level reftex-section-levels-all))
  239. (nth 6 toc-entry)))
  240. (push toc-entry docstruct)
  241. (setq reftex-active-toc toc-entry)))
  242. ((match-end 7)
  243. ;; It's an include or input
  244. (setq include-file (reftex-match-string 7))
  245. ;; Test if this file should be ignored
  246. (unless (delq nil (mapcar
  247. (lambda (x) (string-match x include-file))
  248. reftex-no-include-regexps))
  249. ;; Parse it
  250. (setq docstruct
  251. (reftex-parse-from-file
  252. include-file
  253. docstruct master-dir))))
  254. ((match-end 9)
  255. ;; Appendix starts here
  256. (reftex-init-section-numbers nil t)
  257. (push (cons 'appendix t) docstruct))
  258. ((match-end 10)
  259. ;; Index entry
  260. (when reftex-support-index
  261. (setq index-entry (reftex-index-info file))
  262. (when index-entry
  263. (cl-pushnew (nth 1 index-entry) reftex--index-tags :test #'equal)
  264. (push index-entry docstruct))))
  265. ((match-end 11)
  266. ;; A macro with label
  267. (save-excursion
  268. (let* ((mac (reftex-match-string 11))
  269. (label (progn (goto-char (match-end 11))
  270. (save-match-data
  271. (reftex-no-props
  272. (reftex-nth-arg-wrapper
  273. mac)))))
  274. (typekey (nth 1 (assoc mac reftex-env-or-mac-alist)))
  275. (entry (progn (if typekey
  276. ;; A typing macro
  277. (goto-char (match-end 0))
  278. ;; A neutral macro
  279. (goto-char (match-end 11))
  280. (reftex-move-over-touching-args))
  281. (reftex-label-info
  282. label file bound nil nil))))
  283. (push entry docstruct))))
  284. (t (error "This should not happen (reftex-parse-from-file)")))
  285. )
  286. ;; Find bibliography statement
  287. (when (setq tmp (reftex-locate-bibliography-files master-dir))
  288. (push (cons 'bib tmp) docstruct))
  289. (goto-char 1)
  290. (when (re-search-forward
  291. "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t)
  292. (push (cons 'thebib file) docstruct))
  293. ;; Find external document specifications
  294. (goto-char 1)
  295. (while (re-search-forward "[\n\r][ \t]*\\\\externaldocument\\(\\[\\([^]]*\\)\\]\\)?{\\([^}]+\\)}" nil t)
  296. (push (list 'xr-doc (reftex-match-string 2)
  297. (reftex-match-string 3))
  298. docstruct))
  299. ;; End of file mark
  300. (push (list 'eof file) docstruct)))))
  301. ;; Kill the scanned buffer
  302. (reftex-kill-temporary-buffers next-buf))
  303. ;; Return the list
  304. docstruct))
  305. (defun reftex-using-biblatex-p ()
  306. "Return non-nil if we are using biblatex rather than bibtex."
  307. (if (boundp 'TeX-active-styles)
  308. ;; the sophisticated AUCTeX way
  309. (member "biblatex" TeX-active-styles)
  310. ;; poor-man's check...
  311. (save-excursion
  312. (re-search-forward "^[^%\n]*?\\\\usepackage.*{biblatex}" nil t))))
  313. ;;;###autoload
  314. (defun reftex-locate-bibliography-files (master-dir &optional files)
  315. "Scan buffer for bibliography macros and return file list."
  316. (unless files
  317. (save-excursion
  318. (goto-char (point-min))
  319. ;; when biblatex is used, multiple \bibliography or
  320. ;; \addbibresource macros are allowed. With plain bibtex, only
  321. ;; the first is used.
  322. (let ((using-biblatex (reftex-using-biblatex-p))
  323. (again t))
  324. (while (and again
  325. (re-search-forward
  326. (concat
  327. ;; "\\(\\`\\|[\n\r]\\)[^%]*\\\\\\("
  328. "\\(^\\)[^%\n\r]*\\\\\\("
  329. (mapconcat 'identity reftex-bibliography-commands "\\|")
  330. "\\)\\(\\[.+?\\]\\)?{[ \t]*\\([^}]+\\)") nil t))
  331. (setq files
  332. (append files
  333. (split-string (reftex-match-string 4)
  334. "[ \t\n\r]*,[ \t\n\r]*")))
  335. (unless using-biblatex
  336. (setq again nil))))))
  337. (when files
  338. (setq files
  339. (mapcar
  340. (lambda (x)
  341. (if (or (member x reftex-bibfile-ignore-list)
  342. (delq nil (mapcar (lambda (re) (string-match re x))
  343. reftex-bibfile-ignore-regexps)))
  344. ;; excluded file
  345. nil
  346. ;; find the file
  347. (reftex-locate-file x "bib" master-dir)))
  348. files))
  349. (delq nil files)))
  350. (defun reftex-replace-label-list-segment (old insert &optional entirely)
  351. "Replace the segment in OLD which corresponds to INSERT.
  352. Works with side effects, directly changes old.
  353. If ENTIRELY is t, just return INSERT.
  354. This function also makes sure the old toc markers do not point anywhere."
  355. (cond
  356. (entirely
  357. (reftex-silence-toc-markers old (length old))
  358. insert)
  359. (t (let* ((new old)
  360. (file (nth 1 (car insert)))
  361. (eof-list (member (list 'eof file) old))
  362. (bof-list (member (list 'bof file) old))
  363. n)
  364. (if (not (and bof-list eof-list))
  365. (error "Cannot splice")
  366. ;; Splice
  367. (reftex-silence-toc-markers bof-list (- (length bof-list)
  368. (length eof-list)))
  369. (setq n (- (length old) (length bof-list)))
  370. (setcdr (nthcdr n new) (cdr insert))
  371. (setcdr (nthcdr (1- (length new)) new) (cdr eof-list)))
  372. new))))
  373. ;;;###autoload
  374. (defun reftex-section-info (file)
  375. "Return a section entry for the current match.
  376. Careful: This function expects the match-data to be still in place!"
  377. (let* ((marker (set-marker (make-marker) (1- (match-beginning 3))))
  378. (macro (reftex-match-string 3))
  379. (prefix (save-match-data
  380. (if (string-match "begin{\\([^}]+\\)}" macro)
  381. (match-string 1 macro))))
  382. (level-exp (cdr (assoc macro reftex-section-levels-all)))
  383. (level (if (symbolp level-exp)
  384. (save-match-data (funcall level-exp))
  385. level-exp))
  386. (star (= ?* (char-after (match-end 3))))
  387. (unnumbered (or star (< level 0)))
  388. (level (abs level))
  389. (section-number (reftex-section-number level unnumbered))
  390. (text1 (save-match-data
  391. (save-excursion
  392. (reftex-context-substring prefix))))
  393. (literal (buffer-substring-no-properties
  394. (1- (match-beginning 3))
  395. (min (point-max) (+ (match-end 0) (length text1) 1))))
  396. ;; Literal can be too short since text1 too short. No big problem.
  397. (text (reftex-nicify-text text1)))
  398. ;; Add section number and indentation
  399. (setq text
  400. (concat
  401. (make-string (* reftex-level-indent level) ?\ )
  402. (if (nth 1 reftex-label-menu-flags) ; section number flag
  403. (concat section-number " "))
  404. (if prefix (concat (capitalize prefix) ": ") "")
  405. text))
  406. (list 'toc "toc" text file marker level section-number
  407. literal (marker-position marker))))
  408. ;;;###autoload
  409. (defun reftex-ensure-index-support (&optional abort)
  410. "When index support is turned off, ask to turn it on and
  411. set the current prefix argument so that `reftex-access-scan-info'
  412. will rescan the entire document."
  413. (cond
  414. (reftex-support-index t)
  415. ((y-or-n-p "Turn on index support and rescan entire document? ")
  416. (setq reftex-support-index 'demanded
  417. current-prefix-arg '(16)))
  418. (t (if abort
  419. (error "No index support")
  420. (message "No index support")
  421. (ding)
  422. (sit-for 1)))))
  423. ;;;###autoload
  424. (defun reftex-index-info-safe (file)
  425. (reftex-with-special-syntax
  426. (reftex-index-info file)))
  427. (defvar test-dummy)
  428. ;;;###autoload
  429. (defun reftex-index-info (file)
  430. "Return an index entry for the current match.
  431. Careful: This function expects the match-data to be still in place!"
  432. (catch 'exit
  433. (let* ((macro (reftex-match-string 10))
  434. (bom (match-beginning 10))
  435. (boa (match-end 10))
  436. (entry (or (assoc macro reftex-index-macro-alist)
  437. (throw 'exit nil)))
  438. (exclude (nth 3 entry))
  439. ;; The following is a test if this match should be excluded
  440. (test-dummy (and (fboundp exclude)
  441. (funcall exclude)
  442. (throw 'exit nil)))
  443. (itag (nth 1 entry))
  444. (prefix (nth 2 entry))
  445. (index-tag
  446. (cond ((stringp itag) itag)
  447. ((integerp itag)
  448. (progn (goto-char boa)
  449. (or (reftex-nth-arg itag (nth 6 entry)) "idx")))
  450. (t "idx")))
  451. (arg (or (progn (goto-char boa)
  452. (reftex-nth-arg (nth 5 entry) (nth 6 entry)))
  453. ""))
  454. (end-of-args (progn (goto-char boa)
  455. (reftex-move-over-touching-args)
  456. (point)))
  457. (end-of-context (progn (skip-chars-forward "^ \t\n\r") (point)))
  458. (begin-of-context
  459. (progn (goto-char bom)
  460. (skip-chars-backward "^ \t\r\n")
  461. (point)))
  462. (context (buffer-substring-no-properties
  463. begin-of-context end-of-context))
  464. (key-end (if (string-match reftex-index-key-end-re arg)
  465. (1+ (match-beginning 0))))
  466. (rawkey (substring arg 0 key-end))
  467. (key (if prefix (concat prefix rawkey) rawkey))
  468. (sortkey (downcase key))
  469. (showkey (mapconcat 'identity
  470. (split-string key reftex-index-level-re)
  471. " ! ")))
  472. (goto-char end-of-args)
  473. ;; 0 1 2 3 4 5 6 7 8 9
  474. (list 'index index-tag context file bom arg key showkey sortkey key-end))))
  475. ;;;###autoload
  476. (defun reftex-short-context (env parse &optional bound derive)
  477. "Get about one line of useful context for the label definition at point."
  478. (if (consp parse)
  479. (setq parse (if derive (cdr parse) (car parse))))
  480. (reftex-nicify-text
  481. (cond
  482. ((null parse)
  483. (save-excursion
  484. (reftex-context-substring)))
  485. ((eq parse t)
  486. (if (string= env "section")
  487. ;; special treatment for section labels
  488. (save-excursion
  489. (if (and (re-search-backward reftex-section-or-include-regexp
  490. (point-min) t)
  491. (match-end 2))
  492. (progn
  493. (goto-char (match-end 0))
  494. (reftex-context-substring))
  495. (if reftex-active-toc
  496. (progn
  497. (string-match "{\\([^}]*\\)" (nth 7 reftex-active-toc))
  498. (match-string 1 (nth 7 reftex-active-toc)))
  499. "SECTION HEADING NOT FOUND")))
  500. (save-excursion
  501. (goto-char reftex-default-context-position)
  502. (unless (eq (string-to-char env) ?\\)
  503. (reftex-move-over-touching-args))
  504. (reftex-context-substring))))
  505. ((stringp parse)
  506. (save-excursion
  507. (if (re-search-backward parse bound t)
  508. (progn
  509. (goto-char (match-end 0))
  510. (reftex-context-substring))
  511. "NO MATCH FOR CONTEXT REGEXP")))
  512. ((integerp parse)
  513. (or (save-excursion
  514. (goto-char reftex-default-context-position)
  515. (reftex-nth-arg
  516. parse
  517. (nth 6 (assoc env reftex-env-or-mac-alist))))
  518. ""))
  519. ((fboundp parse)
  520. ;; A hook function. Call it.
  521. (save-excursion
  522. (condition-case error-var
  523. (funcall parse env)
  524. (error (format "HOOK ERROR: %s" (cdr error-var))))))
  525. (t
  526. "INVALID VALUE OF PARSE"))))
  527. ;;;###autoload
  528. (defun reftex-where-am-I ()
  529. "Return the docstruct entry above point.
  530. Actually returns a cons cell in which the cdr is a flag indicating
  531. if the information is exact (t) or approximate (nil)."
  532. (let ((docstruct (symbol-value reftex-docstruct-symbol))
  533. (cnt 0) rtn rtn-if-no-other
  534. found)
  535. (save-excursion
  536. (while (not rtn)
  537. (cl-incf cnt)
  538. (setq found (re-search-backward (reftex-everything-regexp) nil t))
  539. (setq rtn
  540. (cond
  541. ((not found)
  542. ;; no match
  543. (or
  544. (car (member (list 'bof (buffer-file-name)) docstruct))
  545. (not (setq cnt 2))
  546. (assq 'bof docstruct) ;; for safety reasons
  547. 'corrupted))
  548. ((match-end 1)
  549. ;; Label
  550. (assoc (reftex-match-string 1)
  551. (symbol-value reftex-docstruct-symbol)))
  552. ((match-end 3)
  553. ;; Section
  554. (goto-char (1- (match-beginning 3)))
  555. (let* ((list (member (list 'bof (buffer-file-name))
  556. docstruct))
  557. (endelt (car (member (list 'eof (buffer-file-name))
  558. list)))
  559. rtn1)
  560. (while (and list (not (eq endelt (car list))))
  561. (if (and (eq (car (car list)) 'toc)
  562. (string= (buffer-file-name)
  563. (nth 3 (car list))))
  564. (cond
  565. ((equal (point)
  566. (or (and (markerp (nth 4 (car list)))
  567. (marker-position (nth 4 (car list))))
  568. (nth 8 (car list))))
  569. ;; Fits with marker position or recorded position
  570. (setq rtn1 (car list) list nil))
  571. ((looking-at (reftex-make-regexp-allow-for-ctrl-m
  572. (nth 7 (car list))))
  573. ;; Same title: remember, but keep looking
  574. (setq rtn-if-no-other (car list)))))
  575. (pop list))
  576. rtn1))
  577. ((match-end 7)
  578. ;; Input or include...
  579. (car
  580. (member (list 'eof (reftex-locate-file
  581. (reftex-match-string 7) "tex"
  582. (cdr (assq 'master-dir docstruct))))
  583. docstruct)))
  584. ((match-end 9)
  585. (assq 'appendix (symbol-value reftex-docstruct-symbol)))
  586. ((match-end 10)
  587. ;; Index entry
  588. (when reftex-support-index
  589. (let* ((index-info (save-excursion
  590. (reftex-index-info-safe nil)))
  591. (list (member (list 'bof (buffer-file-name))
  592. docstruct))
  593. (endelt (car (member (list 'eof (buffer-file-name))
  594. list)))
  595. dist last-dist last (n 0))
  596. ;; Check all index entries with equal text
  597. (while (and list (not (eq endelt (car list))))
  598. (when (and (eq (car (car list)) 'index)
  599. (string= (nth 2 index-info)
  600. (nth 2 (car list))))
  601. (cl-incf n)
  602. (setq dist (abs (- (point) (nth 4 (car list)))))
  603. (if (or (not last-dist) (< dist last-dist))
  604. (setq last-dist dist last (car list))))
  605. (setq list (cdr list)))
  606. ;; We are sure if we have only one, or a zero distance
  607. (cond ((or (= n 1) (equal dist 0)) last)
  608. ((> n 1) (setq cnt 2) last)
  609. (t nil)))))
  610. ((match-end 11)
  611. (save-excursion
  612. (goto-char (match-end 11))
  613. (assoc (reftex-no-props
  614. (reftex-nth-arg-wrapper
  615. (reftex-match-string 11)))
  616. (symbol-value reftex-docstruct-symbol))))
  617. (t
  618. (error "This should not happen (reftex-where-am-I)"))))))
  619. ;; Check if there was only a by-name match for the section.
  620. (when (and (not rtn) rtn-if-no-other)
  621. (setq rtn rtn-if-no-other
  622. cnt 2))
  623. (cons rtn (eq cnt 1))))
  624. ;;;###autoload
  625. (defun reftex-notice-new (&optional n force)
  626. "Hook to handshake with RefTeX after something new has been inserted."
  627. ;; Add a new entry to the docstruct list. If it is a section, renumber
  628. ;; the following sections.
  629. ;; FIXME: Put in a WHAT parameter and search backward until one is found.
  630. ;; When N is given, go back that many matches of reftex-everything-regexp
  631. ;; When FORCE is non-nil, also insert if `reftex-where-am-I' was uncertain.
  632. (condition-case nil
  633. (catch 'exit
  634. (unless reftex-mode (throw 'exit nil))
  635. (reftex-access-scan-info)
  636. (let* ((docstruct (symbol-value reftex-docstruct-symbol))
  637. here-I-am appendix tail entry star level
  638. section-number context)
  639. (save-excursion
  640. (when (re-search-backward (reftex-everything-regexp) nil t (or n 1))
  641. ;; Find where we are
  642. (setq here-I-am (reftex-where-am-I))
  643. (or here-I-am (throw 'exit nil))
  644. (unless (or force (cdr here-I-am)) (throw 'exit nil))
  645. (setq tail (memq (car here-I-am) docstruct))
  646. (or tail (throw 'exit nil))
  647. (setq reftex-active-toc (reftex-last-assoc-before-elt
  648. 'toc (car here-I-am) docstruct)
  649. appendix (reftex-last-assoc-before-elt
  650. 'appendix (car here-I-am) docstruct))
  651. ;; Initialize section numbers
  652. (if (eq (car (car here-I-am)) 'appendix)
  653. (reftex-init-section-numbers nil t)
  654. (reftex-init-section-numbers reftex-active-toc appendix))
  655. ;; Match the section command
  656. (when (re-search-forward (reftex-everything-regexp) nil t)
  657. (cond
  658. ((match-end 1)
  659. (push (reftex-label-info (reftex-match-string 1) buffer-file-name)
  660. (cdr tail)))
  661. ((match-end 3)
  662. (setq star (= ?* (char-after (match-end 3)))
  663. entry (reftex-section-info (buffer-file-name))
  664. level (nth 5 entry))
  665. ;; Insert the section info
  666. (push entry (cdr tail))
  667. ;; We are done unless we use section numbers
  668. (unless (nth 1 reftex-label-menu-flags) (throw 'exit nil))
  669. ;; Update the remaining toc items
  670. (setq tail (cdr tail))
  671. (while (and (setq tail (memq (assq 'toc (cdr tail)) tail))
  672. (setq entry (car tail))
  673. (>= (nth 5 entry) level))
  674. (setq star (string-match "\\*" (nth 6 entry))
  675. context (nth 2 entry)
  676. section-number
  677. (reftex-section-number (nth 5 entry) star))
  678. (when (string-match "\\`\\([ \t]*\\)\\([.0-9A-Z]+\\)\\(.*\\)"
  679. context)
  680. (when (and (not appendix)
  681. (>= (string-to-char (match-string 2)) ?A))
  682. ;; Just entered the appendix. Get out.
  683. (throw 'exit nil))
  684. ;; Change the section number.
  685. (setf (nth 2 entry)
  686. (concat (match-string 1 context)
  687. section-number
  688. (match-string 3 context))))))
  689. ((match-end 10)
  690. ;; Index entry
  691. (and reftex-support-index
  692. (setq entry (reftex-index-info-safe buffer-file-name))
  693. ;; FIXME: (add-to-list 'reftex--index-tags (nth 1 index-entry))
  694. (push entry (cdr tail))))))))))
  695. (error nil))
  696. )
  697. (defsubst reftex-move-to-previous-arg (&optional bound)
  698. "Assuming that we are in front of a macro argument,
  699. move backward to the closing parenthesis of the previous argument.
  700. This function understands the splitting of macros over several lines
  701. in TeX."
  702. (cond
  703. ;; Just to be quick:
  704. ((memq (preceding-char) '(?\] ?\})))
  705. ;; Do a search
  706. ((and reftex-allow-detached-macro-args
  707. (re-search-backward
  708. "[]}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\=" bound t))
  709. (goto-char (1+ (match-beginning 0)))
  710. t)
  711. (t nil)))
  712. ;;;###autoload
  713. (defun reftex-what-macro-safe (which &optional bound)
  714. "Call `reftex-what-macro' with special syntax table."
  715. (reftex-with-special-syntax
  716. (reftex-what-macro which bound)))
  717. ;;;###autoload
  718. (defun reftex-what-macro (which &optional bound)
  719. "Find out if point is within the arguments of any TeX-macro.
  720. The return value is either (\"\\macro\" . (point)) or a list of them.
  721. If WHICH is nil, immediately return nil.
  722. If WHICH is 1, return innermost enclosing macro.
  723. If WHICH is t, return list of all macros enclosing point.
  724. If WHICH is a list of macros, look only for those macros and return the
  725. name of the first macro in this list found to enclose point.
  726. If the optional BOUND is an integer, bound backwards directed
  727. searches to this point. If it is nil, limit to nearest \\section -
  728. like statement.
  729. This function is pretty stable, but can be fooled if the text contains
  730. things like \\macro{aa}{bb} where \\macro is defined to take only one
  731. argument. As RefTeX cannot know this, the string \"bb\" would still be
  732. considered an argument of macro \\macro."
  733. (unless reftex-section-regexp (reftex-compile-variables))
  734. (catch 'exit
  735. (if (null which) (throw 'exit nil))
  736. (let ((bound (or bound (save-excursion (re-search-backward
  737. reftex-section-regexp nil 1)
  738. (point))))
  739. pos cmd-list cmd cnt cnt-opt entry)
  740. (save-restriction
  741. (save-excursion
  742. (narrow-to-region (max (point-min) bound) (point-max))
  743. ;; move back out of the current parenthesis
  744. (while (condition-case nil
  745. (let ((forward-sexp-function nil))
  746. (up-list -1) t)
  747. (error nil))
  748. (setq cnt 1 cnt-opt 0)
  749. ;; move back over any touching sexps
  750. (while (and (reftex-move-to-previous-arg bound)
  751. (condition-case nil
  752. (let ((forward-sexp-function nil))
  753. (backward-sexp) t)
  754. (error nil)))
  755. (if (eq (following-char) ?\[) (cl-incf cnt-opt))
  756. (cl-incf cnt))
  757. (setq pos (point))
  758. (when (and (or (= (following-char) ?\[)
  759. (= (following-char) ?\{))
  760. (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t))
  761. (setq cmd (reftex-match-string 0))
  762. (when (looking-at "\\\\begin{[^}]*}")
  763. (setq cmd (reftex-match-string 0)
  764. cnt (1- cnt)))
  765. ;; This does ignore optional arguments. Very hard to fix.
  766. (when (setq entry (assoc cmd reftex-env-or-mac-alist))
  767. (if (> cnt (or (nth 4 entry) 100))
  768. (setq cmd nil)))
  769. (cond
  770. ((null cmd))
  771. ((eq t which)
  772. (push (cons cmd (point)) cmd-list))
  773. ((or (eq 1 which) (member cmd which))
  774. (throw 'exit (cons cmd (point))))))
  775. (goto-char pos)))
  776. (nreverse cmd-list)))))
  777. ;;;###autoload
  778. (defun reftex-what-environment (which &optional bound)
  779. "Find out if point is inside a LaTeX environment.
  780. The return value is (e.g.) either (\"equation\" . (point)) or a list of
  781. them.
  782. If WHICH is nil, immediately return nil.
  783. If WHICH is 1, return innermost enclosing environment.
  784. If WHICH is t, return list of all environments enclosing point.
  785. If WHICH is a list of environments, look only for those environments and
  786. return the name of the first environment in this list found to enclose
  787. point.
  788. If the optional BOUND is an integer, bound backwards directed searches to
  789. this point. If it is nil, limit to nearest \\section - like statement."
  790. (unless reftex-section-regexp (reftex-compile-variables))
  791. (catch 'exit
  792. (save-excursion
  793. (if (null which) (throw 'exit nil))
  794. (let ((bound (or bound (save-excursion (re-search-backward
  795. reftex-section-regexp nil 1)
  796. (point))))
  797. env-list end-list env)
  798. (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}"
  799. bound t)
  800. (setq env (buffer-substring-no-properties
  801. (match-beginning 2) (match-end 2)))
  802. (cond
  803. ((string= (match-string 1) "end")
  804. (push env end-list))
  805. ((equal env (car end-list))
  806. (setq end-list (cdr end-list)))
  807. ((eq t which)
  808. (push (cons env (point)) env-list))
  809. ((or (eq 1 which) (member env which))
  810. (throw 'exit (cons env (point))))))
  811. (nreverse env-list)))))
  812. ;;;###autoload
  813. (defun reftex-what-special-env (which &optional bound)
  814. "Run the special environment parsers and return the matches.
  815. The return value is (e.g.) either (\"my-parser-function\" . (point))
  816. or a list of them.
  817. If WHICH is nil, immediately return nil.
  818. If WHICH is 1, return innermost enclosing environment.
  819. If WHICH is t, return list of all environments enclosing point.
  820. If WHICH is a list of environments, look only for those environments and
  821. return the name of the first environment in this list found to enclose
  822. point."
  823. (unless reftex-section-regexp (reftex-compile-variables))
  824. (catch 'exit
  825. (save-excursion
  826. (if (null reftex-special-env-parsers) (throw 'exit nil))
  827. (if (null which) (throw 'exit nil))
  828. (let ((bound (or bound (save-excursion (re-search-backward
  829. reftex-section-regexp nil 1)
  830. (point))))
  831. (fun-list (if (listp which)
  832. (mapcar (lambda (x) (if (memq x which) x nil))
  833. reftex-special-env-parsers)
  834. reftex-special-env-parsers))
  835. specials rtn)
  836. ;; Call all functions
  837. (setq specials (mapcar
  838. (lambda (fun)
  839. (save-excursion
  840. (setq rtn (and fun (funcall fun bound)))
  841. (if rtn (cons (symbol-name fun) rtn) nil)))
  842. fun-list))
  843. ;; Delete the non-matches
  844. (setq specials (delq nil specials))
  845. ;; Sort
  846. (setq specials (sort specials (lambda (a b) (> (cdr a) (cdr b)))))
  847. (if (eq which t)
  848. specials
  849. (car specials))))))
  850. (defsubst reftex-move-to-next-arg (&optional _ignore)
  851. "Assuming that we are at the end of a macro name or a macro argument,
  852. move forward to the opening parenthesis of the next argument.
  853. This function understands the splitting of macros over several lines
  854. in TeX."
  855. (cond
  856. ;; Just to be quick:
  857. ((memq (following-char) '(?\[ ?\{)))
  858. ;; Do a search
  859. ((and reftex-allow-detached-macro-args
  860. (looking-at "[ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*[[{]"))
  861. (goto-char (1- (match-end 0)))
  862. t)
  863. (t nil)))
  864. (defun reftex-nth-arg-wrapper (key)
  865. (let ((entry (assoc key reftex-env-or-mac-alist)))
  866. (reftex-nth-arg (nth 5 entry) (nth 6 entry))))
  867. ;;;###autoload
  868. (defun reftex-nth-arg (n &optional opt-args)
  869. "Return the Nth following {} or [] parentheses content.
  870. OPT-ARGS is a list of argument numbers which are optional."
  871. ;; If we are sitting at a macro start, skip to end of macro name.
  872. (and (eq (following-char) ?\\) (skip-chars-forward "a-zA-Z*\\\\"))
  873. (if (= n 1000)
  874. ;; Special case: Skip all touching arguments
  875. (progn
  876. (reftex-move-over-touching-args)
  877. (reftex-context-substring))
  878. ;; Do the real thing.
  879. (let ((cnt 1))
  880. (when (reftex-move-to-next-arg)
  881. (while (< cnt n)
  882. (while (and (member cnt opt-args)
  883. (eq (following-char) ?\{))
  884. (cl-incf cnt))
  885. (when (< cnt n)
  886. (unless (and (condition-case nil
  887. (or (forward-list 1) t)
  888. (error nil))
  889. (reftex-move-to-next-arg)
  890. (cl-incf cnt))
  891. (setq cnt 1000))))
  892. (while (and (memq cnt opt-args)
  893. (eq (following-char) ?\{))
  894. (cl-incf cnt)))
  895. (if (and (= n cnt)
  896. (> (skip-chars-forward "{\\[") 0))
  897. (reftex-context-substring)
  898. nil))))
  899. ;;;###autoload
  900. (defun reftex-move-over-touching-args ()
  901. (condition-case nil
  902. (while (memq (following-char) '(?\[ ?\{))
  903. (forward-list 1))
  904. (error nil)))
  905. (defun reftex-context-substring (&optional to-end)
  906. "Return up to 150 chars from point.
  907. When point is just after a { or [, limit string to matching parenthesis"
  908. (cond
  909. (to-end
  910. ;; Environment - find next \end
  911. (buffer-substring-no-properties
  912. (point)
  913. (min (+ (point) 150)
  914. (save-match-data
  915. ;; FIXME: This is not perfect
  916. (if (re-search-forward "\\\\end{" nil t)
  917. (match-beginning 0)
  918. (point-max))))))
  919. ((memq (preceding-char) '(?\{ ?\[))
  920. ;; Inside a list - get only the list.
  921. (buffer-substring-no-properties
  922. (point)
  923. (min (+ (point) 150)
  924. (point-max)
  925. (condition-case nil
  926. (let ((forward-sexp-function nil)) ;Unneeded fanciness.
  927. (up-list 1)
  928. (1- (point)))
  929. (error (point-max))))))
  930. (t
  931. ;; no list - just grab 150 characters
  932. (buffer-substring-no-properties (point)
  933. (min (+ (point) 150) (point-max))))))
  934. ;; Variable holding the vector with section numbers
  935. (defvar reftex-section-numbers (make-vector reftex-max-section-depth 0))
  936. ;;;###autoload
  937. (defun reftex-init-section-numbers (&optional toc-entry appendix)
  938. "Initialize the section numbers with zeros or with what is found in the TOC-ENTRY."
  939. (let* ((level (or (nth 5 toc-entry) -1))
  940. (numbers (nreverse (split-string (or (nth 6 toc-entry) "") "\\.")))
  941. (depth (1- (length reftex-section-numbers)))
  942. (i depth) number-string)
  943. (while (>= i 0)
  944. (if (> i level)
  945. (aset reftex-section-numbers i 0)
  946. (setq number-string (or (car numbers) "0"))
  947. (if (string-match "\\`[A-Z]\\'" number-string)
  948. (aset reftex-section-numbers i
  949. (- (string-to-char number-string) ?A -1))
  950. (aset reftex-section-numbers i (string-to-number number-string)))
  951. (pop numbers))
  952. (cl-decf i)))
  953. (put 'reftex-section-numbers 'appendix appendix))
  954. ;;;###autoload
  955. (defun reftex-section-number (&optional level star)
  956. "Return a string with the current section number.
  957. When LEVEL is non-nil, increase section numbers on that level."
  958. (let* ((depth (1- (length reftex-section-numbers))) idx n (string "")
  959. (appendix (get 'reftex-section-numbers 'appendix))
  960. (partspecial (and (not reftex-part-resets-chapter)
  961. (equal level 0))))
  962. ;; partspecial means, this is a part statement.
  963. ;; Parts do not reset the chapter counter, and the part number is
  964. ;; not included in the numbering of other sectioning levels.
  965. (when level
  966. (when (and (> level -1) (not star))
  967. (aset reftex-section-numbers
  968. level (1+ (aref reftex-section-numbers level))))
  969. (setq idx (1+ level))
  970. (when (not star)
  971. (while (<= idx depth)
  972. (if (or (not partspecial)
  973. (not (= idx 1)))
  974. (aset reftex-section-numbers idx 0))
  975. (cl-incf idx))))
  976. (if partspecial
  977. (setq string (concat "Part " (reftex-roman-number
  978. (aref reftex-section-numbers 0))))
  979. (setq idx (if reftex-part-resets-chapter 0 1))
  980. (while (<= idx depth)
  981. (setq n (aref reftex-section-numbers idx))
  982. (if (not (and partspecial (not (equal string ""))))
  983. (setq string (concat string (if (not (string= string "")) "." "")
  984. (int-to-string n))))
  985. (cl-incf idx))
  986. (save-match-data
  987. (if (string-match "\\`\\([@0]\\.\\)+" string)
  988. (setq string (replace-match "" nil nil string)))
  989. (if (string-match "\\(\\.0\\)+\\'" string)
  990. (setq string (replace-match "" nil nil string)))
  991. (if (and appendix
  992. (string-match "\\`[0-9]+" string))
  993. (setq string
  994. (concat
  995. (char-to-string
  996. (1- (+ ?A (string-to-number (match-string 0 string)))))
  997. (substring string (match-end 0))))))
  998. (if star
  999. (concat (make-string (1- (length string)) ?\ ) "*")
  1000. string))))
  1001. (defun reftex-roman-number (n)
  1002. "Return as a string the roman number equal to N."
  1003. (let ((nrest n)
  1004. (string "")
  1005. (list '((1000 . "M") ( 900 . "CM") ( 500 . "D") ( 400 . "CD")
  1006. ( 100 . "C") ( 90 . "XC") ( 50 . "L") ( 40 . "XL")
  1007. ( 10 . "X") ( 9 . "IX") ( 5 . "V") ( 4 . "IV")
  1008. ( 1 . "I")))
  1009. listel i s)
  1010. (while (>= nrest 1)
  1011. (setq listel (pop list)
  1012. i (car listel)
  1013. s (cdr listel))
  1014. (while (>= nrest i)
  1015. (setq string (concat string s)
  1016. nrest (- nrest i))))
  1017. string))
  1018. (provide 'reftex-parse)
  1019. ;;; reftex-parse.el ends here
  1020. ;; Local Variables:
  1021. ;; generated-autoload-file: "reftex-loaddefs.el"
  1022. ;; End: