为了实习,我必须将 iOS 应用程序的所有源代码打印到 LaTeX 文件中。现在我想以结构化的方式执行此操作,为每个嵌套文件夹设置部分、子部分和子子部分...代码不会嵌套超过 3 层。等一下,让我将文件夹结构与我想要的进行比较。
此文件夹结构:
|____Source-master
| |____folderA
| | |____fileC.swift
| |____folderB
| | |____fileA.swift
| | |____folderC
| | | |____fileB.h
| | | |____fileB.m
应该变成这个 LaTeX 代码:
\section{Source-master}
\subsection{folderA}
\lstinputlisting{fileC.swift}
\subsection{folderB}
\lstinputlisting{fileC.swift}
\subsubsection{folderC}
\lstinputlisting{fileC.h}
\lstinputlisting{fileC.m}
我如何将文件系统中的文件转换为这种格式?我需要脚本吗?或者是否有可以导入的包来提供类似的命令\insertSourceRecursively{foldername}
?
答案1
也许我为了实现这一点而过于字面化地理解了 OP 提出的问题。但由于我没有访问磁盘目录结构来确定条目是文件还是文件夹,因此我依赖(如 OP 的 MWE 所示)文件夹名称以“folder”开头,文件名以“file”开头。虽然我可以开发其他方案,但问题仍然存在,即输入流必须以某种方式向解析器指示对象是文件还是文件夹。请参阅附录。
话虽如此,我还是|
激活了它并开始进行解析。如果文件结构试图低于该\subsection
级别,就会生成错误。此外,由于我确实没有这些名称的文件,因此我只是打印单词“lstinputlisting”后跟相对文件名,而不是实际调用列表宏。
\documentclass{article}
\usepackage{ifthen}
\newcommand\setlisting[2][]{lstinputlisting \csname Level#1\endcsname/#2}
\catcode`|=\active%
\def|#1____#2#3#4 {%
\ifx\relax#1\relax%
\section{#2#3#4}\def\LevelA{#2#3#4}%
\else%
\ifthenelse{\equal{\detokenize{#1}}{\detokenize{ |}}}%
{\if o#3\subsection{#2#3#4}\def\LevelB{\LevelA/#2#3#4}%
\else \setlisting[A]{#2#3#4}\fi}%
{\ifthenelse{\equal{\detokenize{#1}}{\detokenize{ | |}}}%
{\if o#3\subsubsection{#2#3#4}\def\LevelC{\LevelB/#2#3#4}%
\else \setlisting[B]{#2#3#4}\fi}%
{\ifthenelse{\equal{\detokenize{#1}}{\detokenize{ | | |}}}%
{\if o#3 ERROR: DIRECTORY LEVEL {#2#3#4} TOO DEEP%
\else \setlisting[C]{#2#3#4}\fi}%
{ERROR: {#2#3#4} TOO DEEP}%
}%
}%
\fi\par%
}%
\catcode`|=12
\newenvironment{filetree}{\catcode`|=\active}{}
\parindent 0pt
\begin{document}
\begin{filetree}
|____Source-master
| |____folderA
| | |____fileC.swift
| |____folderB
| | |____fileA.swift
| | |____folderC
| | | |____fileB.h
| | | |____fileB.m
| | | |____folderD
| | | | |____fileD
\end{filetree}
\end{document}
附录
如上所述,我的解析器需要一些关于目录和文件之间的区别的指导。在此替代实现中,对文件和文件夹本身的命名约定没有任何要求。但是,*
输入参数中的目录名称前面必须有一个星号。
\documentclass{article}
\usepackage{ifthen}
\newcommand\setlisting[2][]{lstinputlisting \csname Level#1\endcsname/#2}
\catcode`|=\active%
\def|#1____#2#3#4 {%
\ifx\relax#1\relax%
\section{#3#4}\def\LevelA{#3#4}%
\else%
\ifthenelse{\equal{\detokenize{#1}}{\detokenize{ |}}}%
{\if *#2\subsection{#3#4}\def\LevelB{\LevelA/#3#4}%
\else \setlisting[A]{#2#3#4}\fi}%
{\ifthenelse{\equal{\detokenize{#1}}{\detokenize{ | |}}}%
{\if *#2\subsubsection{#3#4}\def\LevelC{\LevelB/#3#4}%
\else \setlisting[B]{#2#3#4}\fi}%
{\ifthenelse{\equal{\detokenize{#1}}{\detokenize{ | | |}}}%
{\if *#2 ERROR: DIRECTORY LEVEL {#3#4} TOO DEEP%
\else \setlisting[C]{#2#3#4}\fi}%
{ERROR: {#2#3#4} TOO DEEP}%
}%
}%
\fi\par%
}%
\catcode`|=12
\newenvironment{filetree}{\catcode`|=\active}{}
\parindent 0pt
\begin{document}
\begin{filetree}
|____*Source-master
| |____*DirectoryA
| | |____fileC.swift
| |____*MyfolderB
| | |____fileA.swift
| | |____*folderC
| | | |____fileB.h
| | | |____fileB.m
| | | |____*folderD
| | | | |____fileD
\end{filetree}
\end{document}