在 Lua 中划分目录的正确方法是什么?

在 Lua 中划分目录的正确方法是什么?

我一直在尝试使用一些 Lua 代码来列出目录并将它们提供给 TeX 引擎。

我一直在使用这个Lua File System (lfs)模块。

第一部分列出当前目录(代码第 4 行),并使用 打印\,如下所示C:\Users\Admin\...

在第二部分中,我迭代了我作为变量提供的目录,

`local z="C:/test"`

如果我将其提供为:`local z =“C:\ test”这也有效

该库将其视为有效目录。我很好奇这在其他操作系统上的效果如何(我在 Windows 上测试过)以及这方面的最佳实践是什么。

在此处输入图片描述

完整的 MWE 列表如下。(警告:如果您单独测试,它可以打印数百页C:,请创建一个小的临时目录进行测试)。

\documentclass{tufte-book}
\usepackage[listings]{tcolorbox}
\lstloadlanguages{[LaTeX]TeX, [primitive]TeX}
\usepackage{luacode} % loads luatexbase as well
% Emphasis
%\renewcommand{\ttdefault}{cmtt}            % prefer old tt font
\newcommand\emphasis[2][blue]{\lstset{emph={exec,if,then,else,do,end,while,for,print,sprint,directlua,#2},
   emphstyle={\ttfamily\textcolor{#1}}}}%

\lstset{language={[LaTeX]TeX},
      escapeinside={{(*@}{@*)}}, 
      numbers=left, 
      gobble=0,
      stepnumber=1,numbersep=5pt, 
       numberstyle={\footnotesize\color{gray}},%firstnumber=last,
      breaklines=true,
      framesep=5pt,
      basicstyle=\small\ttfamily,
      showstringspaces=false,
      keywordstyle=\ttfamily\textcolor{blue},
      stringstyle=\color{orange},
      commentstyle=\color{black},
      rulecolor=\color{gray!10},
      breakatwhitespace=true,
     showspaces=false,  % shows spacing symbol
     xleftmargin=0pt,
     xrightmargin=5pt,
     aboveskip=3pt, % compact the code looks ugly in type
     belowskip=7pt,  % user responsible to insert any skips
      backgroundcolor=\color{gray!15}}
\begin{document}

%\begin{tcblisting}{} uncomment if you have the latest version of tcolorbox
\begin{luacode}
  require "lfs"
  local temp=lfs.currentdir()
  tex.sprint(-2, temp)
  tex.sprint("\\par")
  function attrdir (path)
    for file in lfs.dir(path) do
        if file ~= "." and file ~= ".." then
            local f = path..'/'..file
            tex.sprint (-1, f.."\\par     ")
            local attr = lfs.attributes (f)
            assert (type(attr) == "table")
            if attr.mode == "directory" then
                attrdir (f)
            else
               -- for name, value in pairs(attr) do
                    --tex.sprint (-2,name, value)
                -- end
            end
        end
    end
  end
  local z="C:/test"
  attrdir (z)
\end{luacode}
%\end{tcblisting}
\end{document}

答案1

您可以/在 Unix 和 Windows 上使用它作为路径分隔符。“google”告诉我 Windows 软件也接受它/作为分隔符,但您不能在命令行上使用它,因为它表示选项/命令行参数。

tex.sprint(-1, f.."\\par ")您不应该写,而应该写tex.tprint({-2 , f},{"\\par "}),然后您可以使用lfs.isdir()它来检查目录。否则,这是一个很好的解决方案。

答案2

我决定写一个答案。:)

总的来说,可移植性非常具有挑战性。通常最好的情况是编写不依赖于底层系统的代码。遗憾的是,有些情况下我们需要了解主机的内部情况。现在到了棘手的部分。

Patrick 的回答是正确的。:)在我看来,使用/路径分隔符通常是可移植的 - 当然,在极端情况下,某些设备甚至没有分层文件系统,但幸运的是,我们这里的情况并非如此。:)如果我们坚持使用 Windows/Unix/Linux/BSD/Mac 世界,我认为 是安全的/

一个依赖于底层系统的潜在问题是当我们谈论绝对路径。现在很棘手。我想避免为路径分配驱动器号或文件系统协议。我会使用相对路径并尝试从中完成工作。

我一直在问自己 Lua 是否真的有路径分隔符。它确实有,因为Lua 非官方常见问题解答告诉我们:

package.config是一个字符串,其中第一个“字符”是目录分隔符;因此package.config:sub(1,1)是斜杠或反斜杠。一般来说,在构建路径时尽量使用它。

我会坚持这样做,/因为它很有趣。:)不过,如果我们想依赖系统的路径分隔符,我会编写一个函数来构建路径,而不是对它们进行硬编码:

function getPath(...)
    local pathseparator = package.config:sub(1,1);
    local elements = {...}
    return table.concat(elements, pathseparator)
end

如果我想访问foo ► bar ► baz.txt,您可以使用getPath("foo","bar","baz.txt")它将为您提供:

foo\bar\baz.txt

在 Windows 中,或者:

foo/bar/baz.txt

在 Unix 及其朋友中。:)

答案3

我刚刚尝试在我崭新的台式机上玩你的代码

$ uname -a
OpenBSD oko.bagdala2.net 5.1 GENERIC.MP#188 i386

正如您所看到的,我正在使用将于 5 月 1 日发布的 OpenBSD 版本。

我的 Lua 版本是

 $ lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> 

我在这台机器上的 TeXLive 版本是

texlive_texmf-full-2011p0

这大致是去年七月发布的一个稳定版本。

我不确定你希望我用代码做什么,但是

$ luatex mama.tex
This is LuaTeX, Version beta-0.70.1-2012030705 (rev 4277) 
 restricted \write18 enabled.
(./mama.tex
! Undefined control sequence.
l.1 \documentclass
                  {tufte-book}

Lua 代码本身

$ lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> require "lfs"
stdin:1: module 'lfs' not found:
        no field package.preload['lfs']
        no file './lfs.lua'
        no file '/usr/local/share/lua/5.1/lfs.lua'
        no file '/usr/local/share/lua/5.1/lfs/init.lua'
        no file '/usr/local/lib/lua/5.1/lfs.lua'
        no file '/usr/local/lib/lua/5.1/lfs/init.lua'
        no file './lfs.so'
        no file '/usr/local/lib/lua/5.1/lfs.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'
stack traceback:
        [C]: in function 'require'
        stdin:1: in main chunk
        [C]: ?
> 

顺便说一下

z="C:/test"

完全无法移植。我做了快速修复,但您必须使用某种自动配置才能在各种操作系统上运行。

编辑:

感谢您的快速输入!正在运行路拉泰克斯在尖叫之后产生输出

! LaTeX Error: File `tcolorbox.sty' not found.

