reftex-parse.el 42 KB

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