從單獨的檔案導入參數

從單獨的檔案導入參數

花了很長時間尋找解決我的問題的方法,但所說的問題似乎不太適合“google-eez”!

我的問題是:我有一個 Beamer 簡報要向不同的客戶展示。由於我喜歡自訂所述簡報以適合每個客戶的組織,因此在我的父Beamer .tex 檔案中,我有幾個程式碼“區塊”,每個區塊大約10 行,用於引入徽標、設定顏色、顯示組織名稱- 所有這些都可以服務向特定客戶「個人化」演示。當然,每個單獨客戶的演示都需要將另外 10 行程式碼區塊插入所述父 .tex 文件中。正如您可能想像的那樣,過了一段時間,這些「個人化區塊」就會混淆所述父 .tex 文件。

我想做的是創建單獨的“數據”文件,每個客戶一個,其中包含每個客戶獨有的詳細信息(或者,如果可能的話,存儲全部所說的客戶數據,來自全部客戶,進入單身的文件)。然後,我希望能夠使用父 .tex 文件中的一行,從正確的資料檔案中提取自訂資料。

斜體文本由 OP 於 2016 年 2 月 16 日新增: 請記住,我的願望是能夠在交付前幾天按需產生客製化簡報。

就像是:

\documentclass{beamer}
\usepackage{xcolor}

\newcommand{\nameoforg}{1st line from FileA.data}% Name of organization
\newcommand{\mainRGB}{2nd line from FileA.data}% Title color code
\newcommand{\backRGB}{3rd line from FileA.data}% Background color code
\newcommand{\clientlogowidth}{4th line from FileA.data}% Logo width
\newcommand{\clientlogo}{5th line from FileA.data}% Logo file name

\definecolor{mainslidecolor}{RGB}{\mainRGB}
\definecolor{backslidecolor}{RGB}{\backRGB}


\begin{document}

\title[\nameoforg]{Presentation Title}
\titlegraphic{\includegraphics[width=\clientlogowidth]{\clientlogo}}

\begin{frame}
this is boring
\end{frame}

\end{document}

