![Как создать макрос, который манипулирует именем автора?](https://rvso.com/image/420046/%D0%9A%D0%B0%D0%BA%20%D1%81%D0%BE%D0%B7%D0%B4%D0%B0%D1%82%D1%8C%20%D0%BC%D0%B0%D0%BA%D1%80%D0%BE%D1%81%2C%20%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B9%20%D0%BC%D0%B0%D0%BD%D0%B8%D0%BF%D1%83%D0%BB%D0%B8%D1%80%D1%83%D0%B5%D1%82%20%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BC%20%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B0%3F.png)
Я хотел бы создать макрос, который мог бы брать информацию об имени автора, обычно объявляемую в макросе \author
, и разбивать ее на три части: имя, отчество и фамилия. Для этого можно создать внутренние макросы типа \firstname
, \midlename
и \lastname
. Затем макрос мог бы брать эту информацию и печатать ее в формате фамилия, имя и отчество. Например, я мог бы объявить имя \author{Alexsandro Lucena Mota}
и макрос, скажем, \newauthorname
, напечатал бы в документе pdf имя в форме Mota, Alexsandro Lucena
.
Примечание: \newauthorname
макрос был всего лишь предложением, которое, возможно, не было лучшим. Здесь намерение состоит в том, чтобы ссылаться на имя автора в библиографических ссылках, но в форме примера, приведенного выше, то есть . Mota, Alexsandro Lucena
Возможно, лучшим названием для этого макроса было бы \authornameinbibliographycitation
, однако, оно, безусловно, очень длинное. Чувствуйте себя свободно, внося свои предложения.
Известны ли какие-либо пакеты или макросы, способные это сделать?
Возможно, кто-то все еще спросит: «Зачем вам это нужно?»
В Бразилии в диссертациях и дипломных работах за титульным листом необходимо указывать каталожные данные, как в примере ниже.
Итак, я бы хотел, чтобы LaTeX напечатал имя автора в формате, показанном на рисунке выше.
Но кто-то все равно может спросить: почему вы не пишете от руки?
И ответ заключается в том, что я хотел бы создать пакет, чтобы пользователю нужно было только ввести свое имя в макрос \author
, а LaTeX позаботился бы обо всем остальном, автоматически сгенерировав файл.
И, наконец, кто-то попросит минимальный образец и по этой причине будет следовать кодексу дегустации.
\documentclass[12pt,a4paper]{memoir}
\usepackage{lastpage}
\title{Ficha catalográfica: um exemplo mínimo.}
\author{Alexsandro Lucena Mota}
\date{2020}
\begin{document}
\thispagestyle{empty}\null\vfill%
\begin{SingleSpacing}
\begin{center}
\begin{minipage}[c][][c]{13.5cm}
\begin{center}
{\small Ficha gerada por meio do SIGAA/Biblioteca
com dados fornecidos pelo
autor.}%
{\small N\'ucleo Integrado de Bibliotecas/UFMA}%
\end{center}
\end{minipage}
%
\begin{tabular}
[c]{|c|}\hline
\begin{minipage}[c][7.8cm][c]{13.1cm}%
\begin{adjustwidth}{0.5cm}{0.0cm}%
\texttt{Mota, Alexsandro
Lucena}\newline\texttt{\hspace*{0.55cm}\thetitle/
\theauthor. -- \thedate}
\newline\texttt{\hspace*{0.55cm}\pageref{LastPage}
p.}
\newline\newline\texttt{\hspace*{0.55cm}Orientador:
Prof. Dr. Fulando
Beltrano Silva Sauro.}
\newline\hspace{0.55cm}\texttt{Tese
(doutorado)~--~Programa de Pós-Graduação em
Física/ccet, Universidade Federal
do Maranhão, São Luís,
\thedate.}\newline\newline\texttt{\hspace*{0.55cm}1.
Ficha Catalográfica.~2. Exemplo Mínimo.~3.
LaTeX.~4. PDFLaTeX~I. Sauro, Fulando
Beltrano
Silva.~II. Título}
\end{adjustwidth}%
\end{minipage}%
\\\hline
\end{tabular}
\end{center}
\end{SingleSpacing}
\end{document}
Код выше производит
Поэтому я надеюсь, что предоставил достаточно информации, чтобы сориентировать вас в возможных ответах.
решение1
Проблема, которую я вижу в предоставлении команд, которые извлекают неявную информацию из , \author
заключается в том, что существует слишком много угловых случаев, чтобы сделать правильно. В идеале он должен правильно справляться с каждым из следующих вариантов использования:
\author{Alexsandro Lucena Mota}
\author{Doe}
\author{Jane Doe}
\author{Jane Maria Doe}
\author{Jane Maria Ellen Doe}
\author{Jane Maria de Lucca}
\author{Mota, Alexsandro Lucena}
Обработка первых пяти случаев довольно проста. Случай 6 требует накопления знаний обо всех многословных фамилиях на всех языках. Справиться со случаем 7 было бы возможно, но утомительно. Конечно, есть и другие проблемы, поскольку некоторые языки, такие как мандаринский, пишут имена в обратном порядке, с фамилией на первом месте.
Игнорируя все эти проблемы, код ниже определяет \Author
команду, которая устанавливает \firstname
, \middlename
а \lastname
также передает свой аргумент команде \author
. Как показано на рисунке ниже, он подходит для случаев 1-6, а случай 6 требует небольшой дополнительной помощи за счет добавления ~
. \Author
Команда не очень хорошо работает со случаем 7.
Вот код:
\documentclass[12pt,a4paper]{memoir}
\parindent0pt
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \g_firstname_tl
\tl_new:N \g_middlename_tl
\tl_new:N \g_lastname_tl
\seq_new:N \l_author_names_seq
\NewDocumentCommand\Author{m}{
\author{#1}
% clear the first, middle and last token lists
\tl_clear:N \g_firstname_tl
\tl_clear:N \g_middlename_tl
\tl_clear:N \g_lastname_tl
% trim spaces and split the author name(s) on surrounding spaces
\regex_split:nxN {\s+} { \tl_trim_spaces:n {#1} } \l_author_names_seq
\int_case:nnF {\seq_count:N \l_author_names_seq }
{
{0} {}
{1} {\seq_pop_left:NN \l_author_names_seq \g_lastname_tl }
{2} {
\seq_pop_left:NN \l_author_names_seq \g_firstname_tl
\seq_pop_left:NN \l_author_names_seq \g_lastname_tl
}
}
{
\seq_pop_left:NN \l_author_names_seq \g_firstname_tl
\seq_pop_right:NN \l_author_names_seq \g_lastname_tl
\tl_gset:Nx \g_middlename_tl { \seq_use:Nn \l_author_names_seq {\space} }
}
}
\cs_generate_variant:Nn \regex_split:nnN { nxN }
\NewDocumentCommand\firstname{}{\tl_use:N\g_firstname_tl}
\NewDocumentCommand\middlename{}{\tl_use:N\g_middlename_tl}
\NewDocumentCommand\lastname{}{\tl_use:N\g_lastname_tl}
\NewDocumentCommand\fullauthor{}{\lastname,\space\firstname\space\middlename}
\ExplSyntaxOff
\newcommand\Names[1]{\Author{#1}\textsf{Author:} #1.\newline \textit{First}: \firstname, \textit{Middle}: \middlename, \textit{Last}: \lastname.\par\medskip}
\begin{document}
\Names{Alexsandro Lucena Mota}
\Names{Doe}
\Names{Jane Doe}
\Names{Jane Maria Doe}
\Names{Jane Maria Ellen Doe}
\Names{Jane Maria de~Lucca}
\textbf{Fails}:
\Names{Mota, Alexsandro Lucena}
\end{document}
Идея достаточно проста: использоватьLaTeX3 обычные выражениячтобы разделить имена авторов на пробелы, а затем установить последнее "имя" как фамилию, любое оставшееся имя как имя, после чего все, что осталось, становится отчеством. Макрос \Names
- это просто вспомогательный макрос, показывающий, что \Author
он делает.
Код предоставляет \fullauthor
команду, которая печатает last name, first name middle name
. Я не вызывал ее, \newauthorname
потому что, как мне кажется, это команда, которую вы бы использовали дляопределятьавтору, не печатать его.
РЕДАКТИРОВАТЬ
Как и просили в комментариях, вот небольшая вариация, которая переопределяет \author
команду вместо определения новой \Author
команды. Если это будет использоваться часто, код в преамбуле можно поместить в файл стиля, скажем, fullauthor.sty
а затем включить в \usepackage{fullauthor}
.
\documentclass[12pt,a4paper]{article}
\parindent0pt
\let\realAuthor\author
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \g_firstname_tl
\tl_new:N \g_middlename_tl
\tl_new:N \g_lastname_tl
\seq_new:N \l_author_names_seq
\renewcommand\author[1]
{
\realAuthor{#1}
% clear the first, middle and last token lists
\tl_clear:N \g_firstname_tl
\tl_clear:N \g_middlename_tl
\tl_clear:N \g_lastname_tl
% trim spaces and split the author name(s) on surrounding spaces
\regex_split:nxN {\s+} { \tl_trim_spaces:n {#1} } \l_author_names_seq
\int_case:nnF {\seq_count:N \l_author_names_seq }
{
{0} {}
{1} {\seq_pop_left:NN \l_author_names_seq \g_lastname_tl }
{2} {
\seq_pop_left:NN \l_author_names_seq \g_firstname_tl
\seq_pop_left:NN \l_author_names_seq \g_lastname_tl
}
}
{
\seq_pop_left:NN \l_author_names_seq \g_firstname_tl
\seq_pop_right:NN \l_author_names_seq \g_lastname_tl
\tl_gset:Nx \g_middlename_tl { \seq_use:Nn \l_author_names_seq {\space} }
}
}
\cs_generate_variant:Nn \regex_split:nnN { nxN }
\NewDocumentCommand\firstname{}{\tl_use:N\g_firstname_tl}
\NewDocumentCommand\middlename{}{\tl_use:N\g_middlename_tl}
\NewDocumentCommand\lastname{}{\tl_use:N\g_lastname_tl}
\NewDocumentCommand\fullauthor{}{\lastname,\space\firstname\space\middlename}
\ExplSyntaxOff
\newcommand\Names[1]{\author{#1}\textsf{Author:} #1.\newline \textit{First}: \firstname, \textit{Middle}: \middlename, \textit{Last}: \lastname.\par\medskip}
\author{Alexsandro Lucena Mota} % using the new \author command in the preamble
\begin{document}
\fullauthor
\Names{Alexsandro Lucena Mota}
\Names{Doe}
\Names{Jane Doe}
\Names{Jane Maria Doe}
\Names{Jane Maria Ellen Doe}
\Names{Jane Maria de~Lucca}
\textbf{Fails}:
\Names{Mota, Alexsandro Lucena}
\end{document}
решение2
Здесь я привожу ответ — пример, основанный на коде из приведенного выше ответа @Andrew.
\documentclass[12pt,a4paper]{memoir}
\parindent0pt
\usepackage{lastpage}
\usepackage{xparse}
\let\realAuthor\author
\usepackage{xparse}
\ExplSyntaxOn
%\let\__real_author:n \author
\tl_new:N \g_firstname_tl
\tl_new:N \g_middlename_tl
\tl_new:N \g_lastname_tl
\seq_new:N \l_author_names_seq
\renewcommand\author[1]
{
%\realAuthor{#1}
% clear the first, middle and last token lists
\tl_clear:N \g_firstname_tl
\tl_clear:N \g_middlename_tl
\tl_clear:N \g_lastname_tl
% trim spaces and split the author name(s) on surrounding spaces
\regex_split:nxN {\s+} { \tl_trim_spaces:n {#1} }
\l_author_names_seq
\int_case:nnF {\seq_count:N \l_author_names_seq }
{
{0} {}
{1} {\seq_pop_left:NN \l_author_names_seq \g_lastname_tl }
{2} {
\seq_pop_left:NN \l_author_names_seq \g_firstname_tl
\seq_pop_left:NN \l_author_names_seq \g_lastname_tl
}
}
{
\seq_pop_left:NN \l_author_names_seq \g_firstname_tl
\seq_pop_right:NN \l_author_names_seq \g_lastname_tl
\tl_gset:Nx \g_middlename_tl { \seq_use:Nn
\l_author_names_seq {\space} }
}
}
\cs_generate_variant:Nn \regex_split:nnN { nxN }
\NewDocumentCommand\firstname{}{\tl_use:N\g_firstname_tl}
\NewDocumentCommand\middlename{}{\tl_use:N\g_middlename_tl}
\NewDocumentCommand\lastname{}{\tl_use:N\g_lastname_tl}
\NewDocumentCommand\theauthor{}{
\firstname\space\middlename\space\lastname}
\NewDocumentCommand\fullauthor{}{\lastname,
\space\firstname\space\middlename}
\ExplSyntaxOff
\title{Ficha catalográfica: um exemplo mínimo.}
\author{Alexsandro Lucena Mota} % using the new \author command
%in the preamble
\date{2020}
\begin{document}
\thispagestyle{empty}\null\vfill%
\theauthor\par\fullauthor
\begin{SingleSpacing}
\begin{center}
\begin{minipage}[c][][c]{13.5cm}
\begin{center}
{\small Ficha gerada por meio do
SIGAA/Biblioteca
com dados fornecidos pelo autor.\par%
N\'ucleo Integrado de Bibliotecas/UFMA}%
\end{center}
\end{minipage}
%
\begin{tabular}
[c]{|c|}\hline
\begin{minipage}[c][7.8cm][c]{13.1cm}%
\begin{adjustwidth}{0.5cm}{0.0cm}%
\texttt{\fullauthor}\newline\texttt{\hspace*{0.55cm}\thetitle/
\theauthor. -- \thedate}
\newline\texttt{\hspace*{0.55cm}\pageref{LastPage}
p.}
\newline\newline\texttt{\hspace*{0.55cm}Orientador:
Prof. Dr. Fulando
Beltrano Silva Sauro.}
\newline\hspace{0.55cm}\texttt{Tese
(doutorado)~--~Programa de
Pós-Graduação em
Física/ccet, Universidade Federal
do Maranhão, São Luís,
\thedate.}\newline\newline\texttt{\hspace*{0.55cm}1.
Ficha Catalográfica.~2. Exemplo
Mínimo.~3.
LaTeX.~4. PDFLaTeX~I. Sauro, Fulando
Beltrano
Silva.~II. Título}
\end{adjustwidth}%
\end{minipage}%
\\\hline
\end{tabular}
\end{center}
\end{SingleSpacing}
\end{document}
Этот код выдает именно тот ответ, который мы ожидали.