Fusionar archivos bib desde LaTeX

Fusionar archivos bib desde LaTeX

Tengo dos .bibarchivos 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 .bibarchivo que usaré en el archivo .tex. Lo más conveniente es que esto se haga desde LaTeX (por lo que no uso bibtoolsoftware 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 \noexpandno \detokenizefuncionaron 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 \allno coincide con su definición" \alltexty creo que me estoy perdiendo un punto importante aquí.

  • Creo que puse la definición de \all@textafter \alltextpara poder cerrar el grupo, que a mi entender necesito definir la región donde se alteran los catcodes. Pero no veo por qué \all@textdeberí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 .bibarchivos? Si se llaman, digamos, biblio1.biby 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 biblatexpaquete, entiendo que el estilo preferido es utilizar un par de \addbibresourcedeclaraciones 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 .bibcuando se usa el \addbibresourcecomando, mientras que no se debe proporcionar esta extensión cuando se usa el \bibliographycomando.

Respuesta2

Si realmente quieres hacerlo a nivel TeX (lo cual no es realmente necesario porque puedes ingresar tantos .bibarchivos como quieras), aquí tienes un conjunto de macros para hacerlo. Puede dar como argumento obligatorio \concatbibcualquier 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 >.

información relacionada