Type X to quit or <RETURN> to proceed,
or enter new name. (Default extension: sty)

! LaTeX Error: Unknown option `listings' for package `tcolorbox'.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.3 \lstloadlanguages
                     {[LaTeX]TeX, [primitive]TeX}
? 

但确实有输出。我没有改变塔夫特书类。同样的问题tcolorbox.sty(这是预期的)即使我使用文章类。你想让我把日志文件或 pdf 文件放在服务器上的某个地方吗?

另外使用 texlua 代替 lua 只需要使用 lua 脚本的一部分就可以

$ texlua mama.lua
mama.lua:3: attempt to call field 'sprint' (a nil value)

我猜这现在更有用了?

新编辑

将 tcolorbox.sty 添加到本地目录后,又出现了另一个问题

(/usr/local/share/texmf-dist/tex/latex/tools/verbatim.sty)
! I can't find file `tcblistings.code.tex'.
<to be read again> 
                   \futurelet 
l.299 \tcb@temp

Please type another input file name: 
! I can't find file `tcblistings.code'.
<to be read again> 
                   \futurelet 
l.299 \tcb@temp

我从网上下载并安装tcblistings.code.tex

之后 lualatex 就没再出什么问题了。pdf 文件只有一行

tcolorbox /home/predrag

碰巧这不是我编辑的文件(你的 C:/test)的目录

  local z="/home/predrag/Desktop/downloads"

但是,那是我保存您的 tex 源代码、样式文件和其他所需 tex 文件的目录。

我仍然不确定你试图做什么,但经过两次迭代后,它确实在 OpenBSD 上“工作”了。此时我猜它应该在 NetBSD 和 DragonFly BSD 上工作(注意 TeXLive 未移植到 FreeBSD)。

相关内容