reftex-parse.el 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136
  1. ;;; reftex-parse.el --- parser functions for RefTeX
  2. ;; Copyright (C) 1997-2015 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))
  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 toc-entry
  229. ;; It can happen that section info returns nil
  230. (setq level (nth 5 toc-entry))
  231. (setq highest-level (min highest-level level))
  232. (if (= level highest-level)
  233. (message
  234. "Scanning %s %s ..."
  235. (car (rassoc level reftex-section-levels-all))
  236. (nth 6 toc-entry)))
  237. (push toc-entry docstruct)
  238. (setq reftex-active-toc toc-entry)))
  239. ((match-end 7)
  240. ;; It's an include or input
  241. (setq include-file (reftex-match-string 7))
  242. ;; Test if this file should be ignored
  243. (unless (delq nil (mapcar
  244. (lambda (x) (string-match x include-file))
  245. reftex-no-include-regexps))
  246. ;; Parse it
  247. (setq docstruct
  248. (reftex-parse-from-file
  249. include-file
  250. docstruct master-dir))))
  251. ((match-end 9)
  252. ;; Appendix starts here
  253. (reftex-init-section-numbers nil t)
  254. (push (cons 'appendix t) docstruct))
  255. ((match-end 10)
  256. ;; Index entry
  257. (when reftex-support-index
  258. (setq index-entry (reftex-index-info file))
  259. (when index-entry
  260. (add-to-list 'reftex--index-tags (nth 1 index-entry))
  261. (push index-entry docstruct))))
  262. ((match-end 11)
  263. ;; A macro with label
  264. (save-excursion
  265. (let* ((mac (reftex-match-string 11))
  266. (label (progn (goto-char (match-end 11))
  267. (save-match-data
  268. (reftex-no-props
  269. (reftex-nth-arg-wrapper
  270. mac)))))
  271. (typekey (nth 1 (assoc mac reftex-env-or-mac-alist)))
  272. (entry (progn (if typekey
  273. ;; A typing macro
  274. (goto-char (match-end 0))
  275. ;; A neutral macro
  276. (goto-char (match-end 11))
  277. (reftex-move-over-touching-args))
  278. (reftex-label-info
  279. label file bound nil nil))))
  280. (push entry docstruct))))
  281. (t (error "This should not happen (reftex-parse-from-file)")))
  282. )
  283. ;; Find bibliography statement
  284. (when (setq tmp (reftex-locate-bibliography-files master-dir))
  285. (push (cons 'bib tmp) docstruct))
  286. (goto-char 1)
  287. (when (re-search-forward
  288. "\\(\\`\\|[\n\r]\\)[ \t]*\\\\begin{thebibliography}" nil t)
  289. (push (cons 'thebib file) docstruct))
  290. ;; Find external document specifications
  291. (goto-char 1)
  292. (while (re-search-forward "[\n\r][ \t]*\\\\externaldocument\\(\\[\\([^]]*\\)\\]\\)?{\\([^}]+\\)}" nil t)
  293. (push (list 'xr-doc (reftex-match-string 2)
  294. (reftex-match-string 3))
  295. docstruct))
  296. ;; End of file mark
  297. (push (list 'eof file) docstruct)))))
  298. ;; Kill the scanned buffer
  299. (reftex-kill-temporary-buffers next-buf))
  300. ;; Return the list
  301. docstruct))
  302. (defun reftex-using-biblatex-p ()
  303. "Return non-nil if we are using biblatex rather than bibtex."
  304. (if (boundp 'TeX-active-styles)
  305. ;; the sophisticated AUCTeX way
  306. (member "biblatex" TeX-active-styles)
  307. ;; poor-man's check...
  308. (save-excursion
  309. (re-search-forward "^[^%\n]*?\\\\usepackage.*{biblatex}" nil t))))
  310. ;;;###autoload
  311. (defun reftex-locate-bibliography-files (master-dir &optional files)
  312. "Scan buffer for bibliography macros and return file list."
  313. (unless files
  314. (save-excursion
  315. (goto-char (point-min))
  316. ;; when biblatex is used, multiple \bibliography or
  317. ;; \addbibresource macros are allowed. With plain bibtex, only
  318. ;; the first is used.
  319. (let ((using-biblatex (reftex-using-biblatex-p))
  320. (again t))
  321. (while (and again
  322. (re-search-forward
  323. (concat
  324. ;; "\\(\\`\\|[\n\r]\\)[^%]*\\\\\\("
  325. "\\(^\\)[^%\n\r]*\\\\\\("
  326. (mapconcat 'identity reftex-bibliography-commands "\\|")
  327. "\\)\\(\\[.+?\\]\\)?{[ \t]*\\([^}]+\\)") nil t))
  328. (setq files
  329. (append files
  330. (split-string (reftex-match-string 4)
  331. "[ \t\n\r]*,[ \t\n\r]*")))
  332. (unless using-biblatex
  333. (setq again nil))))))
  334. (when files
  335. (setq files
  336. (mapcar
  337. (lambda (x)
  338. (if (or (member x reftex-bibfile-ignore-list)
  339. (delq nil (mapcar (lambda (re) (string-match re x))
  340. reftex-bibfile-ignore-regexps)))
  341. ;; excluded file
  342. nil
  343. ;; find the file
  344. (reftex-locate-file x "bib" master-dir)))
  345. files))
  346. (delq nil files)))
  347. (defun reftex-replace-label-list-segment (old insert &optional entirely)
  348. "Replace the segment in OLD which corresponds to INSERT.
  349. Works with side effects, directly changes old.
  350. If ENTIRELY is t, just return INSERT.
  351. This function also makes sure the old toc markers do not point anywhere."
  352. (cond
  353. (entirely
  354. (reftex-silence-toc-markers old (length old))
  355. insert)
  356. (t (let* ((new old)
  357. (file (nth 1 (car insert)))
  358. (eof-list (member (list 'eof file) old))
  359. (bof-list (member (list 'bof file) old))
  360. n)
  361. (if (not (and bof-list eof-list))
  362. (error "Cannot splice")
  363. ;; Splice
  364. (reftex-silence-toc-markers bof-list (- (length bof-list)
  365. (length eof-list)))
  366. (setq n (- (length old) (length bof-list)))
  367. (setcdr (nthcdr n new) (cdr insert))
  368. (setcdr (nthcdr (1- (length new)) new) (cdr eof-list)))
  369. new))))
  370. ;;;###autoload
  371. (defun reftex-section-info (file)
  372. "Return a section entry for the current match.
  373. Careful: This function expects the match-data to be still in place!"
  374. (let* ((marker (set-marker (make-marker) (1- (match-beginning 3))))
  375. (macro (reftex-match-string 3))
  376. (prefix (save-match-data
  377. (if (string-match "begin{\\([^}]+\\)}" macro)
  378. (match-string 1 macro))))
  379. (level-exp (cdr (assoc macro reftex-section-levels-all)))
  380. (level (if (symbolp level-exp)
  381. (save-match-data (funcall level-exp))
  382. level-exp))
  383. (star (= ?* (char-after (match-end 3))))
  384. (unnumbered (or star (< level 0)))
  385. (level (abs level))
  386. (section-number (reftex-section-number level unnumbered))
  387. (text1 (save-match-data
  388. (save-excursion
  389. (reftex-context-substring prefix))))
  390. (literal (buffer-substring-no-properties
  391. (1- (match-beginning 3))
  392. (min (point-max) (+ (match-end 0) (length text1) 1))))
  393. ;; Literal can be too short since text1 too short. No big problem.
  394. (text (reftex-nicify-text text1)))
  395. ;; Add section number and indentation
  396. (setq text
  397. (concat
  398. (make-string (* reftex-level-indent level) ?\ )
  399. (if (nth 1 reftex-label-menu-flags) ; section number flag
  400. (concat section-number " "))
  401. (if prefix (concat (capitalize prefix) ": ") "")
  402. text))
  403. (list 'toc "toc" text file marker level section-number
  404. literal (marker-position marker))))
  405. ;;;###autoload
  406. (defun reftex-ensure-index-support (&optional abort)
  407. "When index support is turned off, ask to turn it on and
  408. set the current prefix argument so that `reftex-access-scan-info'
  409. will rescan the entire document."
  410. (cond
  411. (reftex-support-index t)
  412. ((y-or-n-p "Turn on index support and rescan entire document? ")
  413. (setq reftex-support-index 'demanded
  414. current-prefix-arg '(16)))
  415. (t (if abort
  416. (error "No index support")
  417. (message "No index support")
  418. (ding)
  419. (sit-for 1)))))
  420. ;;;###autoload
  421. (defun reftex-index-info-safe (file)
  422. (reftex-with-special-syntax
  423. (reftex-index-info file)))
  424. (defvar test-dummy)
  425. ;;;###autoload
  426. (defun reftex-index-info (file)
  427. "Return an index entry for the current match.
  428. Careful: This function expects the match-data to be still in place!"
  429. (catch 'exit
  430. (let* ((macro (reftex-match-string 10))
  431. (bom (match-beginning 10))
  432. (boa (match-end 10))
  433. (entry (or (assoc macro reftex-index-macro-alist)
  434. (throw 'exit nil)))
  435. (exclude (nth 3 entry))
  436. ;; The following is a test if this match should be excluded
  437. (test-dummy (and (fboundp exclude)
  438. (funcall exclude)
  439. (throw 'exit nil)))
  440. (itag (nth 1 entry))
  441. (prefix (nth 2 entry))
  442. (index-tag
  443. (cond ((stringp itag) itag)
  444. ((integerp itag)
  445. (progn (goto-char boa)
  446. (or (reftex-nth-arg itag (nth 6 entry)) "idx")))
  447. (t "idx")))
  448. (arg (or (progn (goto-char boa)
  449. (reftex-nth-arg (nth 5 entry) (nth 6 entry)))
  450. ""))
  451. (end-of-args (progn (goto-char boa)
  452. (reftex-move-over-touching-args)
  453. (point)))
  454. (end-of-context (progn (skip-chars-forward "^ \t\n\r") (point)))
  455. (begin-of-context
  456. (progn (goto-char bom)
  457. (skip-chars-backward "^ \t\r\n")
  458. (point)))
  459. (context (buffer-substring-no-properties
  460. begin-of-context end-of-context))
  461. (key-end (if (string-match reftex-index-key-end-re arg)
  462. (1+ (match-beginning 0))))
  463. (rawkey (substring arg 0 key-end))
  464. (key (if prefix (concat prefix rawkey) rawkey))
  465. (sortkey (downcase key))
  466. (showkey (mapconcat 'identity
  467. (split-string key reftex-index-level-re)
  468. " ! ")))
  469. (goto-char end-of-args)
  470. ;; 0 1 2 3 4 5 6 7 8 9
  471. (list 'index index-tag context file bom arg key showkey sortkey key-end))))
  472. ;;;###autoload
  473. (defun reftex-short-context (env parse &optional bound derive)
  474. "Get about one line of useful context for the label definition at point."
  475. (if (consp parse)
  476. (setq parse (if derive (cdr parse) (car parse))))
  477. (reftex-nicify-text
  478. (cond
  479. ((null parse)
  480. (save-excursion
  481. (reftex-context-substring)))
  482. ((eq parse t)
  483. (if (string= env "section")
  484. ;; special treatment for section labels
  485. (save-excursion
  486. (if (and (re-search-backward reftex-section-or-include-regexp
  487. (point-min) t)
  488. (match-end 2))
  489. (progn
  490. (goto-char (match-end 0))
  491. (reftex-context-substring))
  492. (if reftex-active-toc
  493. (progn
  494. (string-match "{\\([^}]*\\)" (nth 7 reftex-active-toc))
  495. (match-string 1 (nth 7 reftex-active-toc)))
  496. "SECTION HEADING NOT FOUND")))
  497. (save-excursion
  498. (goto-char reftex-default-context-position)
  499. (unless (eq (string-to-char env) ?\\)
  500. (reftex-move-over-touching-args))
  501. (reftex-context-substring))))
  502. ((stringp parse)
  503. (save-excursion
  504. (if (re-search-backward parse bound t)
  505. (progn
  506. (goto-char (match-end 0))
  507. (reftex-context-substring))
  508. "NO MATCH FOR CONTEXT REGEXP")))
  509. ((integerp parse)
  510. (or (save-excursion
  511. (goto-char reftex-default-context-position)
  512. (reftex-nth-arg
  513. parse
  514. (nth 6 (assoc env reftex-env-or-mac-alist))))
  515. ""))
  516. ((fboundp parse)
  517. ;; A hook function. Call it.
  518. (save-excursion
  519. (condition-case error-var
  520. (funcall parse env)
  521. (error (format "HOOK ERROR: %s" (cdr error-var))))))
  522. (t
  523. "INVALID VALUE OF PARSE"))))
  524. ;;;###autoload
  525. (defun reftex-where-am-I ()
  526. "Return the docstruct entry above point.
  527. Actually returns a cons cell in which the cdr is a flag indicating
  528. if the information is exact (t) or approximate (nil)."
  529. (let ((docstruct (symbol-value reftex-docstruct-symbol))
  530. (cnt 0) rtn rtn-if-no-other
  531. found)
  532. (save-excursion
  533. (while (not rtn)
  534. (incf cnt)
  535. (setq found (re-search-backward (reftex-everything-regexp) nil t))
  536. (setq rtn
  537. (cond
  538. ((not found)
  539. ;; no match
  540. (or
  541. (car (member (list 'bof (buffer-file-name)) docstruct))
  542. (not (setq cnt 2))
  543. (assq 'bof docstruct) ;; for safety reasons
  544. 'corrupted))
  545. ((match-end 1)
  546. ;; Label
  547. (assoc (reftex-match-string 1)
  548. (symbol-value reftex-docstruct-symbol)))
  549. ((match-end 3)
  550. ;; Section
  551. (goto-char (1- (match-beginning 3)))
  552. (let* ((list (member (list 'bof (buffer-file-name))
  553. docstruct))
  554. (endelt (car (member (list 'eof (buffer-file-name))
  555. list)))
  556. rtn1)
  557. (while (and list (not (eq endelt (car list))))
  558. (if (and (eq (car (car list)) 'toc)
  559. (string= (buffer-file-name)
  560. (nth 3 (car list))))
  561. (cond
  562. ((equal (point)
  563. (or (and (markerp (nth 4 (car list)))
  564. (marker-position (nth 4 (car list))))
  565. (nth 8 (car list))))
  566. ;; Fits with marker position or recorded position
  567. (setq rtn1 (car list) list nil))
  568. ((looking-at (reftex-make-regexp-allow-for-ctrl-m
  569. (nth 7 (car list))))
  570. ;; Same title: remember, but keep looking
  571. (setq rtn-if-no-other (car list)))))
  572. (pop list))
  573. rtn1))
  574. ((match-end 7)
  575. ;; Input or include...
  576. (car
  577. (member (list 'eof (reftex-locate-file
  578. (reftex-match-string 7) "tex"
  579. (cdr (assq 'master-dir docstruct))))
  580. docstruct)))
  581. ((match-end 9)
  582. (assq 'appendix (symbol-value reftex-docstruct-symbol)))
  583. ((match-end 10)
  584. ;; Index entry
  585. (when reftex-support-index
  586. (let* ((index-info (save-excursion
  587. (reftex-index-info-safe nil)))
  588. (list (member (list 'bof (buffer-file-name))
  589. docstruct))
  590. (endelt (car (member (list 'eof (buffer-file-name))
  591. list)))
  592. dist last-dist last (n 0))
  593. ;; Check all index entries with equal text
  594. (while (and list (not (eq endelt (car list))))
  595. (when (and (eq (car (car list)) 'index)
  596. (string= (nth 2 index-info)
  597. (nth 2 (car list))))
  598. (incf n)
  599. (setq dist (abs (- (point) (nth 4 (car list)))))
  600. (if (or (not last-dist) (< dist last-dist))
  601. (setq last-dist dist last (car list))))
  602. (setq list (cdr list)))
  603. ;; We are sure if we have only one, or a zero distance
  604. (cond ((or (= n 1) (equal dist 0)) last)
  605. ((> n 1) (setq cnt 2) last)
  606. (t nil)))))
  607. ((match-end 11)
  608. (save-excursion
  609. (goto-char (match-end 11))
  610. (assoc (reftex-no-props
  611. (reftex-nth-arg-wrapper
  612. (reftex-match-string 11)))
  613. (symbol-value reftex-docstruct-symbol))))
  614. (t
  615. (error "This should not happen (reftex-where-am-I)"))))))
  616. ;; Check if there was only a by-name match for the section.
  617. (when (and (not rtn) rtn-if-no-other)
  618. (setq rtn rtn-if-no-other
  619. cnt 2))
  620. (cons rtn (eq cnt 1))))
  621. ;;;###autoload
  622. (defun reftex-notice-new (&optional n force)
  623. "Hook to handshake with RefTeX after something new has been inserted."
  624. ;; Add a new entry to the docstruct list. If it is a section, renumber
  625. ;; the following sections.
  626. ;; FIXME: Put in a WHAT parameter and search backward until one is found.
  627. ;; When N is given, go back that many matches of reftex-everything-regexp
  628. ;; When FORCE is non-nil, also insert if `reftex-where-am-I' was uncertain.
  629. (condition-case nil
  630. (catch 'exit
  631. (unless reftex-mode (throw 'exit nil))
  632. (reftex-access-scan-info)
  633. (let* ((docstruct (symbol-value reftex-docstruct-symbol))
  634. here-I-am appendix tail entry star level
  635. section-number context)
  636. (save-excursion
  637. (when (re-search-backward (reftex-everything-regexp) nil t (or n 1))
  638. ;; Find where we are
  639. (setq here-I-am (reftex-where-am-I))
  640. (or here-I-am (throw 'exit nil))
  641. (unless (or force (cdr here-I-am)) (throw 'exit nil))
  642. (setq tail (memq (car here-I-am) docstruct))
  643. (or tail (throw 'exit nil))
  644. (setq reftex-active-toc (reftex-last-assoc-before-elt
  645. 'toc (car here-I-am) docstruct)
  646. appendix (reftex-last-assoc-before-elt
  647. 'appendix (car here-I-am) docstruct))
  648. ;; Initialize section numbers
  649. (if (eq (car (car here-I-am)) 'appendix)
  650. (reftex-init-section-numbers nil t)
  651. (reftex-init-section-numbers reftex-active-toc appendix))
  652. ;; Match the section command
  653. (when (re-search-forward (reftex-everything-regexp) nil t)
  654. (cond
  655. ((match-end 1)
  656. (push (reftex-label-info (reftex-match-string 1) buffer-file-name)
  657. (cdr tail)))
  658. ((match-end 3)
  659. (setq star (= ?* (char-after (match-end 3)))
  660. entry (reftex-section-info (buffer-file-name))
  661. level (nth 5 entry))
  662. ;; Insert the section info
  663. (push entry (cdr tail))
  664. ;; We are done unless we use section numbers
  665. (unless (nth 1 reftex-label-menu-flags) (throw 'exit nil))
  666. ;; Update the remaining toc items
  667. (setq tail (cdr tail))
  668. (while (and (setq tail (memq (assq 'toc (cdr tail)) tail))
  669. (setq entry (car tail))
  670. (>= (nth 5 entry) level))
  671. (setq star (string-match "\\*" (nth 6 entry))
  672. context (nth 2 entry)
  673. section-number
  674. (reftex-section-number (nth 5 entry) star))
  675. (when (string-match "\\`\\([ \t]*\\)\\([.0-9A-Z]+\\)\\(.*\\)"
  676. context)
  677. (when (and (not appendix)
  678. (>= (string-to-char (match-string 2)) ?A))
  679. ;; Just entered the appendix. Get out.
  680. (throw 'exit nil))
  681. ;; Change the section number.
  682. (setf (nth 2 entry)
  683. (concat (match-string 1 context)
  684. section-number
  685. (match-string 3 context))))))
  686. ((match-end 10)
  687. ;; Index entry
  688. (and reftex-support-index
  689. (setq entry (reftex-index-info-safe buffer-file-name))
  690. ;; FIXME: (add-to-list 'reftex--index-tags (nth 1 index-entry))
  691. (push entry (cdr tail))))))))))
  692. (error nil))
  693. )
  694. (defsubst reftex-move-to-previous-arg (&optional bound)
  695. "Assuming that we are in front of a macro argument,
  696. move backward to the closing parenthesis of the previous argument.
  697. This function understands the splitting of macros over several lines
  698. in TeX."
  699. (cond
  700. ;; Just to be quick:
  701. ((memq (preceding-char) '(?\] ?\})))
  702. ;; Do a search
  703. ((and reftex-allow-detached-macro-args
  704. (re-search-backward
  705. "[]}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\=" bound t))
  706. (goto-char (1+ (match-beginning 0)))
  707. t)
  708. (t nil)))
  709. ;;;###autoload
  710. (defun reftex-what-macro-safe (which &optional bound)
  711. "Call `reftex-what-macro' with special syntax table."
  712. (reftex-with-special-syntax
  713. (reftex-what-macro which bound)))
  714. ;;;###autoload
  715. (defun reftex-what-macro (which &optional bound)
  716. "Find out if point is within the arguments of any TeX-macro.
  717. The return value is either (\"\\macro\" . (point)) or a list of them.
  718. If WHICH is nil, immediately return nil.
  719. If WHICH is 1, return innermost enclosing macro.
  720. If WHICH is t, return list of all macros enclosing point.
  721. If WHICH is a list of macros, look only for those macros and return the
  722. name of the first macro in this list found to enclose point.
  723. If the optional BOUND is an integer, bound backwards directed
  724. searches to this point. If it is nil, limit to nearest \\section -
  725. like statement.
  726. This function is pretty stable, but can be fooled if the text contains
  727. things like \\macro{aa}{bb} where \\macro is defined to take only one
  728. argument. As RefTeX cannot know this, the string \"bb\" would still be
  729. considered an argument of macro \\macro."
  730. (unless reftex-section-regexp (reftex-compile-variables))
  731. (catch 'exit
  732. (if (null which) (throw 'exit nil))
  733. (let ((bound (or bound (save-excursion (re-search-backward
  734. reftex-section-regexp nil 1)
  735. (point))))
  736. pos cmd-list cmd cnt cnt-opt entry)
  737. (save-restriction
  738. (save-excursion
  739. (narrow-to-region (max (point-min) bound) (point-max))
  740. ;; move back out of the current parenthesis
  741. (while (condition-case nil
  742. (let ((forward-sexp-function nil))
  743. (up-list -1) t)
  744. (error nil))
  745. (setq cnt 1 cnt-opt 0)
  746. ;; move back over any touching sexps
  747. (while (and (reftex-move-to-previous-arg bound)
  748. (condition-case nil
  749. (let ((forward-sexp-function nil))
  750. (backward-sexp) t)
  751. (error nil)))
  752. (if (eq (following-char) ?\[) (incf cnt-opt))
  753. (incf cnt))
  754. (setq pos (point))
  755. (when (and (or (= (following-char) ?\[)
  756. (= (following-char) ?\{))
  757. (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t))
  758. (setq cmd (reftex-match-string 0))
  759. (when (looking-at "\\\\begin{[^}]*}")
  760. (setq cmd (reftex-match-string 0)
  761. cnt (1- cnt)))
  762. ;; This does ignore optional arguments. Very hard to fix.
  763. (when (setq entry (assoc cmd reftex-env-or-mac-alist))
  764. (if (> cnt (or (nth 4 entry) 100))
  765. (setq cmd nil)))
  766. (cond
  767. ((null cmd))
  768. ((eq t which)
  769. (push (cons cmd (point)) cmd-list))
  770. ((or (eq 1 which) (member cmd which))
  771. (throw 'exit (cons cmd (point))))))
  772. (goto-char pos)))
  773. (nreverse cmd-list)))))
  774. ;;;###autoload
  775. (defun reftex-what-environment (which &optional bound)
  776. "Find out if point is inside a LaTeX environment.
  777. The return value is (e.g.) either (\"equation\" . (point)) or a list of
  778. them.
  779. If WHICH is nil, immediately return nil.
  780. If WHICH is 1, return innermost enclosing environment.
  781. If WHICH is t, return list of all environments enclosing point.
  782. If WHICH is a list of environments, look only for those environments and
  783. return the name of the first environment in this list found to enclose
  784. point.
  785. If the optional BOUND is an integer, bound backwards directed searches to
  786. this point. If it is nil, limit to nearest \\section - like statement."
  787. (unless reftex-section-regexp (reftex-compile-variables))
  788. (catch 'exit
  789. (save-excursion
  790. (if (null which) (throw 'exit nil))
  791. (let ((bound (or bound (save-excursion (re-search-backward
  792. reftex-section-regexp nil 1)
  793. (point))))
  794. env-list end-list env)
  795. (while (re-search-backward "\\\\\\(begin\\|end\\){\\([^}]+\\)}"
  796. bound t)
  797. (setq env (buffer-substring-no-properties
  798. (match-beginning 2) (match-end 2)))
  799. (cond
  800. ((string= (match-string 1) "end")
  801. (push env end-list))
  802. ((equal env (car end-list))
  803. (setq end-list (cdr end-list)))
  804. ((eq t which)
  805. (push (cons env (point)) env-list))
  806. ((or (eq 1 which) (member env which))
  807. (throw 'exit (cons env (point))))))
  808. (nreverse env-list)))))
  809. ;;;###autoload
  810. (defun reftex-what-special-env (which &optional bound)
  811. "Run the special environment parsers and return the matches.
  812. The return value is (e.g.) either (\"my-parser-function\" . (point))
  813. or a list of them.
  814. If WHICH is nil, immediately return nil.
  815. If WHICH is 1, return innermost enclosing environment.
  816. If WHICH is t, return list of all environments enclosing point.
  817. If WHICH is a list of environments, look only for those environments and
  818. return the name of the first environment in this list found to enclose
  819. point."
  820. (unless reftex-section-regexp (reftex-compile-variables))
  821. (catch 'exit
  822. (save-excursion
  823. (if (null reftex-special-env-parsers) (throw 'exit nil))
  824. (if (null which) (throw 'exit nil))
  825. (let ((bound (or bound (save-excursion (re-search-backward
  826. reftex-section-regexp nil 1)
  827. (point))))
  828. (fun-list (if (listp which)
  829. (mapcar (lambda (x) (if (memq x which) x nil))
  830. reftex-special-env-parsers)
  831. reftex-special-env-parsers))
  832. specials rtn)
  833. ;; Call all functions
  834. (setq specials (mapcar
  835. (lambda (fun)
  836. (save-excursion
  837. (setq rtn (and fun (funcall fun bound)))
  838. (if rtn (cons (symbol-name fun) rtn) nil)))
  839. fun-list))
  840. ;; Delete the non-matches
  841. (setq specials (delq nil specials))
  842. ;; Sort
  843. (setq specials (sort specials (lambda (a b) (> (cdr a) (cdr b)))))
  844. (if (eq which t)
  845. specials
  846. (car specials))))))
  847. (defsubst reftex-move-to-next-arg (&optional _ignore)
  848. "Assuming that we are at the end of a macro name or a macro argument,
  849. move forward to the opening parenthesis of the next argument.
  850. This function understands the splitting of macros over several lines
  851. in TeX."
  852. (cond
  853. ;; Just to be quick:
  854. ((memq (following-char) '(?\[ ?\{)))
  855. ;; Do a search
  856. ((and reftex-allow-detached-macro-args
  857. (looking-at "[ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*[[{]"))
  858. (goto-char (1- (match-end 0)))
  859. t)
  860. (t nil)))
  861. (defun reftex-nth-arg-wrapper (key)
  862. (let ((entry (assoc key reftex-env-or-mac-alist)))
  863. (reftex-nth-arg (nth 5 entry) (nth 6 entry))))
  864. ;;;###autoload
  865. (defun reftex-nth-arg (n &optional opt-args)
  866. "Return the Nth following {} or [] parentheses content.
  867. OPT-ARGS is a list of argument numbers which are optional."
  868. ;; If we are sitting at a macro start, skip to end of macro name.
  869. (and (eq (following-char) ?\\) (skip-chars-forward "a-zA-Z*\\\\"))
  870. (if (= n 1000)
  871. ;; Special case: Skip all touching arguments
  872. (progn
  873. (reftex-move-over-touching-args)
  874. (reftex-context-substring))
  875. ;; Do the real thing.
  876. (let ((cnt 1))
  877. (when (reftex-move-to-next-arg)
  878. (while (< cnt n)
  879. (while (and (member cnt opt-args)
  880. (eq (following-char) ?\{))
  881. (incf cnt))
  882. (when (< cnt n)
  883. (unless (and (condition-case nil
  884. (or (forward-list 1) t)
  885. (error nil))
  886. (reftex-move-to-next-arg)
  887. (incf cnt))
  888. (setq cnt 1000))))
  889. (while (and (memq cnt opt-args)
  890. (eq (following-char) ?\{))
  891. (incf cnt)))
  892. (if (and (= n cnt)
  893. (> (skip-chars-forward "{\\[") 0))
  894. (reftex-context-substring)
  895. nil))))
  896. ;;;###autoload
  897. (defun reftex-move-over-touching-args ()
  898. (condition-case nil
  899. (while (memq (following-char) '(?\[ ?\{))
  900. (forward-list 1))
  901. (error nil)))
  902. (defun reftex-context-substring (&optional to-end)
  903. "Return up to 150 chars from point.
  904. When point is just after a { or [, limit string to matching parenthesis"
  905. (cond
  906. (to-end
  907. ;; Environment - find next \end
  908. (buffer-substring-no-properties
  909. (point)
  910. (min (+ (point) 150)
  911. (save-match-data
  912. ;; FIXME: This is not perfect
  913. (if (re-search-forward "\\\\end{" nil t)
  914. (match-beginning 0)
  915. (point-max))))))
  916. ((memq (preceding-char) '(?\{ ?\[))
  917. ;; Inside a list - get only the list.
  918. (buffer-substring-no-properties
  919. (point)
  920. (min (+ (point) 150)
  921. (point-max)
  922. (condition-case nil
  923. (let ((forward-sexp-function nil)) ;Unneeded fanciness.
  924. (up-list 1)
  925. (1- (point)))
  926. (error (point-max))))))
  927. (t
  928. ;; no list - just grab 150 characters
  929. (buffer-substring-no-properties (point)
  930. (min (+ (point) 150) (point-max))))))
  931. ;; Variable holding the vector with section numbers
  932. (defvar reftex-section-numbers (make-vector reftex-max-section-depth 0))
  933. ;;;###autoload
  934. (defun reftex-init-section-numbers (&optional toc-entry appendix)
  935. "Initialize the section numbers with zeros or with what is found in the TOC-ENTRY."
  936. (let* ((level (or (nth 5 toc-entry) -1))
  937. (numbers (nreverse (split-string (or (nth 6 toc-entry) "") "\\.")))
  938. (depth (1- (length reftex-section-numbers)))
  939. (i depth) number-string)
  940. (while (>= i 0)
  941. (if (> i level)
  942. (aset reftex-section-numbers i 0)
  943. (setq number-string (or (car numbers) "0"))
  944. (if (string-match "\\`[A-Z]\\'" number-string)
  945. (aset reftex-section-numbers i
  946. (- (string-to-char number-string) ?A -1))
  947. (aset reftex-section-numbers i (string-to-number number-string)))
  948. (pop numbers))
  949. (decf i)))
  950. (put 'reftex-section-numbers 'appendix appendix))
  951. ;;;###autoload
  952. (defun reftex-section-number (&optional level star)
  953. "Return a string with the current section number.
  954. When LEVEL is non-nil, increase section numbers on that level."
  955. (let* ((depth (1- (length reftex-section-numbers))) idx n (string "")
  956. (appendix (get 'reftex-section-numbers 'appendix))
  957. (partspecial (and (not reftex-part-resets-chapter)
  958. (equal level 0))))
  959. ;; partspecial means, this is a part statement.
  960. ;; Parts do not reset the chapter counter, and the part number is
  961. ;; not included in the numbering of other sectioning levels.
  962. (when level
  963. (when (and (> level -1) (not star))
  964. (aset reftex-section-numbers
  965. level (1+ (aref reftex-section-numbers level))))
  966. (setq idx (1+ level))
  967. (when (not star)
  968. (while (<= idx depth)
  969. (if (or (not partspecial)
  970. (not (= idx 1)))
  971. (aset reftex-section-numbers idx 0))
  972. (incf idx))))
  973. (if partspecial
  974. (setq string (concat "Part " (reftex-roman-number
  975. (aref reftex-section-numbers 0))))
  976. (setq idx (if reftex-part-resets-chapter 0 1))
  977. (while (<= idx depth)
  978. (setq n (aref reftex-section-numbers idx))
  979. (if (not (and partspecial (not (equal string ""))))
  980. (setq string (concat string (if (not (string= string "")) "." "")
  981. (int-to-string n))))
  982. (incf idx))
  983. (save-match-data
  984. (if (string-match "\\`\\([@0]\\.\\)+" string)
  985. (setq string (replace-match "" nil nil string)))
  986. (if (string-match "\\(\\.0\\)+\\'" string)
  987. (setq string (replace-match "" nil nil string)))
  988. (if (and appendix
  989. (string-match "\\`[0-9]+" string))
  990. (setq string
  991. (concat
  992. (char-to-string
  993. (1- (+ ?A (string-to-number (match-string 0 string)))))
  994. (substring string (match-end 0))))))
  995. (if star
  996. (concat (make-string (1- (length string)) ?\ ) "*")
  997. string))))
  998. (defun reftex-roman-number (n)
  999. "Return as a string the roman number equal to N."
  1000. (let ((nrest n)
  1001. (string "")
  1002. (list '((1000 . "M") ( 900 . "CM") ( 500 . "D") ( 400 . "CD")
  1003. ( 100 . "C") ( 90 . "XC") ( 50 . "L") ( 40 . "XL")
  1004. ( 10 . "X") ( 9 . "IX") ( 5 . "V") ( 4 . "IV")
  1005. ( 1 . "I")))
  1006. listel i s)
  1007. (while (>= nrest 1)
  1008. (setq listel (pop list)
  1009. i (car listel)
  1010. s (cdr listel))
  1011. (while (>= nrest i)
  1012. (setq string (concat string s)
  1013. nrest (- nrest i))))
  1014. string))
  1015. (provide 'reftex-parse)
  1016. ;;; reftex-parse.el ends here
  1017. ;; Local Variables:
  1018. ;; generated-autoload-file: "reftex.el"
  1019. ;; End: