
Tengo dos .bib
archivos que quiero usar en mi bibliografía. Las entradas no se superponen. He encontrado bastantes temas en foros sobre eso, pero ninguno de ellos realmente me satisfizo. Entonces mi idea es fusionar los dos en un .bib
archivo que usaré en el archivo .tex
. Lo más conveniente es que esto se haga desde LaTeX (por lo que no uso bibtool
software de referencia ni de ). Entonces, hice una macro para fusionar dos archivos:
\newwrite\bibwrite
\newcommand{\concatbib}[2]{%
\begingroup
\IfFileExists{#1}%
{\CatchFileDef{\bibone}{#1}{}}
{\let\bibone\empty}
\IfFileExists{#2}%
{\CatchFileDef{\bibtwo}{#2}{}}
{\let\bibtwo\empty}%
\immediate\openout\bibwrite=MyBib.bib\relax
\immediate\write\bibwrite{\bibone \bibtwo}%
\immediate\closeout\bibwrite
\endgroup
}
que básicamente está tomado de otra pregunta (¿Cómo puedo abrir un archivo en modo "añadir"?). Ahora el problema es que Latex quiere interpretar el contenido del archivo y cosas como \noexpand
no \detokenize
funcionaron como se deseaba. Así que tengo que leerlo palabra por palabra, lo cual intenté según la respuesta de Martin Scharrer aquí:Argumentos del comando de control.
\def\alltext{
\begingroup
\let\do\@makeother % define \do to change the category code of its argument to 'other'
\dospecials % makro that is a string of every special character preceeded with \do -> all catcodes are changed
\all@text
}
\def\all@text#1{
\endgroup
#1
}
y usaría esto dentro de la otra macro. Sin embargo, al probarlo solo, aparece el error "Uso de \all
no coincide con su definición" \alltext
y creo que me estoy perdiendo un punto importante aquí.
- Creo que puse la definición de
\all@text
after\alltext
para poder cerrar el grupo, que a mi entender necesito definir la región donde se alteran los catcodes. Pero no veo por qué\all@text
debería saberse ya en la definición de\alltext
? - Hasta ahora entendía que
\@...
los comandos son comandos primitivos, pero pensé que era solo una notación. ¿Hay más? - ¿Hay alguna manera de hacer que ese código funcione?
Respuesta1
No estoy seguro de si me falta algo acerca de su configuración, pero ¿necesita siquiera combinar los dos .bib
archivos? Si se llaman, digamos, biblio1.bib
y biblio2.bib
, BibTeX y LaTeX pueden acceder a ambos archivos fácilmente a través de la declaración
\bibliography{biblio1,biblio2}
Si utiliza el biblatex
paquete, entiendo que el estilo preferido es utilizar un par de \addbibresource
declaraciones separadas (consulte la sección 3.6.1 del paquetemanual):
\addbibresource{biblio1.bib}
\addbibresource{biblio2.bib}
Observe que es necesario proporcionar la extensión del nombre del archivo .bib
cuando se usa el \addbibresource
comando, mientras que no se debe proporcionar esta extensión cuando se usa el \bibliography
comando.
Respuesta2
Si realmente quieres hacerlo a nivel TeX (lo cual no es realmente necesario porque puedes ingresar tantos .bib
archivos como quieras), aquí tienes un conjunto de macros para hacerlo. Puede dar como argumento obligatorio \concatbib
cualquier número de nombres de archivos bib (sin extensión), separados por comas.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% The document level command
\NewDocumentCommand{\concatbib}{ O{output} m }
{
\heinrich_concatbib:nn { #1 } { #2 }
}
% Variables and messages
\ior_new:N \l__heinrich_input_stream
\iow_new:N \l__heinrich_output_stream
\msg_new:nnnn { concatbib } { file-exist }
{ File~`#1'~exists.~Not~overwriting.}
{ The~file~`#1'~already~exists.~I'll~ignore~this~command. }
% Internal functions
% First we check that the named output file doesn't exist
\cs_new_protected:Npn \heinrich_concatbib:nn #1 #2
{
\file_if_exist:nTF { #1.bib }
{
\msg_error:nnn { concatbib } { file-exist } { #1.bib }
}
{
\__heinrich_concatbib_aux:nn { #1 } { #2 }
}
}
% If we're writing, we open an output stream and cycle
% through the second argument, a comma separated list
% of bib file names
\cs_new_protected:Npn \__heinrich_concatbib_aux:nn #1 #2
{
\iow_open:Nn \l__heinrich_output_stream { #1.bib }
\clist_map_inline:nn { #2 } { \__heinrich_read_write:n { ##1 } }
\iow_close:N \l__heinrich_output_stream
}
% At each step we read each line of the current .bib file
% and write it to the output stream
\cs_new_protected:Npn \__heinrich_read_write:n #1
{
\ior_open:Nn \l__heinrich_input_stream { #1.bib }
\ior_str_map_inline:Nn \l__heinrich_input_stream
{ \iow_now:Nn \l__heinrich_output_stream { ##1 } }
\ior_close:N \l__heinrich_input_stream
}
\ExplSyntaxOff
% This will concatenate in `output.bib'
\concatbib{foo1,foo2}
% This will concatenate in `foo.bib'
\concatbib[foo]{foo1,foo2}
Respuesta3
Hm... Soy un gran amigo de usar-la-herramienta-adecuada-para-la-tarea. Entonces, si bien es intelectualmente esclarecedor, no implementaría esto en LaTeX, sino que simplemente usaría las capacidades básicas del sistema operativo (no se requiere bibtool ni otras cosas sofisticadas):
En Linux/UNIX/MacOS, abra un bash (o cualquier shell o terminal) en el directorio respectivo e ingrese:
cat bibone.bib bibtwo.bib >MyBib.bib
En Windows, abra un mensaje CMD e ingrese:
type bibone.bib bibtwo.bib >MyBib.bib
En ambos sistemas también puedesadjuntara un MyBib.bib existente redirigiendo la salida con >>
en lugar de >
.