summaryrefslogtreecommitdiff
path: root/lisp/org/org-latex.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/org/org-latex.el')
-rw-r--r--lisp/org/org-latex.el357
1 files changed, 217 insertions, 140 deletions
diff --git a/lisp/org/org-latex.el b/lisp/org/org-latex.el
index 7b6970bbca9..bea5955ec5c 100644
--- a/lisp/org/org-latex.el
+++ b/lisp/org/org-latex.el
@@ -4,7 +4,7 @@
;;
;; Emacs Lisp Archive Entry
;; Filename: org-latex.el
-;; Version: 6.31a
+;; Version: 6.33
;; Author: Bastien Guerry <bzg AT altern DOT org>
;; Maintainer: Carsten Dominik <carsten.dominik AT gmail DOT com>
;; Keywords: org, wp, tex
@@ -94,7 +94,10 @@
\\usepackage[T1]{fontenc}
\\usepackage{graphicx}
\\usepackage{longtable}
+\\usepackage{float}
+\\usepackage{wrapfig}
\\usepackage{soul}
+\\usepackage{amssymb}
\\usepackage{hyperref}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
@@ -107,7 +110,10 @@
\\usepackage[T1]{fontenc}
\\usepackage{graphicx}
\\usepackage{longtable}
+\\usepackage{float}
+\\usepackage{wrapfig}
\\usepackage{soul}
+\\usepackage{amssymb}
\\usepackage{hyperref}"
("\\part{%s}" . "\\part*{%s}")
("\\chapter{%s}" . "\\chapter*{%s}")
@@ -120,7 +126,10 @@
\\usepackage[T1]{fontenc}
\\usepackage{graphicx}
\\usepackage{longtable}
+\\usepackage{float}
+\\usepackage{wrapfig}
\\usepackage{soul}
+\\usepackage{amssymb}
\\usepackage{hyperref}"
("\\part{%s}" . "\\part*{%s}")
("\\chapter{%s}" . "\\chapter*{%s}")
@@ -177,7 +186,7 @@ to represent the section title."
Each element of the list is a list of three elements.
The first element is the character used as a marker for fontification.
The second element is a formatting string to wrap fontified text with.
-If it is \"\\verb\", Org will automatically select a deimiter
+If it is \"\\verb\", Org will automatically select a delimiter
character that is not in the string.
The third element decides whether to protect converted text from other
conversions."
@@ -269,7 +278,7 @@ the %s stands here for the inserted headline and is mandatory.
It may also be a list of three string to define a user-defined environment
that should be used. The first string should be the like
\"\\begin{itemize}\", the second should be like \"\\item %s %s\" with up
-to two occurrences of %s for the title and a lable, respectively. The third
+to two occurrences of %s for the title and a label, respectively. The third
string should be like \"\\end{itemize\"."
:group 'org-export-latex
:type '(choice (const :tag "Ignore" nil)
@@ -284,7 +293,7 @@ string should be like \"\\end{itemize\"."
(string :tag "Use a section string" :value "\\subparagraph{%s}")))
(defcustom org-export-latex-list-parameters
- '(:cbon "\\texttt{[X]}" :cboff "\\texttt{[ ]}")
+ '(:cbon "$\\boxtimes$" :cboff "$\\Box$")
"Parameters for the LaTeX list exporter.
These parameters will be passed on to `org-list-to-latex', which in turn
will pass them (combined with the LaTeX default list parameters) to
@@ -389,12 +398,12 @@ as a command. %s in the command will be replaced by the full file name, %b
by the file base name (i.e. without extension).
The reason why this is a list is that it usually takes several runs of
pdflatex, maybe mixed with a call to bibtex. Org does not have a clever
-mechanism to detect whihc of these commands have to be run to get to a stable
+mechanism to detect which of these commands have to be run to get to a stable
result, and it also does not do any error checking.
Alternatively, this may be a Lisp function that does the processing, so you
could use this to apply the machinery of AUCTeX or the Emacs LaTeX mode.
-THis function should accept the file name as its single argument."
+This function should accept the file name as its single argument."
:group 'org-export-latex
:type '(choice (repeat :tag "Shell command sequence"
(string :tag "Shell command"))
@@ -481,7 +490,7 @@ in a window. A non-interactive call will only return the buffer."
(setq buffer "*Org LaTeX Export*"))
(let ((transient-mark-mode t) (zmacs-regions t)
ext-plist rtn)
- (setq ext-plist (plist-put ext-plist :ignore-subree-p t))
+ (setq ext-plist (plist-put ext-plist :ignore-subtree-p t))
(goto-char end)
(set-mark (point)) ;; to activate the region
(goto-char beg)
@@ -535,7 +544,7 @@ when PUB-DIR is set, use this as the publishing directory."
(rbeg (and region-p (region-beginning)))
(rend (and region-p (region-end)))
(subtree-p
- (if (plist-get opt-plist :ignore-subree-p)
+ (if (plist-get opt-plist :ignore-subtree-p)
nil
(when region-p
(save-excursion
@@ -977,7 +986,7 @@ OPT-PLIST is the options plist for current buffer."
;; insert author info
(if (plist-get opt-plist :author-info)
(format "\\author{%s}\n"
- (org-export-latex-fontify-headline (or author user-full-name)));????????????????????
+ (org-export-latex-fontify-headline (or author user-full-name)))
(format "%%\\author{%s}\n"
(or author user-full-name)))
;; insert the date
@@ -1000,7 +1009,9 @@ OPT-PLIST is the options plist for current buffer."
(format "\\setcounter{tocdepth}{%s}\n\\tableofcontents\n\\vspace*{1cm}\n"
(min toc (plist-get opt-plist :headline-levels))))
(toc (format "\\setcounter{tocdepth}{%s}\n\\tableofcontents\n\\vspace*{1cm}\n"
- (plist-get opt-plist :headline-levels))))))))
+ (plist-get opt-plist :headline-levels)))))
+ (when (plist-get opt-plist :preserve-breaks)
+ "\\obeylines\n"))))
(defun org-export-latex-first-lines (opt-plist &optional beg end)
"Export the first lines before first headline.
@@ -1124,6 +1135,15 @@ links, keywords, lists, tables, fixed-width"
;; the beginning of the buffer - inserting "\n" is safe here though.
(insert "\n" string)
(goto-char (point-min))
+ (let ((re (concat "\\\\[a-zA-Z]+\\(?:"
+ "\\[.*\\]"
+ "\\)?"
+ (org-create-multibrace-regexp "{" "}" 3))))
+ (while (re-search-forward re nil t)
+ (unless (save-excursion (goto-char (match-beginning 0))
+ (equal (char-after (point-at-bol)) ?#))
+ (add-text-properties (match-beginning 0) (match-end 0)
+ '(org-protected t)))))
(when (plist-get org-export-latex-options-plist :emphasize)
(org-export-latex-fontify))
(org-export-latex-keywords-maybe)
@@ -1151,13 +1171,14 @@ links, keywords, lists, tables, fixed-width"
'(("\\(\\s-\\)\"" "«~")
("\\(\\S-\\)\"" "~»")
("\\(\\s-\\)'" "`"))
- '(("\\(\\s-\\|(\\)\"" "``")
+ '(("\\(\\s-\\|[[(]\\)\"" "``")
("\\(\\S-\\)\"" "''")
("\\(\\s-\\|(\\)'" "`")))))
(mapc (lambda(l) (goto-char (point-min))
(while (re-search-forward (car l) nil t)
- (let ((rpl (concat (match-string 1) (cadr l))))
- (org-export-latex-protect-string rpl)
+ (let ((rpl (concat (match-string 1)
+ (org-export-latex-protect-string
+ (copy-sequence (cadr l))))))
(org-if-unprotected-1
(replace-match rpl t t))))) quote-rpl)))
@@ -1329,114 +1350,115 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
"Convert tables to LaTeX and INSERT it."
(goto-char (point-min))
(while (re-search-forward "^\\([ \t]*\\)|" nil t)
- (org-table-align)
- (let* ((beg (org-table-begin))
- (end (org-table-end))
- (raw-table (buffer-substring beg end))
- (org-table-last-alignment (copy-sequence org-table-last-alignment))
- (org-table-last-column-widths (copy-sequence
- org-table-last-column-widths))
- fnum fields line lines olines gr colgropen line-fmt align
- caption label attr floatp longtblp)
- (if org-export-latex-tables-verbatim
- (let* ((tbl (concat "\\begin{verbatim}\n" raw-table
- "\\end{verbatim}\n")))
- (apply 'delete-region (list beg end))
- (insert (org-export-latex-protect-string tbl)))
- (progn
- (setq caption (org-find-text-property-in-string
- 'org-caption raw-table)
- attr (org-find-text-property-in-string
- 'org-attributes raw-table)
- label (org-find-text-property-in-string
- 'org-label raw-table)
- longtblp (and attr (stringp attr)
- (string-match "\\<longtable\\>" attr))
- align (and attr (stringp attr)
- (string-match "\\<align=\\([^ \t\n\r,]+\\)" attr)
- (match-string 1 attr))
- floatp (or caption label))
- (setq lines (org-split-string raw-table "\n"))
- (apply 'delete-region (list beg end))
- (when org-export-table-remove-special-lines
- (setq lines (org-table-clean-before-export lines 'maybe-quoted)))
- (when org-table-clean-did-remove-column
+ (org-if-unprotected-at (1- (point))
+ (org-table-align)
+ (let* ((beg (org-table-begin))
+ (end (org-table-end))
+ (raw-table (buffer-substring beg end))
+ (org-table-last-alignment (copy-sequence org-table-last-alignment))
+ (org-table-last-column-widths (copy-sequence
+ org-table-last-column-widths))
+ fnum fields line lines olines gr colgropen line-fmt align
+ caption label attr floatp longtblp)
+ (if org-export-latex-tables-verbatim
+ (let* ((tbl (concat "\\begin{verbatim}\n" raw-table
+ "\\end{verbatim}\n")))
+ (apply 'delete-region (list beg end))
+ (insert (org-export-latex-protect-string tbl)))
+ (progn
+ (setq caption (org-find-text-property-in-string
+ 'org-caption raw-table)
+ attr (org-find-text-property-in-string
+ 'org-attributes raw-table)
+ label (org-find-text-property-in-string
+ 'org-label raw-table)
+ longtblp (and attr (stringp attr)
+ (string-match "\\<longtable\\>" attr))
+ align (and attr (stringp attr)
+ (string-match "\\<align=\\([^ \t\n\r,]+\\)" attr)
+ (match-string 1 attr))
+ floatp (or caption label))
+ (setq lines (org-split-string raw-table "\n"))
+ (apply 'delete-region (list beg end))
+ (when org-export-table-remove-special-lines
+ (setq lines (org-table-clean-before-export lines 'maybe-quoted)))
+ (when org-table-clean-did-remove-column
(pop org-table-last-alignment)
(pop org-table-last-column-widths))
- ;; make a formatting string to reflect aligment
- (setq olines lines)
- (while (and (not line-fmt) (setq line (pop olines)))
- (unless (string-match "^[ \t]*|-" line)
- (setq fields (org-split-string line "[ \t]*|[ \t]*"))
- (setq fnum (make-vector (length fields) 0))
- (setq line-fmt
- (mapconcat
- (lambda (x)
- (setq gr (pop org-table-colgroup-info))
- (format "%s%%s%s"
- (cond ((eq gr :start)
- (prog1 (if colgropen "|" "|")
- (setq colgropen t)))
- ((eq gr :startend)
- (prog1 (if colgropen "|" "|")
- (setq colgropen nil)))
- (t ""))
- (if (memq gr '(:end :startend))
- (progn (setq colgropen nil) "|")
- "")))
- fnum ""))))
- ;; fix double || in line-fmt
- (setq line-fmt (replace-regexp-in-string "||" "|" line-fmt))
- ;; maybe remove the first and last "|"
- (when (and (not org-export-latex-tables-column-borders)
- (string-match "^\\(|\\)?\\(.+\\)|$" line-fmt))
- (setq line-fmt (match-string 2 line-fmt)))
- ;; format alignment
- (unless align
- (setq align (apply 'format
- (cons line-fmt
- (mapcar (lambda (x) (if x "r" "l"))
- org-table-last-alignment)))))
- ;; prepare the table to send to orgtbl-to-latex
- (setq lines
- (mapcar
- (lambda(elem)
- (or (and (string-match "[ \t]*|-+" elem) 'hline)
- (org-split-string (org-trim elem) "|")))
- lines))
- (when insert
- (insert (org-export-latex-protect-string
- (concat
- (if longtblp
- (concat "\\begin{longtable}{" align "}\n")
- (if floatp "\\begin{table}[htb]\n"))
- (if (or floatp longtblp)
- (format
- "\\caption{%s%s}"
- (if label (concat "\\\label{" label "}") "")
- (or caption "")))
- (if longtblp "\\\\\n" "\n")
- (if (and org-export-latex-tables-centered (not longtblp))
- "\\begin{center}\n")
- (if (not longtblp) (concat "\\begin{tabular}{" align "}\n"))
- (orgtbl-to-latex
- lines
- `(:tstart nil :tend nil
- :hlend ,(if longtblp
- (format "\\\\
+ ;; make a formatting string to reflect alignment
+ (setq olines lines)
+ (while (and (not line-fmt) (setq line (pop olines)))
+ (unless (string-match "^[ \t]*|-" line)
+ (setq fields (org-split-string line "[ \t]*|[ \t]*"))
+ (setq fnum (make-vector (length fields) 0))
+ (setq line-fmt
+ (mapconcat
+ (lambda (x)
+ (setq gr (pop org-table-colgroup-info))
+ (format "%s%%s%s"
+ (cond ((eq gr :start)
+ (prog1 (if colgropen "|" "|")
+ (setq colgropen t)))
+ ((eq gr :startend)
+ (prog1 (if colgropen "|" "|")
+ (setq colgropen nil)))
+ (t ""))
+ (if (memq gr '(:end :startend))
+ (progn (setq colgropen nil) "|")
+ "")))
+ fnum ""))))
+ ;; fix double || in line-fmt
+ (setq line-fmt (replace-regexp-in-string "||" "|" line-fmt))
+ ;; maybe remove the first and last "|"
+ (when (and (not org-export-latex-tables-column-borders)
+ (string-match "^\\(|\\)?\\(.+\\)|$" line-fmt))
+ (setq line-fmt (match-string 2 line-fmt)))
+ ;; format alignment
+ (unless align
+ (setq align (apply 'format
+ (cons line-fmt
+ (mapcar (lambda (x) (if x "r" "l"))
+ org-table-last-alignment)))))
+ ;; prepare the table to send to orgtbl-to-latex
+ (setq lines
+ (mapcar
+ (lambda(elem)
+ (or (and (string-match "[ \t]*|-+" elem) 'hline)
+ (org-split-string (org-trim elem) "|")))
+ lines))
+ (when insert
+ (insert (org-export-latex-protect-string
+ (concat
+ (if longtblp
+ (concat "\\begin{longtable}{" align "}\n")
+ (if floatp "\\begin{table}[htb]\n"))
+ (if (or floatp longtblp)
+ (format
+ "\\caption{%s%s}"
+ (if label (concat "\\\label{" label "}") "")
+ (or caption "")))
+ (if longtblp "\\\\\n" "\n")
+ (if (and org-export-latex-tables-centered (not longtblp))
+ "\\begin{center}\n")
+ (if (not longtblp) (concat "\\begin{tabular}{" align "}\n"))
+ (orgtbl-to-latex
+ lines
+ `(:tstart nil :tend nil
+ :hlend ,(if longtblp
+ (format "\\\\
\\hline
\\endhead
\\hline\\multicolumn{%d}{r}{Continued on next page}\\
\\endfoot
\\endlastfoot" (length org-table-last-alignment))
- nil)))
- (if (not longtblp) (concat "\n\\end{tabular}"))
- (if longtblp "\n" (if org-export-latex-tables-centered
- "\n\\end{center}\n" "\n"))
- (if longtblp
- "\\end{longtable}"
- (if floatp "\\end{table}"))))
- "\n\n")))))))
+ nil)))
+ (if (not longtblp) (concat "\n\\end{tabular}"))
+ (if longtblp "\n" (if org-export-latex-tables-centered
+ "\n\\end{center}\n" "\n"))
+ (if longtblp
+ "\\end{longtable}"
+ (if floatp "\\end{table}"))))
+ "\n\n"))))))))
(defun org-export-latex-fontify ()
"Convert fontification to LaTeX."
@@ -1447,23 +1469,33 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
org-export-latex-emphasis-alist))
(beg (match-beginning 0))
(end (match-end 0))
- rpl)
+ rpl s)
(unless emph
(message "`org-export-latex-emphasis-alist' has no entry for formatting triggered by \"%s\""
(match-string 3)))
- (unless (or (get-text-property (1- (point)) 'org-protected)
+ (unless (or (and (get-text-property (- (point) 2) 'org-protected)
+ (not (get-text-property
+ (- (point) 2) 'org-verbatim-emph)))
(save-excursion
(goto-char (match-beginning 1))
(save-match-data
(and (org-at-table-p)
(string-match
"[|\n]" (buffer-substring beg end))))))
+ (setq s (match-string 4))
(setq rpl (concat (match-string 1)
(org-export-latex-emph-format (cadr emph)
(match-string 4))
(match-string 5)))
(if (caddr emph)
- (setq rpl (org-export-latex-protect-string rpl)))
+ (setq rpl (org-export-latex-protect-string rpl))
+ (save-match-data
+ (if (string-match "\\`.\\(\\\\[a-z]+{\\)\\(.*\\)\\(}\\).\\'" rpl)
+ (progn
+ (add-text-properties (match-beginning 1) (match-end 1)
+ '(org-protected t) rpl)
+ (add-text-properties (match-beginning 3) (match-end 3)
+ '(org-protected t) rpl)))))
(replace-match rpl t t)))
(backward-char)))
@@ -1496,8 +1528,7 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
(setq char (or (cdr (assoc char trans)) (concat "\\" char))
rtn (concat rtn char)))
(setq string (concat rtn string) format "\\texttt{%s}")))))
- (setq string (org-export-latex-protect-string
- (format format string))))
+ (format format string))
(defun org-export-latex-links ()
;; Make sure to use the LaTeX hyperref and graphicx package
@@ -1505,7 +1536,7 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
"Convert links to LaTeX."
(goto-char (point-min))
(while (re-search-forward org-bracket-link-analytic-regexp++ nil t)
- (org-if-unprotected
+ (org-if-unprotected-1
(goto-char (match-beginning 0))
(let* ((re-radio org-export-latex-all-targets-re)
(remove (list (match-beginning 0) (match-end 0)))
@@ -1521,7 +1552,6 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
(attr (or (org-find-text-property-in-string 'org-attributes raw-path)
(plist-get org-export-latex-options-plist :latex-image-options)))
(label (org-find-text-property-in-string 'org-label raw-path))
- (floatp (or label caption))
imgp radiop
;; define the path of the link
(path (cond
@@ -1551,20 +1581,11 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
raw-path))))))))
;; process with link inserting
(apply 'delete-region remove)
- (cond ((and imgp (plist-get org-export-latex-options-plist :inline-images))
+ (cond ((and imgp
+ (plist-get org-export-latex-options-plist :inline-images))
+ ;; OK, we need to inline an image
(insert
- (concat
- (if floatp "\\begin{figure}[htb]\n\\centering\n")
- (format "\\includegraphics[%s]{%s}\n"
- attr
- (if (file-name-absolute-p raw-path)
- (expand-file-name raw-path)
- raw-path))
- (if floatp
- (format "\\caption{%s%s}\n"
- (if label (concat "\\label{" label "}") "")
- (or caption "")))
- (if floatp "\\end{figure}"))))
+ (org-export-latex-format-image raw-path caption label attr)))
(coderefp
(insert (format
(org-export-get-coderef-format path desc)
@@ -1586,6 +1607,61 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
(insert (format "\\href{%s}{%s}" path desc)))
(t (insert "\\texttt{" desc "}")))))))
+
+(defun org-export-latex-format-image (path caption label attr)
+ "Format the image element, depending on user settings."
+ (let (floatp wrapp placement figenv)
+ (setq floatp (or caption label))
+ (when (and attr (stringp attr))
+ (if (string-match "[ \t]*\\<wrap\\>" attr)
+ (setq wrapp t floatp nil attr (replace-match "" t t attr)))
+ (if (string-match "[ \t]*\\<float\\>" attr)
+ (setq wrapp nil floatp t attr (replace-match "" t t attr))))
+
+ (setq placement
+ (cond
+ (wrapp "{l}{0.5\\textwidth}")
+ (floatp "[htb]")
+ (t "")))
+
+ (when (and attr (stringp attr)
+ (string-match "[ \t]*\\<placement=\\(\\S-+\\)" attr))
+ (setq placement (match-string 1 attr)
+ attr (replace-match "" t t attr)))
+ (setq attr (and attr (org-trim attr)))
+ (when (or (not attr) (= (length attr) 0))
+ (setq attr (cond (floatp "width=0.7\\textwidth")
+ (wrapp "width=0.48\\textwidth")
+ (t attr))))
+ (setq figenv
+ (cond
+ (wrapp "\\begin{wrapfigure}%placement
+\\centering
+\\includegraphics[%attr]{%path}
+\\caption{%labelcmd%caption}
+\\end{wrapfigure}")
+ (floatp "\\begin{figure}%placement
+\\centering
+\\includegraphics[%attr]{%path}
+\\caption{%labelcmd%caption}
+\\end{figure}")
+ (t "\\includegraphics[%attr]{%path}")))
+
+ (if (and (not label) (not caption)
+ (string-match "^\\\\caption{.*\n" figenv))
+ (setq figenv (replace-match "" t t figenv)))
+ (org-fill-template
+ figenv
+ (list (cons "path"
+ (if (file-name-absolute-p path)
+ (expand-file-name path)
+ path))
+ (cons "attr" attr)
+ (cons "labelcmd" (if label (format "\\label{%s}"
+ label)""))
+ (cons "caption" (or caption ""))
+ (cons "placement" (or placement ""))))))
+
(defun org-export-latex-protect-amp (s)
(while (string-match "\\([^\\\\]\\)\\(&\\)" s)
(setq s (replace-match (concat (match-string 1 s) "\\" (match-string 2 s))
@@ -1666,7 +1742,7 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
(concat "\\hspace*{1cm}" (match-string 2))) t t)
(beginning-of-line 1))
(if (looking-at "[ \t]*$")
- (insert "\\vspace*{1em}")
+ (insert (org-export-latex-protect-string "\\vspace*{1em}"))
(unless (looking-at ".*?[^ \t\n].*?\\\\\\\\[ \t]*$")
(end-of-line 1)
(insert "\\\\")))
@@ -1716,7 +1792,7 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
(while (re-search-forward
(concat "<<<?" org-export-latex-all-targets-re
">>>?\\((INVISIBLE)\\)?") nil t)
- (org-if-unprotected
+ (org-if-unprotected-at (+ (match-beginning 0) 2)
(replace-match
(org-export-latex-protect-string
(format "\\label{%s}%s" (save-match-data (org-solidify-link-text
@@ -1736,9 +1812,10 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
(goto-char (point-min))
(while (re-search-forward "\\[\\([0-9]+\\)\\]" nil t)
(org-if-unprotected
- (when (save-match-data
- (save-excursion (beginning-of-line)
- (looking-at "[^:|#]")))
+ (when (and (save-match-data
+ (save-excursion (beginning-of-line)
+ (looking-at "[^:|#]")))
+ (not (org-in-verbatim-emphasis)))
(let ((foot-beg (match-beginning 0))
(foot-end (match-end 0))
(foot-prefix (match-string 0))
@@ -1969,7 +2046,7 @@ The conversion is made depending of STRING-BEFORE and STRING-AFTER."
(when (consp x)
(add-to-list 'org-latex-entities-exceptions x)
(setq x (car x)))
- (if (string-match "[a-z][A-Z]$" x)
+ (if (string-match "[a-zA-Z]$" x)
(push x names)
(push x rest)))
(concat "\\(" (regexp-opt (nreverse names)) "\\>\\)"