
.bib
参考文献に使用したいファイルが 2 つあります。エントリは重複しません。これについてはフォーラムのトピックをいくつか見つけましたが、どれも満足できるものではありませんでした。そこで、2 つのファイルを 1 つの.bib
ファイルに結合して、 で使用することにしました.tex
。最も便利なのは、これを LaTeX 内から実行することです (そのためbibtool
、 や参照ソフトウェアは使用しません)。そこで、2 つのファイルを結合するマクロを作成しました。
\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
}
これは基本的に別の質問から引用したものです(ファイルを「追加」モードで開くにはどうすればいいですか?)。ここで問題となるのは、Latex がファイルの内容を解釈しようとするため、 などが\noexpand
期待\detokenize
どおりに動作しないことです。そのため、これを逐語的に読み取る必要がありますが、Martin Scharrer の回答に従って試してみました。制御コマンド引数。
\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
}
\all
そして、これを他のマクロ内で使用します。ただし、単独でテストすると、「 の使用がその定義と一致しない」というエラーが発生し\alltext
、ここで大きなポイントを見逃していると思います。
- グループを閉じるためにの定義を
\all@text
の後に置いたと思いますが、私の理解では、catcodes が変更される領域を定義する必要があります。しかし、 の定義で がすでにわかっている必要がある\alltext
理由がわかりません。\all@text
\alltext
- これまで、
\@...
コマンドはプリミティブコマンドであると理解していましたが、それは単なる表記法だと思っていました。それ以上の何かがあるのでしょうか? - そのコードを動作させる方法はありますか?
答え1
設定について何か見落としているのかどうかわかりませんが、2つの.bib
ファイルを結合する必要はあるのでしょうか?たとえば、とという名前であれば、biblio1.bib
BibTeXbiblio2.bib
とLaTeXは次のステートメントで簡単に両方のファイルにアクセスできます。
\bibliography{biblio1,biblio2}
パッケージを使用する場合biblatex
、別々のステートメントのペアを使用するのが望ましいスタイルだと理解しています\addbibresource
(パッケージのセクション3.6.1を参照)。マニュアル):
\addbibresource{biblio1.bib}
\addbibresource{biblio2.bib}
.bib
コマンドを使用する場合はファイル名拡張子を指定する必要があることに注意してください\addbibresource
。一方、 コマンドを使用する場合は、この拡張子を指定する必要はありません\bibliography
。
答え2
本当に TeX レベルで実行したい場合 (必要な数のファイルを入力できるため、これは実際には必要ありません)、これを実行するマクロのセットを次に示します。カンマで区切られた任意の数の bib ファイル名 (拡張子なし).bib
を必須引数として指定できます。\concatbib
\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}
答え3
うーん... 私は、タスクに適したツールを使用するという考え方を強く支持しています。したがって、知的に啓発されるとはいえ、これを LaTeX で実装するのではなく、基本的な OS 機能を使用するだけにします (bibtool やその他の高度な機能は必要ありません)。
Linux/UNIX/MacOS では、それぞれのディレクトリで bash (または任意のシェルやターミナル) を開き、次のように入力します。
cat bibone.bib bibtwo.bib >MyBib.bib
Windows では、CMD プロンプトを開いて次のように入力します。
type bibone.bib bibtwo.bib >MyBib.bib
どちらのシステムでも、追加>>
の代わりにを使用して出力をリダイレクトすることで、既存の MyBib.bib に追加します>
。