我目前正在寻找一个不错的、具有挑战性的开源项目,以便在完成论文后进行工作/合作。我没有计算机科学背景,但我想了解更多关于编译器构造我也想提高我的 TeX 技能,所以我想:一石二鸟。
我在考虑一个 LaTeX 软件包,它允许比软件包目前提供的更高级的语法突出显示列表listings
。我经常使用后者,发现它大部分都很好,但我发现它对于一些更高级的东西也非常令人沮丧。在 中,对具有上下文相关语法的语言实现正确的语法突出显示确实是一件令人头疼的事情listings
。此外,Unicode 不是“开箱即用”支持的。
当然,我们有minted
,,verbments
。pythontex
这些包成功释放了 Python 的强大功能,皮格门特斯在 TeX 的世界里;然而,语法高亮(颜色等)的定制需要编写/定制 Pygments 词法分析器;换句话说,它需要一些文件外的 Python 编码.tex
。如果一切都可以在不使用的情况下完成,那不是很好吗-shell-escape
?或者说,尝试在 TeX 中复制 Pygments 是没有意义的吗?
可以说,通过结合和fancyvrb
强大的 LaTeX3 软件包(例如),更强大的语法突出显示似乎更容易实现l3regex
。
- 我是不是在自欺欺人?这样的项目还有意义吗?还是我们应该满足于使用现有的工具(
listings
、minted
等)? - 如果不将其变成大列表,您觉得什么地方(如果有的话)让您感到沮丧
listings
?对于用于排版源代码的假设新软件包,您的愿望清单上会有什么? - 有谁有兴趣合作做这样的项目吗?请站起来。有人吗?你好……?
l3regex
在决定使用这样的包之前我应该了解哪些限制?
请在下面发表意见...
答案1
限制l3regex
第 12 页文档,在“PCRE 或 Perl 的以下功能肯定不会被实现”下:
- 递归:这是一个非常规特性。
- 反向引用:非常规特征,这需要回溯,但速度非常慢。
因此,看起来您将无法l3regex
单独使用来跟踪匹配/不匹配的括号(至少到任意深度),并且如果没有额外的工具,其他一些事情会变得复杂。
最终,问题可能是,“l3regex
考虑到我们无法匹敌 Pygments(至少在没有大量的工作...而且即使我们可以,也可能太慢了)?”
语法高亮状态
作为的作者pythontex
和新维护者minted
,以下是我对语法高亮状态的看法。
- 在我看来,使用 Python 的工具的主要缺点是性能。它们要么需要两次编译(
pythontex
),要么编译一次就很慢(minted
)。但我在开发版本,所以minted
我认为这已经解决了。 - 的第二个缺点
minted
是使用 存在潜在的安全问题\write18
。也许有人可以想出一种方法,将 Pygments 之类的东西添加到某种白名单中。(pythontex
不使用,\write18
因为它使用两次编译,中间运行 Python 脚本,因此对于突出显示但我还没有尝试确保它的安全性,因为它是为了执行Python 代码和语法高亮只是为了方便。) - 我认为没有理由不能创建一个用于自定义 Pygments 词法分析器的 TeX 接口,特别是如果调用 LuaTeX 的强大功能。我期望可以在 TeX 端收集设置,然后自动插入自定义 Pygments 词法分析器的 Python 模板中。(话虽如此,由于时间限制,至少在不久的将来,我没有任何尝试这样做的计划。)
- 对于语法高亮,我真正想看到的是 的更新版,易于定制
fancyvrb
。这将是构建未来语法高亮包的良好基础。特别是,以下功能将非常有用。- 内置对 Unicode 的支持(补丁
VerbatimOut
使用\detokenize
等) - 支持长线自动断线。
- 对字体相关问题进行错误检查(由于字体问题,波浪号可能会像上标一样升高,反引号可能需要
upquote
,等等) - 内置支持创建具有自定义名称的环境,然后自动连续编号此类环境的行,例如,所有 Python 代码都使用一个编号,而所有 C 代码都使用另一个编号。
framed
默认设置可以与、、等框架包很好地配合使用。mdframed
或者tcolorbox
至少可以与其中一个很好地配合使用的设置。- 用于创建样式的内置宏。
- 内置对 Unicode 的支持(补丁
答案2
我不认为语法高亮应该纯粹用 Tex 来完成,原因如下:
语言很复杂(上下文敏感),为了正确突出语法,您必须实现完整的编译器前端。例如,以下是一些简单的 C++ 代码:
struct foo; // foo is the name of a data type void f(foo param); // function f, taking a foo as parameter f(foo()); // 1 \color{type}{f}(\color{type}{Foo}); foo foo; // 2 \color{type}{foo} \color{variable}{foo}; f(foo()); // 3 \color{type}{f}(\color{variable}{foo});
好的高亮器需要知道 foo 是类名还是变量名。要确定这一点,您需要了解上下文。这个例子可能看起来有点不自然,但这种高亮问题在正常代码中随处可见,正确的高亮可以帮助理解代码,错误的高亮会让读者感到困惑。
好的突出显示是人们真正想要的,例如,参见 C# 的这个问题,其中类型和非类型应该有不同的颜色。
为了解决这个问题,你必须跟踪所有的声明(在许多语言中甚至需要更多(例如 C++))。基本上,你必须实现一个完整的编译器前端,我不确定这是否可以在 TeX 中有效地完成。举个例子,到目前为止,只有 5 个编译器理解 C++ 语言最新版本(2011 年发布)的语法。为了获得良好的突出显示效果,你必须这样做。
使用启发式方法,您可以提供一个可以突出显示代码的包,但这是 pygments 已经做到的,因此复制它没有任何意义。特别是如果情况变得更糟,我认为没有人会从 minted 更改为纯 LaTeX 包。您说只有 TeX 才能实现更好的定制。我不这么认为,因为颜色更改可以在例如 minted 中同样轻松地完成,而且更深入的更改并不常见,对于许多懂编程但不懂 TeX 的人来说,在 python 中应该更容易(这些人可能会在他们的文档中包含代码)。
有很多优秀的语法高亮工具每一个语言。但它们通常只提供 IDE 高亮,而不是 LaTeX 后端。对于 C++,人们可以轻松地使用 clang 来实现,我相信其他语言也可以做到这一点。用 TeX 重写它们毫无意义!
我认为需要解决的是与其他程序通信的方法。-shell-escape 不是处理此问题的最佳方法。恕我直言,已安装的软件包应该有权在需要时执行 shell-escape。因为我安装了它们,并且我信任维护它们的人。您不能利用 minted 执行 pygmentize 的事实(假设没有安全漏洞)。使用外部工具格式化代码没有错。
外部工具比 TeX 更快,即使与它们交互,TeX 也很难解决。据我所知,LaTeX 还不能有效地缓存输出。在我看来,这是应该做的事情。
总而言之,我认为你无法用纯 TeX 提供高质量的荧光笔。至于为偶尔使用而编写一个荧光笔,而这些使用对质量没有要求,我认为不值得。
答案3
总体而言,我对 比较满意listings
。事实上,listings
这也是我从 Word 转到 LyX,然后又转到 LaTeX 的原因。
我还觉得,多年来,它已经成为一段设计精良的代码,提供了出色的界面和良好的可扩展性。当我问我的问题时 如何自动跳过列表中的前导空格,我对在 Martin Scharrer 的答案中集成这样的功能的优雅和简单感到非常惊讶,这最终成为他的lstaddons
捆绑包的一部分。
长话短说: 中有很多做得非常好的东西
listings
,例如界面。让我们保留它们!我最怀念的是(除了正确的 unicode 支持,但到目前为止,我总是可以用技巧解决这个问题
literate
)更好的覆盖界面beamer
。我现在主要用listings
它来上 CS 课。虽然多年来,我在这方面已经开发出了很多习语和技巧(例如这里,这里,和这里)我仍然认为它们是解决方法。l3regex
但是,我确实明白有关上下文相关语言的观点,并且我还认为使用一般和其他高级包来解决这个问题的希望很小。我不太喜欢
minted
和其他依赖外部程序的软件包。除了编译时间问题(如果在beamer
包含数十个覆盖的框架中使用它们,这个问题可能会变得非常严重)和由此引起的一般安全问题之外,--shell-escape
还存在外部依赖问题:特别是在 Windows 世界中,不能假设用户已经正确python
安装。这使得minted
和类似的软件包在较大的协作设置中几乎无法使用。
因此,我认为可行的方法是(a)使用真正的编程语言进行词法分析和解析,(b)但使用内置的语言:Lua!
基本上,当今所有 TeX 发行版都包含
lualatex
,因此即使在 Windows 世界中(或在协作在线编辑器中,例如 WriteLatex),它们也可用。此外,所有常见的 IDE 都提供内置支持以用作lualatex
引擎。Lua 语言
lualatex
为 TeX 世界提供了良好的接口,两者可以以比外部程序更细的粒度相互交互。lualatex
提供对unicode的内置支持。尽管大多数用户(包括我)仍在使用
pdflatex
,但我相信向的转变lualatex
已经存在。即将推出的 TikZ 版本及其基于 Lua 的图形布局引擎无疑将成为这方面的加速器。
所以我的建议是:采用现有listings
包并扩展它,以便可以用 Lua 编写特定语言的扫描器和解析器。
理想情况下,此软件包的第一个版本将保持兼容,listings
并且lualatex
仅对高级功能或复杂功能有要求。这将允许大量重用并促进过渡。lualatex
如果有必要或大大简化实施,则后续版本可能通常依赖于。
答案4
正如 teknokrat 上面所说,用 TeX 编写 C 或 C++ 处理器会很困难。但是,您可以通过 libclang C 库运行您的程序。这是一个使用 clang C/C++ 编译器编译源文件的库。结果是指向文本的一组指针,称为游标。这些游标包含的源代码信息比 TeX 可以提取的任何信息都要多,因为它来自真正的编译器。列出清单将是这个的一个相当简单的应用。它也是生产质量编译器的一个相当不错的介绍。