Я хотел бы извлечь содержимое различных команд latex, например
- раздел
- глава
- подпись
- заметка на полях и т.д.
из .tex
файла. Эти элементы в конечном итоге окажутся в CSV-файле
chapter, chapter 1 title text
chapter, chapter 2 title text
figure, figure text
Требуется ли для этого регулярное выражение или это изобретение велосипеда?
Файл .tex
создается из документа Markdown с помощью pandoc.
Пример А
\documentclass{report}
\usepackage{hyperref}
\newcommand*\Quux{Pouet}
\begin{document}
\chapter[foo]{Foo}
\url{http://www.tex.org}
\end{document}
Я хотел бы извлечь главы и URL-адреса.
Пример Б
\documentclass{tufte-book}
\begin{document}
\chapter{A chap}
\marginnote{A note}
\end{document}
Я хотел бы извлечь заметку на полях
решение1
Вы можете использовать такой файл для инструментирования всех команд секционирования (назовем его instrumenter.tex
):
\RequirePackage{xparse}
\ExplSyntaxOn
\iow_new:N \l_csgillespie_iow
% #1: sectioning command name as a single token
% #2: character tokens representing the command name, without the backslash
\cs_new_protected:Npn \csgillespie_instrument_sec_cmd:Nn #1#2
{
% Save the original sectioning command
\cs_gset_eq:cN { g_csgillespie_#2_orig: } #1
\RenewDocumentCommand #1 { s O{##3} m }
{
\iow_now:Nn \l_csgillespie_iow { #2 ; ##2 ; ##3 }
\IfBooleanTF {##1}
{ \use:c { g_csgillespie_#2_orig: } * {##3} }
{ \use:c { g_csgillespie_#2_orig: } [##2] {##3} }
}
}
\cs_generate_variant:Nn \csgillespie_instrument_sec_cmd:Nn { c }
% #1: character tokens representing the command name, without the backslash
\cs_new_protected:Npn \csgillespie_instrument_sec_cmd_ifexists:n #1
{
\cs_if_exist:cT {#1}
{ \csgillespie_instrument_sec_cmd:cn {#1} {#1} }
}
\AtBeginDocument
{
\iow_open:Nn \l_csgillespie_iow { sectioning.csv }
\clist_map_inline:nn
{
part, chapter, section, subsection, subsubsection, paragraph,
subparagraph
}
{ \csgillespie_instrument_sec_cmd_ifexists:n {#1} }
}
\AtEndDocument { \iow_close:N \l_csgillespie_iow }
\ExplSyntaxOff
\endinput
Затем предположим, что вы хотите проверить файл с именем tested.tex
:
\documentclass{report}
\newcommand*\Quux{Pouet}
\begin{document}
\chapter[foo]{Foo}
\chapter{Bar \emph{Baz!}}
\chapter*{\Quux !}
\section{A \emph{section}!}
\section[Short title]{Another section}
\end{document}
Все, что вам нужно сделать, это указать instrumenter.tex
местоположение, имеющееся в TEXINPUTS
(возможно, в том же каталоге, что и tested.tex
), а затем запустить:
latex '\input instrumenter \input tested'
(одинарные кавычки здесь для оболочки, адаптируйте под свою оболочку). Вы получите файл, который называется sectioning.csv
в том же каталоге, что и tested.tex
выглядит так для этого примера:
chapter;foo;Foo
chapter;Bar \emph {Baz!};Bar \emph {Baz!}
chapter;\Quux !;\Quux !
section;A \emph {section}!;A \emph {section}!
section;Short title;Another section
Вы можете добавить двойные кавычки к выводу (или то, что вам нужно для формата CSV) на случай, если некоторые заголовки содержат разделитель в виде точки с запятой ( ;
). Просто добавьте их в строку, которая гласит:
\iow_now:Nn \l_csgillespie_iow { #2 ; ##2 ; ##3 }
Абзацы в аргументах
Если вы используете этот код для оборачивания других команд, и эти команды могут иметь \par
токены (например, пустые строки) в своих аргументах, то добавьте a +
перед соответствующими аргументами, например:
\RenewDocumentCommand #1 { s +O{##3} +m }
Соответствует O{##3}
необязательному аргументу упакованной команды (по умолчанию — значению обязательного аргумента), — m
ее обязательному аргументу. +
Не должен быть полезен для стандартных команд секционирования, но может быть полезен, если вы используете эту систему для регистрации аргументов других команд.
решение2
Пакет extract позволит вам сделать это:
https://www.ctan.org/tex-archive/macros/latex/contrib/extract
Документация в файле readme (extract.pdf) довольно хороша.