從 LaTeX 合併書目文件

從 LaTeX 合併書目文件

.bib我想在參考書目中使用兩個文件。條目不重疊。我發現了很多關於此的論壇主題,但沒有一個真正令我滿意。所以我的想法是將兩個文件合併為一個.bib文件,我將在.tex.最方便的是,這可以在 LaTeX 中完成(所以我不使用bibtool或參考軟體)。因此,我製作了一個巨集來合併兩個檔案:

\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
}

我會在另一個巨集中使用它。不過,當我單獨測試它時,我得到了 Use of \alldoes not match itsdefinition的錯誤\alltext,我認為我在這裡遺漏了一個重要點。

  • \all@text我認為我放置了after的定義,\alltext這樣我就可以關閉該群組,據我了解,我需要定義更改目錄程式碼的區域。但我不明白為什麼\all@text在 的定義中應該已經知道\alltext
  • 到目前為止,我明白\@...命令是原始命令,但我認為這只是一種符號。還有更多嗎?
  • 有沒有辦法讓該程式碼運作?

答案1

我不確定我是否遺漏了您的設定的某些內容,但是您是否需要合併這兩個.bib文件?如果它們被命名為biblio1.biband biblio2.bib,BibTeX 和 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 中實現這一點,而只是使用基本的作業系統功能(不需要 bibtool 或其他花哨的東西):

在 Linux/UNIX/MacOS 上,在對應目錄中開啟 bash(或任何 shell 或終端)並輸入:

cat bibone.bib bibtwo.bib >MyBib.bib

在 Windows 上,開啟 CMD 提示字元並輸入:

type bibone.bib bibtwo.bib >MyBib.bib

在這兩個系統上,您還可以附加>>透過使用而不是重定向輸出到現有的 MyBib.bib >

相關內容