花了很長時間尋找解決我的問題的方法,但所說的問題似乎不太適合“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.dat
和2-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,如上面一行所示。