文件A.txt當然,是“數據”文件之一(或者,也許是唯一我上面提到的這樣的文件(如果可能的話)。

我的一些研究似乎表明該catchfile包是我困境的答案,但我無法理解該包的文檔。

我怎樣才能做到這一點?而且,是否可以將我的所有「資料」檔案合併為一個檔案(我真的很想這樣做),或者最好將它們分開,一個給客戶?

答案1

我最初在評論中提到了這一點,並被要求將此作為答案發布。

在沒有其他套件的情況下執行此操作的另一種非常簡單的方法是將\newcommand聲明放在自己的.tex檔案中並使用\input來載入它們。也就是說,有:

% Name of organization
\newcommand{\nameoforg}{Organization A}
% Title color code
\newcommand{\mainRGB}{255,0,0}
% Background color code
\newcommand{\backRGB}{255,255,255}
% Logo width
\newcommand{\clientlogowidth}{6cm}
% Logo file name
\newcommand{\clientlogo}{example-image-a}

clientA.tex對於其他客戶也是如此。然後可以使用簡單的方法載入\input{clientA.tex}

\documentclass{beamer}
\usepackage{mwe}

\input{clientA.tex}

\definecolor{mainslidecolor}{RGB}{\mainRGB}
\definecolor{backslidecolor}{RGB}{\backRGB}

\title[\nameoforg]{Presentation Title}
\titlegraphic{\includegraphics[width=\clientlogowidth]{\clientlogo}}

\begin{document}
\begin{frame}
  \maketitle
\end{frame}

\begin{frame}
  Hello, World!
\end{frame}
\end{document}

正如其他人所示,這可以透過腳本進行擴展以批量生產幻燈片,儘管 Digger 似乎只需要一次創建一組幻燈片。

答案2

我將使用 shell 腳本來執行此操作,並\input為腳本中的每個客戶端定義檔案名,然後將其傳遞給命令pdflatex(或您正在使用的任何引擎)。

這是一個例子。對於每個客戶端,建立一個.tex包含該客戶端的相關定義的檔案。以下是三個範例檔案:

客戶端A.tex

\newcommand\clientname{Client A}
\newcommand\clienttheme{EastLansing}

客戶端B.tex

\newcommand\clientname{Client B}
\newcommand\clienttheme{Madrid}

客戶端C.tex

\newcommand\clientname{Client C}
\newcommand\clienttheme{Bergen}

文件的第一行client-presentation.tex(在 之前\documentclass)將包含以下行:

\InputIfFileExists{\clientfile}{}{\typeout{\detokenize{\clientfile}\ not found!}}

示範文件

\InputIfFileExists{\clientfile}{}{\typeout{\detokenize{\clientfile}\ not found!}}
\documentclass{beamer}
\usetheme{\clienttheme}
\title{My Presentation}
\author{Prepared for:\\\clientname}
\date{}
\begin{document}
\begin{frame}[plain]
\maketitle
\end{frame}
\begin{frame}
\begin{block}{This is a block}
\begin{itemize}
\item An item
\end{itemize}
\end{block}
\end{frame}
\end{document}

然後在命令列上,我們定義\clientfile並將其傳遞給pdflatex.單一文件如下所示:

pdflatex "\def\clientfile{clientA}\input{client-presentation}"

這將client-presentation.pdf使用 中定義的命令建立clientA.tex

一次性使用 shell 腳本

我們現在可以建立一個簡單的 shell 腳本,它採用客戶端檔案基本名和簡報檔案基本名,然後為該客戶端產生文件。由於該文件可能需要多次編譯來解析引用等,因此我習慣於latexmk進行編譯。這將確保在大多數情況下正確編譯文件。

#!/bin/sh
#Usage: first argument = client file base name, second = latex document base
latexmk -pdf -silent    \
        -jobname="$1_$2" \
        -pdflatex="pdflatex --file-line-error --shell-escape --synctex=1 %O '\def\clientfile{$1}\input{%S}'" $2.tex

用於自動化的 Shell 腳本

如果需要的話,我們現在可以一次自動產生一堆客戶端檔案。

#!/bin/sh
#Usage: pass the basename of the presentation file as an argument
for f in client*.tex; do
basefile=$(basename "$f")
if [ "${basefile%.*}" != "$1" ]
then
latexmk -pdf     \
        -jobname="${basefile%.*}_$1" \
        -pdflatex="pdflatex --file-line-error --shell-escape --synctex=1 %O '\def\clientfile{${basefile%.*}}\input{%S}'" $1.tex
fi
done

此 shell 腳本將簡報檔案的基本名稱作為參數,並為clientX.tex目前目錄中的每個檔案產生單獨的 PDF。

輸出範例:

在此輸入影像描述 在此輸入影像描述 在此輸入影像描述

答案3

您可以考慮使用鍵值介面方法。這不太脆弱,因為可以按任何順序指定鍵,而不必位於特定行上。

此外,如果特定客戶端缺少某些數據,鍵值包允許指定預設值,或在將來添加更多鍵時提供向後相容性。對於某些鍵值包,您可以將某些鍵標記為必需的或各種其他事情。基本上,它增加了很多靈活性。

這是該方法的一個基本範例。看每個 keyval 包的大列表有關軟體包的說明和 TUGboat 文章實現鍵值輸入:簡介 經過約瑟夫·賴特克里斯蒂安·費爾桑格介紹鍵值介面的想法和可能性。

\RequirePackage{filecontents}
\begin{filecontents*}{clientA.data}
\diggersetup{
  orgname = First Organization,
  mainRGB = {1,0,0},
  backRGB = {0,0,1},
  clientlogowidth = 1in,
  clientlogo = example-image-a,
}
\end{filecontents*}
\begin{filecontents*}{clientB.data}
\diggersetup{
  orgname = Second Organization,
  mainRGB = {1,1,0},
  backRGB = {0,1,0},
  clientlogowidth = 1.5in,
  clientlogo = example-image-b,
}
\end{filecontents*}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\documentclass{beamer}
\usetheme{Boadilla}

\usepackage{lmodern} % no font substitution warnings
\usepackage{graphicx}
\usepackage{keyval} % or your favorite key-value package of the month

\makeatletter
\newlength\clientlogowidth
\define@key{digger}{orgname}{\def\nameoforg{#1}}
\define@key{digger}{mainRGB}{\definecolor{mainslidecolor}{RGB}{#1}}
\define@key{digger}{backRGB}{\definecolor{backslidecolor}{RGB}{#1}}
\define@key{digger}{clientlogo}{\def\clientlogo{#1}}
\define@key{digger}{clientlogowidth}{\setlength\clientlogowidth{#1}}
\setkeys{digger}{ % default key settings
  orgname = No Name!, 
  mainRGB = {1,1,1}, 
  backRGB = {1,0,1}, 
  clientlogo = example-image, 
  clientlogowidth = 1in,
}
\newcommand{\diggersetup}[1]{\setkeys{digger}{#1}}
\makeatother

%-------------------------------------
\input{clientA.data}
%\input{clientB.data}
%-------------------------------------

\begin{document}

\title[\nameoforg]{Presentation Title}
\titlegraphic{\includegraphics[width=\clientlogowidth]{\clientlogo}}

\begin{frame}
\titlepage
\end{frame}

\begin{frame}
this is boring
\end{frame}
\end{document}

在此輸入影像描述

答案4

這是一個簡單的範例,說明如何使用textmerg.假設您知道每種情況下需要哪些變量,您可以為每個公司建立一個單獨的文件,然後將其「合併」到您的文件中。所以,給定這個文件(稱為,比如說,textmerg-example.dat

FooCo Inc.
rose
whale
serif
4cm
example-image

然後您可以像這樣設定您的投影機檔案:

\documentclass{beamer}%
\usepackage{mwe}% to get "example-image" named in .dat file
\usepackage{textmerg}
% the "Fields" are read and assigned in the order of the .dat file
\Fields{
\nameoforg
\myinnertheme
\myoutertheme
\myfonttheme
\clientlogowidth
\clientlogo
}
% Load the specific options
\Merge{textmerg-example.dat}{}% <-- note the second argument is empty because we are looping anything.

\usecolortheme{\myinnertheme}
\usecolortheme{\myoutertheme}
\usefonttheme{\myfonttheme}
\title[\nameoforg]{Presentation Title}
\titlegraphic{\includegraphics[width=\clientlogowidth]{\clientlogo}}


\begin{document}
\maketitle

\begin{frame}
\frametitle{Some Frame Title}

\nameoforg: This is boring\ldots
\end{frame}

\end{document}

顯然,您每次都需要相當仔細地考慮您可能想要更改的內容。

編輯如果您想使用一組不同的變數同時產生多個文件,那麼您可以修改上面的範例。讓我們來看兩個.dat文件:1-textmerg.dat2-textmerg.dat

FooCo Inc.
rose
whale
serif
4cm
example-image

SOME COMPANY
orchid
seahorse
default
7cm
example-image

然後我們對上面的beamer檔案進行這樣的修改:

% main.tex
\documentclass{beamer}%
\usepackage{mwe}% to get "example-image" named in .dat file
\usepackage{textmerg}
% the "Fields" are read and assigned in the order of the .dat file
\Fields{
\nameoforg
\myinnertheme
\myoutertheme
\myfonttheme
\clientlogowidth
\clientlogo
}
% Hack: we don't want to loop the file, so we leave the second argument empty
\providecommand{\tmdatanum}{1}% set a default input file
\Merge{\tmdatanum-textmerg.dat}{}
\usecolortheme{\myinnertheme}
\usecolortheme{\myoutertheme}
\usefonttheme{\myfonttheme}
\title[\nameoforg]{Presentation Title}
\titlegraphic{\includegraphics[width=\clientlogowidth]{\clientlogo}}


\begin{document}

\maketitle

\begin{frame}
\frametitle{Some Frame Title}

\nameoforg: This is boring\ldots

I have used \textbf{\myinnertheme\ \& \myoutertheme} as the inner and outer themes, with this as the client logo: \texttt{\clientlogo}.

\end{frame}

\end{document}

現在,為了一次產生所有不同的 PDF,我們可以使用以下方法:

for num in {1..2} ; do pdflatex -jobname=$num-beamer "\def\tmdatanum{$num}\input{main.tex}" ; done

這會挑選出(包含)在 1 和 2“之間”範圍內開始的文件,為它們分配相應的名稱1-2-beamer輸出,定義\tmdatanum在我們的非循環\Merge命令中使用的命令,然後輸入主項目文件, main.tex.結果應該是兩個單獨的文件,其中的設置在兩個不同的.dat文件中命名。

mergit或者,可以按照以下方式建立shell 腳本(稱為):

#!/bin/bash
#
# Usage: mergit [FILE] [Highest input file num]
#
MASTERFILE=$1
ENDNUMBER=$2
#
for ((num=1;num<=ENDNUMBER;num++))
do
  pdflatex -jobname=$num-beamer "\def\tmdatanum{$num}\input{$MASTERFILE.tex}"
done

因此,mergit main 2將建立兩個 PDF,如上面一行所示。

相關內容