我想从.h
头部(C 语言)提取一个值并将该值用作 LaTeX 的输入。
举个例子,考虑defines.h
:
#define MEB_COM_PACKET_ID 0x01
.tex
在文档表上使用此值main.tex
:
\begin{table}[ht!]
\begin{tabularx}{0.5\textwidth}{l X}
Value & Description \\
\hline \hline
**MEB_COM_PACKET_ID** & balblabla blabla \\
\end{tabularx}
\end{table}
其中MEB_COM_PACKET_ID
将 更新为0x01
。
答案1
下面的示例使用 C 预处理器以一种格式获取定义的正确值,该格式可以轻松被 LaTeX 读取。
该文件defines_tex.c
包含所需的标头,这些标头被\iffalse
和包围\fi
。预处理器包含标头并传递 TeX 代码,因为 TeX 代码不包含预处理器指令。然后是 TeX 代码,它使用定义作为值来定义所需的宏,例如:
\newcommand*{\MebComPacketId}{MEB_COMP_PACKET_ID}
该 C 文件通过 C 预处理器运行:
gcc -E -P defines_tex.c >defines_tex.tex
启用 shell 转义后,可以从 LaTeX 内部调用 C 预处理器,或者在 LaTeX 运行之前调用它。
生成的TeX文件像往常一样包含在LaTeX中:
\input{defines_tex}
由于将 C 代码包装在\iffalse
and中,因此标头 C 代码将被忽略\fi
。(C 代码不应意外包含不匹配的 TeX 条件或不匹配的括号。)
完整示例:
\documentclass{article}
\usepackage{filecontents}
\usepackage{booktabs}
\usepackage{tabularx}
\begin{filecontents*}{defines_tex.c}
\iffalse
#include <stdio.h>
#include "defines.h"
\fi
\newcommand*{\MebComPacketId}{MEB_COM_PACKET_ID}
#ifdef MEB_COM_PACKET_NAME
\newcommand*{\MebComPacketName}{MEB_COM_PACKET_NAME}
#else
\newcommand*{\MebComPacketName}{unknown}
#endif
\newcommand*{\SeekCur}{SEEK_CUR}% from stdio.h
\end{filecontents*}
% Call of C preprocessor, when shell escape is enabled
\immediate\write18{gcc -E -P defines_tex.c >defines_tex.tex}
% Load the definition file
\input{defines_tex}
\begin{document}
% Use of the defined values
\begin{tabular}{ll}
\toprule
Variable & Value \\
\midrule
\verb|MEB_COM_PACKET_ID| & \MebComPacketId\\
\verb|MEB_COM_PACKET_NAME| & \MebComPacketName\\
\verb|SEEK_CUR| & \SeekCur\\
\bottomrule
\end{tabular}
\end{document}
答案2
这需要稍微改变\?{MEB_COM_PACKET_ID}
表中的语法。
\documentclass{article}
\usepackage{readarray,filecontents,ifthen,tabularx}
\begin{filecontents*}{defines.h}
#define MEB_COM_PACKET_ID 0x01
#define OTHER_ID 0x07
\end{filecontents*}
\newcommand\?[1]{\csname#1\endcsname}
\newcounter{defsindex}
\catcode`#=12 %
\def\ReadTheDefs{%
\readdef{defines.h}{\Definitions}
\readArrayij{\Definitions}{Defs}{3}
\whiledo{\value{defsindex} < \DefsROWS}{
\stepcounter{defsindex}%
\def\DEFROW{\arabic{defsindex}}%
\ifthenelse{\equal{\arrayij{Defs}{\DEFROW}{1}}{#define}}{%
\expandafter\xdef\csname\arrayij{Defs}{\DEFROW}{2}\endcsname{%
\arrayij{Defs}{\DEFROW}{3}}}{}%
}%
}
\catcode`#=6
\begin{document}
\begin{table}[ht!]
\catcode`#=12 \ReadTheDefs\catcode`#=6 %
\begin{tabularx}{0.5\textwidth}{l X}
Value & Description \\
\hline \hline
\?{MEB_COM_PACKET_ID} & balblabla blabla \\
\hline \hline
\?{OTHER_ID} & more stuff \\
\end{tabularx}
\end{table}
\end{document}
答案3
您可以使用以下设置从中提取内容defines.h
:
defines.h
捕获宏内部的文件内容(使用catchfile
;使用 TeX 的参数文本定义来提取适当的值。这就像模式识别定义一样,只提取与模式匹配的内容。
下面的例子实现了上述操作:
\documentclass{article}
\usepackage{catchfile,filecontents}
% Create a dummy defines.h
\begin{filecontents*}{defines.h}
#define MEB_COM_PACKET_ID_NAME abc
#define MEB_COM_PACKET_ID 0x01
#define MEB_COM_PACKET_TYPE def
\end{filecontents*}
\def\extractMEBNAME#1 MEB_COM_PACKET_ID_NAME #2 #3\@nil{#2}
\def\extractMEBID#1 MEB_COM_PACKET_ID #2 #3\@nil{#2}
\def\extractMEBTYPE#1 MEB_COM_PACKET_TYPE #2 #3\@nil{#2}
\begin{document}
\CatchFileDef{\defines}{defines.h}{\catcode`\#=11}% Capture defines.h into \defines (making # act like a regular letter)
\noindent
\begin{tabular}{l l}
Value & Description \\
\hline
\verb|MEB_COM_PACKET_ID_NAME| & \expandafter\extractMEBNAME\defines\@nil \\% Extract MEB_COM_PACKET_ID_NAME value
\verb|MEB_COM_PACKET_ID| & \expandafter\extractMEBID\defines\@nil \\% Extract MEB_COM_PACKET_ID value
\verb|MEB_COM_PACKET_TYPE| & \expandafter\extractMEBTYPE\defines\@nil \\% Extract MEB_COM_PACKET_TYPE value
\end{tabular}
\end{document}
请注意,如果上面(2)中使用的模式不存在,则会发生错误。
答案4
Werner 和 Steven 的答案的一个变体,假设defines.h
只包含以下形式的语句
#define VAR value
并且value
不包含@
(字符可以改变)。
这是示例文件
% Create a dummy defines.h
\begin{filecontents*}{defines.h}
#define MEB_COM_PACKET_ID_NAME abc
#define MEB_COM_PACKET_ID 0x01
#define MEB_COM_PACKET_TYPE def
\end{filecontents*}
\documentclass{article}
\usepackage{catchfile}
\begingroup
\CatchFileDef{\defines}{defines.h}{\catcode`\#=0 \endlinechar=`@ }
\def\define #1 #2@{\expandafter\gdef\csname#1\endcsname{#2}}
\defines
\endgroup
\newcommand{\?}[1]{%
\ifcsname#1\endcsname
\csname#1\endcsname
\else
UNDEFINED VAR
\fi
}
\begin{document}
\begin{tabular}{l l}
Value & Description \\
\hline
\verb|MEB_COM_PACKET_ID_NAME| & \?{MEB_COM_PACKET_ID_NAME} \\
\verb|MEB_COM_PACKET_ID| & \?{MEB_COM_PACKET_ID} \\
\verb|MEB_COM_PACKET_TYPE| & \?{MEB_COM_PACKET_TYPE} \\
\verb|WHATEVER| & \?{WHATEVER} \\
\end{tabular}
\end{document}