我有一个文件夹包含如下文件,
2007.pdf
2007_Q1.pdf
2007_Q10.pdf
...
2007_Q5.pdf
2007_Q6.pdf
2007_Q7.pdf
2007_Q8.pdf
2007_Q9.pdf
2008.pdf
2008_Q1.pdf
2008_Q10.pdf
2008_Q11.pdf
2008_Q12.pdf
2008_Q13.pdf
2008_Q14.pdf
2008_Q15.pdf
2008_Q16.pdf
2008_Q17.pdf
2008_Q18.pdf
2008_Q19.pdf
2008_Q2.pdf
2008_Q20.pdf
2008_Q21.pdf
2008_Q22.pdf
2008_Q23.pdf
2008_Q24.pdf
2008_Q25.pdf
2008_Q3.pdf
...
...
2008_Q6.pdf
2008_Q7.pdf
2008_Q8.pdf
2008_Q9.pdf
...
...
我还有一个 Excel 文件,可以按主题筛选这些问题。所以我很容易得到这样的列表,
2006 Q7
2006 Q24
2007 Q11
2007 Q24
2009 Q17
2009 Q23
对于每个主题。然后我使用 Notepad++ 获取
\includegraphics[scale=0.9]{2006_Q7} \\[2ex]
\includegraphics[scale=0.9]{2006_Q24} \\[2ex]
\includegraphics[scale=0.9]{2007_Q11} \\[2ex]
\includegraphics[scale=0.9]{2007_Q24} \\[2ex]
\includegraphics[scale=0.9]{2009_Q17} \\[2ex]
\includegraphics[scale=0.9]{2009_Q23} \\[2ex]
相当高效。最后,把它们放入文档中
\section*{Topic A}
\subsection*{2006}
\includegraphics[scale=0.9]{2006_Q7} \\[2ex]
\includegraphics[scale=0.9]{2006_Q24} \\[2ex]
\subsection*{2007}
\includegraphics[scale=0.9]{2007_Q11} \\[2ex]
\includegraphics[scale=0.9]{2007_Q24} \\[2ex]
\subsection*{2009}
\includegraphics[scale=0.9]{2009_Q17} \\[2ex]
\includegraphics[scale=0.9]{2009_Q23} \\[2ex]
问题
有没有更有效的设置(方式)来
2006 Q7
2006 Q24
2007 Q11
2007 Q24
2009 Q17
2009 Q23
到
\section*{Topic A}
\subsection*{2006}
\includegraphics[scale=0.9]{2006_Q7} \\[2ex]
\includegraphics[scale=0.9]{2006_Q24} \\[2ex]
\subsection*{2007}
\includegraphics[scale=0.9]{2007_Q11} \\[2ex]
\includegraphics[scale=0.9]{2007_Q24} \\[2ex]
\subsection*{2009}
\includegraphics[scale=0.9]{2009_Q17} \\[2ex]
\includegraphics[scale=0.9]{2009_Q23} \\[2ex]
所以我只需要手动生成主题 A、主题 B 和主题 C 等的问题列表?
谢谢。
答案1
假设数据包含在文件中,您可以执行以下操作:
\begin{filecontents*}{\jobname.lst}
2006 Q7
2006 Q24
2007 Q11
2007 Q24
2009 Q17
2009 Q23
\end{filecontents*}
\documentclass{article}
\usepackage{xparse}
\usepackage[draft]{graphicx}
\ExplSyntaxOn
\NewDocumentCommand{\makereport}{m}
{% #1 = filename
\chenstatsyu_makereport:n { #1 }
}
\ior_new:N \g_chenstatsyu_makereport_stream
\str_new:N \l__chenstatsyu_makereport_year_str
\cs_new_protected:Nn \chenstatsyu_makereport:n
{
\str_clear:N \l__chenstatsyu_makereport_year_str
\ior_open:Nn \g_chenstatsyu_makereport_stream { #1 }
\ior_map_inline:Nn \g_chenstatsyu_makereport_stream
{
\__chenstatsyu_makereport_entry:n { ##1 }
}
\ior_close:N \g_chenstatsyu_makereport_stream
}
\cs_new_protected:Nn \__chenstatsyu_makereport_entry:n
{
\__chenstatsyu_makereport_entry_aux:w #1 \q_stop
}
\cs_new_protected:Npn \__chenstatsyu_makereport_entry_aux:w #1 ~ #2 ~ \q_stop
{
\str_if_eq:VnTF \l__chenstatsyu_makereport_year_str { #1 }
{
\\[2ex]
}
{
\str_set:Nn \l__chenstatsyu_makereport_year_str { #1 }
\subsection*{#1}
}
\includegraphics[height=2cm]{#1_#2} % fix the option
}
\ExplSyntaxOff
\begin{document}
\section*{Topic A}
\makereport{\jobname.lst}
\end{document}
我使用draft
来显示文件名(图形文件是 的副本example-image.pdf
)。将选项修改为\includegraphics
以适合您(但我不建议使用scale
)。
如果数据是在 TeX 文件中给出的,最好使用明确的行终止符,这应该很容易通过 Excel 获得:
\documentclass{article}
\usepackage{xparse}
\usepackage[draft]{graphicx}
\ExplSyntaxOn
\NewDocumentCommand{\makereport}{m}
{% #1 = lines
\chenstatsyu_makereport:n { #1 }
}
\clist_new:N \l__chenstatsyu_makereport_data_clist
\str_new:N \l__chenstatsyu_makereport_year_str
\cs_new_protected:Nn \chenstatsyu_makereport:n
{
\str_clear:N \l__chenstatsyu_makereport_year_str
\clist_set:Nn \l__chenstatsyu_makereport_data_clist { #1 }
\clist_map_function:NN \l__chenstatsyu_makereport_data_clist \__chenstatsyu_makereport_entry:n
}
\cs_new_protected:Nn \__chenstatsyu_makereport_entry:n
{
\__chenstatsyu_makereport_entry_aux:w #1 \q_stop
}
\cs_new_protected:Npn \__chenstatsyu_makereport_entry_aux:w #1 ~ #2 \q_stop
{
\str_if_eq:VnTF \l__chenstatsyu_makereport_year_str { #1 }
{
\\[2ex]
}
{
\str_set:Nn \l__chenstatsyu_makereport_year_str { #1 }
\subsection*{#1}
}
\includegraphics[height=2cm]{#1_#2} % fix the option
}
\ExplSyntaxOff
\begin{document}
\section*{Topic A}
\makereport{
2006 Q7,
2006 Q24,
2007 Q11,
2007 Q24,
2009 Q17,
2009 Q23,
}
\end{document}
答案2
\documentclass{article}
\usepackage[demo]{graphicx}% lose demo in real document
\newread\zzz
\def\dozzz#1 #2 {%
\def\thissec{#1}%
\ifx\sec\thissec\else
\section*{\thissec}
\let\sec\thissec
\fi
\par\includegraphics[scale=.9]{#1_#2}}
\def\zzzstop{\par}
\def\sec{}
\begin{document}
\setlength\parskip{2ex plus 2ex}
\setlength\parindent{0pt}
\openin\zzz=zzz.txt
\loop
\ifeof\zzz
\else
\read\zzz to \tmp
\ifx\tmp\zzzstop\else
\expandafter\dozzz\tmp
\fi
\repeat
\closein\zzz
\end{document}
其中 zzz.txt 是
2006 Q7
2006 Q24
2007 Q11
2007 Q24
2009 Q17
2009 Q23
答案3
下面提供了一种基于 (La)TeX 的方法。
基于 (La)TeX 的方法可能有助于减少所需的外部程序数量。
减少所需的外部程序数量是否意味着提高效率又是另一个问题。
无论怎样,以下处理问题的方法是否可以被认为是有效的,在很大程度上取决于您的工作流程以及其他可用且正在使用的工具。
我有时会使用 MariaDB 等数据库管理系统,其中的数据可以以各种方式导出,例如 csv 格式。csv 格式的数据可以在 LaTeX 中通过 datatool 包进行处理。
有时我使用 PHP 脚本从数据库服务器获取数据并创建包含即将创建的完整文档的 (La)TeX 源代码的 .tex 文件。
在某些情况下,使用此类外部程序/工具对我来说似乎比摆弄 (La)TeX 中宏编程和输入解析的所有可能的陷阱和各种或多或少有趣的技巧更有效率。
但在很多情况下,使用数据库管理服务器和 PHP 脚本之类的东西对我来说就像用大锤砸坚果一样。;-)
您可以让 (La)TeX 通过 分配一个新的句柄来读取输入文件(我们称之为\MyReadHandle
)\newread\MyReadHandle
。
您可以通过让 (La)TeX 将输入文件关联到用于读取输入文件的句柄来让 (La)TeX 使输入文件可供读取。
您可以将 (La)TeX 关联到\MyReadHandle
名为我的输入文件.txt通过\openin\MyReadHandle=MyInputFile.txt
.
(某些 TeX 平台的文件系统可以使用带空格的文件名,因此允许将文件名嵌套在引号中:\openin\MyReadHandle="MyInputFile.txt"
. )
你可以让 (La)TeX 定义宏\LineJustRead
来扩展输入文件下一行的内容我的输入文件.txt通过\read\MyReadHandle to\LineJustRead
。
\MyReadHandle
您可以让 (La)TeX通过 检查是否到达关联文件的末尾\ifeof\MyReadHandle..\else..\fi
。
\MyReadHandle
您可以让 (La)TeX 取消与via当前关联的文件\closein\MyReadHandle
。
因此,您可以让 (La)TeX 逐行迭代读取您的 Excel 创建文件,以便通过某些解析宏\LineJustRead
来解析的扩展: 。\LineJustRead
\expandafter\MyParsingMacro\LineJustRead
由于 (La)TeX 通常会将输入中的几个连续空格折叠成一个空格标记,因此你可以使用如下代码
2006 Q7
2006 Q24
2007 Q11
2007 Q24
2009 Q17
2009 Q23
对于模式实例
<year><space token><question number>
例如,您可以附加 catcode-12-return,模式变为:
<year><space token><question number>^^M
,因此你可以用宏来解析
\def\MyParsingMacro#1 #2^^M{%
#1 is the year.
#2 is the question number.
}
\expandafter\MyParsingMacro\LineJustRead^^M
似乎在您问题中提供的场景中,您不需要从参数中删除前导/尾随空格标记的例程。
在其他类似的场景中,您可能有一天会需要它们。
因此,我在此示例中粘贴了一些用于删除空间的例程,尽管在这种特定场景中它们并不是必需的。
如果你不想要它们,
只需删除整个部分
可扩展删除前导和尾随空格。
在对 EXCEL 过滤器创建的列表的文件进行解析的部分中,
删除两行调用,\UD@TrimAllSurroundSpace
并取消注释它们下面的行。
\documentclass{article}
\usepackage[draft]{graphicx}
% verbatim-package is used only for \verbatiminput
% of newly created files.
\usepackage{verbatim}
\makeatletter
% patch \verbatim@processline to also show line-breaks and thus
% also visualize empty lines:
\def\verbatim@processline{%
\the\verbatim@line
{\normalfont\textit{$\mathit{\langle}$linebreak$\mathit{\rangle}$}}%
\par
}
\makeatother
\makeatletter
%%//////////////////////////////////////////////////////////////////////////////
%% SECTION LICENCE AND COPYRIGHT
%%
%% Copyright (C) 2007-2018 by Ulrich W. Diez ([email protected])
%%..............................................................................
%% This work may be distributed and/or modified under the conditions of the
%% LaTeX Project Public Licence (LPPL), either version 1.3 of this license or
%% (at your option) any later version.
%% (The latest version of this license is in:
%% http://www.latex-project.org/lppl.txt
%% and version 1.3 or later is part of all distributions of
%% LaTeX version 1999/12/01 or later.)
%% The author of this work is Ulrich Diez.
%% This work has the LPPL maintenance status ‘not maintained’.
%% Usage of any/every component of this work is at your own risk.
%% There is no warranty — neither for probably included documentation nor for
%% any other part/component of this work.
%% If something breaks, you usually may keep the pieces.
%%
%% EOF SECTION LICENCE AND COPYRIGHT
%%//////////////////////////////////////////////////////////////////////////////
%%
%%
%%//////////////////////////////////////////////////////////////////////////////
%% SECTION PARAPHERNALIA:
%%
%% \UD@firstoftwo, \UD@secondoftwo, \UD@Exchange, \UD@CheckWhetherNull,
%% \UD@CheckWhetherBlank
%%==============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@Exchange[2]{#2#1}%
%%------------------------------------------------------------------------------
%% Check whether argument is empty:
%%..............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
%%
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%------------------------------------------------------------------------------
%% Check whether argument is blank (empty or only spaces):
%%..............................................................................
%% -- Take advantage of the fact that TeX discards space tokens when
%% "fetching" _un_delimited arguments: --
%% \UD@CheckWhetherBlank{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that
%% argument which is to be checked is blank>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not blank}%
\newcommand\UD@CheckWhetherBlank[1]{%
\romannumeral\expandafter\expandafter\expandafter\UD@secondoftwo
\expandafter\UD@CheckWhetherNull\expandafter{\UD@firstoftwo#1{}.}%
}%
%%
%% EOF SECTION PARAPHERNALIA
%%//////////////////////////////////////////////////////////////////////////////
%%
%%
%%//////////////////////////////////////////////////////////////////////////////
%% SECTION EXPANDABLE REMOVAL OF LEADING AND TRAILING SPACES.
%%
%% - REQUIRES SECTION PARAPHERNALIA.
%%
%% The obscure case of removing several leading/trailing spaces was taken
%% into consideration.
%%
%% Removal of spaces was implemented in a way where no brace-stripping from
%% the arguments takes place.
%% Explicit-catcode-1/2-character-token-pairs remain untouched.
%%
%% Spaces interspersing the argument or hidden within braces will be left in
%% place.
%%
%% The arguments themselves do not get expanded.
%%
%% (For some obscure reason I don't remember any more I needed this in the
%% past.)
%%
%%==============================================================================
%% Check whether brace-balanced argument starts with a space-token
%%..............................................................................
%% \UD@CheckWhetherLeadingSpace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is a
%% space-token>}%
%% {<Tokens to be delivered in case <argument
%% which is to be checked>'s 1st token is not
%% a space-token>}%
\newcommand\UD@CheckWhetherLeadingSpace[1]{%
\romannumeral0\UD@CheckWhetherNull{#1}%
{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
{\expandafter\UD@secondoftwo\string{\UD@CheckWhetherLeadingSpaceB.#1 }{}}%
}%
\newcommand\UD@CheckWhetherLeadingSpaceB{}%
\long\def\UD@CheckWhetherLeadingSpaceB#1 {%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@secondoftwo#1{}}%
{\UD@Exchange{\UD@firstoftwo}}{\UD@Exchange{\UD@secondoftwo}}%
{\UD@Exchange{ }{\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter}\expandafter\expandafter
\expandafter}\expandafter\UD@secondoftwo\expandafter{\string}%
}%
%%==============================================================================
%% \UD@TrimAllLeadSpace{<action>}{<argument>}
%%..............................................................................
%% expandably removes all leading spaces from <argument> in case at least
%% one leading space is present.
%% Then
%% <action>{<argument without leading spaces>}
%% is performed.
%%==============================================================================
\newcommand\UD@TrimAllLeadSpace[2]{%
\romannumeral0\UD@TrimAllLeadSpaceLoop{#2}{#1}%
}%
\newcommand\UD@TrimAllLeadSpaceLoop[2]{%
\UD@CheckWhetherLeadingSpace{#1}%
{%
\expandafter\UD@TrimAllLeadSpaceLoop
\expandafter{\UD@removespace#1}{#2}%
}%
{ #2{#1}}%
}%
\newcommand\UD@removespace{}\UD@firstoftwo{\def\UD@removespace}{} {}%
%%==============================================================================
%% \UD@TrimAllTrailSpace{<action>}{<argument>}
%%..............................................................................
%% expandably removes all trailing spaces from <argument> in case at least
%% one trailing space is present.
%% Then
%% <action>{<argument without trailing spaces>}
%% is performed.
%%==============================================================================
\newcommand\UD@TrimAllTrailSpace[2]{%
\romannumeral0\UD@TrimTrailSpaceLoop{#2}{#1}%
}%
%%------------------------------------------------------------------------------
%% \UD@TrimTrailSpaceLoop{<list of space-delimited arguments>}{<action>}
%%..............................................................................
%% both extracts the first space-delimited argument from the <list of space-
%% delimited arguments> as {<current argument with one trailing space
%% removed>} and removes it from the <list of space-delimited arguments> for
%% obtaining the <remaining list of space delimited arguments> and passes
%% these two things and an empty list of <arguments preceding the current
%% argument gathered so far> and the <action> to perform at the end of the
%% iteration to \UD@CheckWhetherLastSpaceDelimitedItem.
%%
%% \UD@CheckWhetherLastSpaceDelimitedItem in turn does choose the next
%% action.
\newcommand\UD@TrimTrailSpaceLoop[2]{%
\UD@ObtainFirstSpaceDelimitedTokenSetLoop{.#1 \UD@SeLDom}{%
\expandafter\UD@CheckWhetherLastSpaceDelimitedItem
\expandafter{\UD@RemoveTokensTillNextSpace.#1 }%
}{}{#2}%
}%
%%------------------------------------------------------------------------------
%% Macros for \UD@ObtainFirstSpaceDelimitedTokenSetLoop.
%%
\newcommand*\UD@RemoveTokensTillNextSpace{}%
\long\def\UD@RemoveTokensTillNextSpace#1 {}%
\newcommand*\UD@BraceStripRemoveNextSpace{}%
\long\def\UD@BraceStripRemoveNextSpace#1 {#1}%
\newcommand*\UD@GetFirstSpaceDelimitedTokenSet{}%
\long\def\UD@GetFirstSpaceDelimitedTokenSet#1 #2\UD@SeLDom{#1 }%
\newcommand\UD@gobbledot{}%
\def\UD@gobbledot.{}%
%%------------------------------------------------------------------------------
%% \UD@ObtainFirstSpaceDelimitedTokenSetLoop%
%% {<list of space delimited arguments>}%
%% {<action>}%
%%
%% -> <action>{<first element of list of space delimited arguments>}%
%%...............................................................................
%% \UD@ObtainFirstSpaceDelimitedTokenSetLoop does--without unwanted brace-re-
%% moval--append the first space delimited argument from a
%% <list of space delimited arguments> as brace-delimited argument behind
%% a set of tokens given as <action>.
\newcommand\UD@ObtainFirstSpaceDelimitedTokenSetLoop[1]{%
\expandafter\UD@CheckWhetherNull
\expandafter{\UD@RemoveTokensTillNextSpace#1}{%
\expandafter\expandafter\expandafter\UD@Exchange
\expandafter\expandafter\expandafter{%
\expandafter\expandafter\expandafter{%
\expandafter\UD@gobbledot\UD@BraceStripRemoveNextSpace#1}}%
}{%
\expandafter\UD@ObtainFirstSpaceDelimitedTokenSetLoop
\expandafter{\UD@GetFirstSpaceDelimitedTokenSet#1}%
}%
}%
%%------------------------------------------------------------------------------
%% \UD@CheckWhetherLastSpaceDelimitedItem
%% {<remaining list of space delimited arguments>}%
%% {<current argument with one trailing space removed>}%
%% {<arguments preceding the current argument gathered
%% so far>}%
%% {<action>}%
%%..............................................................................
%% Case 1: <remaining list of space delimited arguments> is
%% empty.
%% We are done: Thus:
%% <space>% for terminating \romannumeral-expansion, and
%% <action>{<arguments preceding the current argument gathered so
%% far><current argument with one trailing space removed>}
%% Case 2: <remaining list of space delimited arguments> consists of a single
%% space.
%% A trailing space was removed. There may be more. Thus:
%% \UD@TrimTrailSpaceLoop{%
%% <arguments preceding the current argument gathered so
%% far><current argument with one trailing space removed>%
%% }{<action>}%
%% Neither case 1 nor case 2:
%% The <current argument with one trailing space removed> is not the
%% last argument of the list, thus:
%% For the next iteration
%% - attach it and a trailing space to the <arguments preceding the
%% current argument gathered so far>,
%% - get the first space delimited argument of the <remaining list of
%% space delimited arguments> as <current argument with one trailing
%% space removed>
%% - remove that first space delimited argument from the <remaining list
%% of space delimited arguments>
\newcommand\UD@CheckWhetherLastSpaceDelimitedItem[4]{%
\UD@CheckWhetherNull{#1}{ #4{#3#2}}{%
\UD@CheckWhetherLeadingSpace{#1}{%
\expandafter\UD@CheckWhetherNull
\expandafter{\UD@removespace#1}{\UD@firstoftwo}{\UD@secondoftwo}%
}{\UD@secondoftwo}%
{\UD@TrimTrailSpaceLoop{#3#2}{#4}}%
{%
\UD@ObtainFirstSpaceDelimitedTokenSetLoop{.#1\UD@SeLDom}{%
\expandafter\UD@CheckWhetherLastSpaceDelimitedItem
\expandafter{\UD@RemoveTokensTillNextSpace.#1}%
}{#3#2 }{#4}%
}%
}%
}%
%%==============================================================================
%% \UD@TrimAllSurroundSpace{<action>}{<argument>}
%%..............................................................................
%% expandably removes all leading and trailing spaces from <argument> in
%% case at least one leading space is present.
%% Then
%% <action>{<argument without leading and trailing spaces>}
%% is performed.
%%==============================================================================
\newcommand\UD@TrimAllSurroundSpace[2]{%
\romannumeral\UD@TrimAllLeadSpace{\UD@TrimAllTrailSpace{0 #1}}{#2}%
}%
%%
%% EOF SECTION EXPANDABLE REMOVAL OF LEADING AND TRAILING SPACES.
%%//////////////////////////////////////////////////////////////////////////////
%%
%%
%%//////////////////////////////////////////////////////////////////////////////
%% SECTION PARSING FILES WITH LISTS CREATED BY THE EXCEL FILTER
%%
%% - REQUIRES MACRO \UD@TrimAllSurroundSpace FROM
%% SECTION EXPANDABLE REMOVAL OF LEADING AND TRAILING SPACES.
%%
%% - REQUIRES SECTION PARAPHERNALIA.
%% (Even when removing the calls to \UD@TrimAllSurroundSpace.)
%%
%%==============================================================================
%% \CreateSectioningFileFromExcelList{%
%% <phrase before sectioning titles>
%% }{%
%% <phrase behind sectioning titles>
%% }{%
%% <phrase before the name of the pdf-file>
%% }{%
%% <phrase bhind the name of the pdf-file>
%% }{%
%% <name of file with sectionings that is to be created>
%% }{%
%% <name of existing file that comes from the excel-filter>
%% }%
%%..............................................................................
%%
\newcommand\UD@LineFromFile{}
\newcommand\UD@YearInPreviousLine{}
\newcommand\UD@YearInThisLine{}
\newcommand\UD@ParseLine{}%
\newwrite\UD@SectioningFile
\newread\UD@TextFileByExcelFilter
\newif\ifUD@dontstopreading
%%
\begingroup
\endlinechar=-1\relax
\catcode`\^^M=12\relax
\UD@secondoftwo{}{%
\endgroup
\newcommand\CreateSectioningFileFromExcelList[6]{%
\begingroup
\renewcommand\UD@LineFromFile{}%
\renewcommand\UD@YearInPreviousLine{}%
\UD@dontstopreadingtrue
\let\do=\@makeother
\dospecials
\catcode`\ =10 %
\catcode`\^^M=10 %
\openin\UD@TextFileByExcelFilter=#6 %
\ifeof\UD@TextFileByExcelFilter
\expandafter\UD@firstoftwo
\else
\expandafter\UD@secondoftwo
\fi
{%
\@latex@warning@no@line{No file #6.}%
}{%
\IfFileExists{#5}{%
\@latex@warning@no@line{%
File `#5' already exists on the system.\MessageBreak
Not generating it from this source%
}%
}{%
\immediate\openout\UD@SectioningFile=#5 %
\loop
\ifeof\UD@TextFileByExcelFilter\UD@dontstopreadingfalse\fi
\ifUD@dontstopreading
\read\UD@TextFileByExcelFilter to\UD@LineFromFile
\expandafter\UD@CheckWhetherBlank\expandafter{\UD@LineFromFile}{}{%
\expandafter\UD@Exchange
\expandafter{\UD@LineFromFile^^M}{\UD@ParseLine{#1}{#2}{#3}{#4}}%
}%
\repeat
\immediate\closeout\UD@SectioningFile
}%
}%
\closein\UD@TextFileByExcelFilter
\endgroup
}%
%%
%%
\long\def\UD@ParseLine#1#2#3#4#5 #6^^M{%
\UD@TrimAllSurroundSpace{\def\UD@YearInThisLine}%
%\def\UD@YearInThisLine
{#5}%
\ifx\UD@YearInThisLine\UD@YearInPreviousLine
\expandafter\UD@firstoftwo
\else
\expandafter\UD@secondoftwo
\fi
{}{%
\immediate\write\UD@SectioningFile{%
#1\UD@YearInThisLine#2%
}%
}%
\immediate\write\UD@SectioningFile{%
#3%
\UD@YearInThisLine
\UD@CheckWhetherNull{#6}{}{%
\string_%
\UD@TrimAllSurroundSpace{\UD@secondoftwo{}}{#6}%
%#6%
}%
#4%
}%
\let\UD@YearInPreviousLine=\UD@YearInThisLine
}%
}%
\relax
%%
%% EOF SECTION PARSING FILES WITH LISTS CREATED BY THE EXCEL FILTER
%%//////////////////////////////////////////////////////////////////////////////
\makeatother
\edef\endgroupchar{\string}}%
\edef\begingroupchar{\string{}%
\begin{filecontents*}{FromExcel.txt}
2006
2006 Q7
2006 Q24
2007
2007 Q11
2007 Q24
2009 Q17
2009 Q23
\end{filecontents*}
\begin{document}
This is the content of FromExcel.txt
\verbatiminput*{FromExcel.txt}
\CreateSectioningFileFromExcelList{^^J\string\subsection\string*\begingroupchar}%
{\endgroupchar}%
{\string\includegraphics[scale=0.9]\begingroupchar}%
{\endgroupchar\space\string\\[2ex]}%
{MyPictureList.tex}%
{FromExcel.txt}
This is the content of MyPictureList.tex
\verbatiminput*{MyPictureList.tex}
%\input{MyPictureList.tex}
\end{document}