57

mathematica.SE目前处于私人测试阶段,几天后将向公众开放。Stack Overflow 和相关站点使用prettify.js,但 Mathematica 不是受支持的语言。为我们的网站提供一个自定义突出显示脚本会非常棒,我请求 JavaScript 和 CSS 社区帮助开发这样的脚本和随附的 CSS。

我在下面列出了一些基本要求,以便它捕获 Mathematica 默认突出显示方案的大部分功能(忽略只有内部解析器知道的内容)。我还对颜色进行了通用命名——十六进制颜色代码可以从我提供的屏幕截图中选择(下文进一步说明)。我还添加了代码示例来配合屏幕截图,以便人们可以测试它。

基本要求

  1. 注释
    这些输入为(* comment *)。因此,这些之间的任何内容都应以灰色突出显示。

  2. 字符串
    这些输入为"string"(不支持单引号),并应以粉红色突出显示。

  3. 运算符/简写符号
    除了标准+, -, *, /, ^, ==的 等,Mathematica 还有其他几个运算符和简写符号。最常遇到的有:

    @, @@, @@@, /@, //@, //, ~, /., //., ->, :>, /:, /;, :=, :^=, =., 
    &, |, ||, &&, _, __, ___, ;;, [[, ]], <<, >>, ~~, <>
    

    这些以及括号、方括号和大括号都应以黑色突出显示。

  4. Patterns 对象和槽
    Pattern 对象以字母开头,并带有______附加,例如x_x__x___。这些也可以在下划线后面有其他字母,如x_abc等。所有这些都应该以绿色突出显示。

    插槽是###,也可以后跟整数,如#1##4等,也应该是绿色的。

    这两个(模式对象和插槽)通常由上面第 3 点的运算符/括号/简写形式终止。

  5. 函数/变量
    函数和变量在这里是一个相当松散的术语,但用于本文的目的。任何不属于上述 4 的东西都可以用黑色突出显示。Mathematica 经常`在代码中使用反引号,应将其视为函数/变量名称的一部分。例如,abcd`defg。变量名称中任何位置的美元符号$都应像字母一样对待(即,没什么特别的)。

对于上述所有内容,如果它们出现在字符串中,则应将其视为此类,即"@~#应以粉红色突出显示。

额外的好东西:

  1. 在上面第 3 点的模式对象中,如果下划线后面跟着 a?和一些字母,那么后面的部分_应该是黑色的。例如,在 中x__?abc,该x__部分必须为绿色,而该部分?abc为黑色。
  2. 如果函数/变量以大写字母开头,则以黑色突出显示。如果它以小写字母开头,则以蓝色突出显示。在内部,这区分了内置函数和用户定义函数。但是,mathematica 社区(几乎无处不在)很好地遵守了这种命名约定,因此区分两者将起到一定的作用。

屏幕截图和代码示例:

1.简单的例子

这是一个小示例集,最后有一个屏幕截图显示它在 Mathematica 中的外观:

(*simple pattern objects & operators*)
f[x_, y__] := x Times @@ y  

(*pattern objects with chars at the end and strings*)

f[x_String] := x <> "hello@world" 

(*pattern objects with ?xxx at the end*)

f[x_?MatrixQ] := x + Transpose@x

<< Combinatorica` (*example with backticks and inline comment*)

(*Slightly more complicated example with a mix of stuff*)

Developer`PartitionMap[Total, Range@1000, 3][[3 ;; -3]]~Partition~2 //
  Times @@@ # &

在此处输入图像描述

2. 一个真实世界的例子

这是我的这个答案的一个例子,它也表明了我在“附加的好东西”部分中的第 2 点,即小写的东西以蓝色突出显示。

此外,您可能会注意到一些以橙色突出显示的变量——我故意没有将其作为要求包括在内,因为我认为如果没有了解 Mathematica 的解析器,这将变得更加困难。

prob = MapIndexed[#1/#2 &, 
    Accumulate[
     EuclideanDistance[{0, 0}, #] < 1 & /@ arrows // Boole]]~N~4;

Manipulate[
 Graphics[{White, Rectangle[{-5, -5}, {5, 5}], Red, Disk[{0, 0}, 1], 
   Black, Point[arrows[[;; i]]], 
   Text[Style[First@prob[[i]], Bold, 18, "Helvetica"], {-4.5, 4.5}]}, 
  ImageSize -> 200], {i, Range[2, 20000, 1]}, 
 ControlType -> Manipulator, SaveDefinitions -> True]

在此处输入图像描述

这可行吗?太多了?太难?不可能的?

坦率地说,我不知道其中任何一个的答案。我刚刚列出了一些mathematica.SE 上每个人都希望拥有的基本功能,以及一些额外的东西,它们会是最重要的。但是,请让我知道这些是否难以实施。我们可以计算出更小的特征子集。

为表彰这一帮助,Mathematica 社区对你们所有人表示永远的感激之情,此外,我将向为此做出重大贡献的每个人奖励 500 元奖金(如果由不同的人部分完成)——我将依靠你们对答案进行投票/评论/输出以决定什么是重要的(如果他们做了所有的工作,可能会给一个人多于一份赏金)。无论以前的赏金如何,实施“额外的好东西”都会自动获得 +500,所以即使你不做前半部分,你也可以在别人的工作基础上再接再厉。我也可能会定期设置较小的赏金来吸引可能没有看到这个问题的用户,所以如果你碰巧获得了这些赏金,它们将是“奖励现有答案的赏金”的补充,这将在最后决定.

最后,我并不着急。所以请花点时间回答这个问题。在 SE 实施之前,赏金始终是一个选项(或者如果已确定现有答案完全满足要求)。理想情况下,我希望在 2 个月后的 beta 版中实现 2/3rs。

4

2 回答 2

43

前言

由于Mathematica对 google-code-prettify 的支持主要是为新的Mathematica.Stackexchange站点开发的,请参见此处的讨论。

介绍

我对所有这一切都没有深入的了解,但有时我为 Idea 编写了一个 cweb 插件来突出显示我的代码。在 IDE 中,这一切都不是一步完成的过程。它分为几个步骤,每个步骤都有更多的突出显示能力。让我稍微解释一下,以便稍后给出一些原因,为什么某些事情(恕我直言)对于我们需要的代码高亮器来说是不可能的。

首先,代码被拆分为标记,这些标记是编程语言的单个部分。在这个词法分析器之后,您可以将代码的间隔分类为例如空格、文字、字符串、注释等。这个词法分析器通过测试正则表达式、存储文本跨度的标记类型并在代码中前进来吃掉源代码。

在这个词法扫描之后,可以使用编程语言的规则、标记和底层代码来解析源代码。例如,如果我们有一个Plus类型的标记,Keyword那么我们知道括号和参数应该跟在后面。如果不是,则语法不正确。您可以使用此解析构建的东西称为 AST,抽象语法树,看起来基本上类似于TreeFormMathematica 语法。

使用精心设计的语言,例如 Java,可以在键入时检查代码,并且几乎不可能编写语法错误的代码。

prettify.js 和 Mathematica 代码

首先,prettify.js 只实现了一个词法扫描器,没有解析器。我很确定,关于显示网页的时间限制,无论如何这都是不可能的。所以让我解释一下 prettify.js 不可能/不可行的功能:

此外,您可能会注意到一些以橙色突出显示的变量——我故意没有将其作为要求包括在内,因为我认为如果没有了解 Mathematica 的解析器,这将变得更加困难。

对,因为这些变量的突出显示取决于上下文。你必须知道,你在一个Table构造或类似的东西里面。

黑客 prettify.js

我认为破解 prettify.js 的扩展并不难。我是一个绝对的正则表达式菜鸟,所以要准备好接下来的内容。

对于一个简单的 Mathematica 词法分析器,我们不需要这么多东西。我们有空格、注释、字符串文字、大括号、许多运算符、变量等常用文字和一个巨大的关键字列表。

让我们从 java-script regexp-form 中的关键字开始:

Export["google-code-prettify/keywordsmma.txt", 
   StringJoin @@ Riffle[Apply[StringJoin, 
         Partition[Riffle[Names[RegularExpression["[A-Z].*"]], 
             "|"], 100], {1}], "'+ \n '"], "TEXT"]

空格和字符串文字的正则表达式可以从另一种语言复制。评论与类似的东西相匹配

/^\(\*[\s\S]*?\*\)/

如果我们在评论中有评论,这会出错,但目前我不在乎。我们有大括号和方括号

/^(?:\[|\]|{|}|\(|\))/

我们有类似的东西blub_boing应该单独匹配。

/^[a-zA-Z$]+[a-zA-Z0-9$]*_+([a-zA-Z$]+[a-zA-Z0-9$]*)*/

我们有插槽#、##、#1、##9(目前只能跟随一位数字)

/^#+[0-9]?/

我们有变量名和其他文字。它们需要以字母或 $ 开头,然后可以跟随字母、数字和 $。目前\[Gamma]不匹配作为一种文字,但目前还可以。

/^[a-zA-Z$]+[a-zA-Z0-9$]*/

我们有运营商(我不确定这个列表是否完整)。

/^(?:\+|\-|\*|\/|,|;|\.|:|@|~|=|\>|\<|&|\||_|`|\^)/

更新

我稍微清理了一下这些东西,进行了一些调试,并创建了一种对我来说看起来很漂亮的颜色样式。据我所知,以下内容有效:

  • 所有可以找到的系统符号Names[RegularExpression["[A-Z].*"]]都匹配并以蓝色突出显示
  • 大括号和方括号是黑色但粗体字重。这是 Szabolcs 的建议,我非常喜欢它,因为它确实为代码的外观增添了一些活力
  • 模式,因为它们出现在函数定义中,纯函数的插槽以绿色突出显示。这是由 Yoda 提出的,并与 Mathematica 前端中的荧光笔一起使用。模式只有在与 in或 inblub__Integer等变量组合时才会显示为绿色。像 in 这样的模式的测试函数只有问号前面的绿色。a1_b34_Integer32num_?NumericQ
  • 注释和字符串具有相同的颜色。注释和字符串可以跨越几行。字符串可以包含反斜杠引号。评论不能嵌套。
  • 对于着色,我一直使用该ColorData[1]方案以确保颜色并排看起来不错。

目前它看起来像这样:

在此处输入图像描述

测试和调试

Szabolcs 询问是否以及如何进行测试。这很简单:您需要我的 google-code-prettify 源(我可以把它放在哪里,以便每个人都可以访问?)。解压缩源并tests/mathematica_test.html在网络浏览器中打开文件。该文件自己加载文件src/prettify.jssrc/lang-mma.js并且src/prettify-mma-1.css.

  • lang-mma.js您找到词法分析器在将代码拆分为标记时使用的正则表达式。
  • prettify-mma-1.css你找到我使用的样式定义

要测试您自己的代码,只需mathematica_test.html在编辑器中打开并在pre标签之间粘贴您的内容。重新加载页面,您的代码应该会出现。

调试:如果荧光笔无法正常工作,您可以使用 IDE 或 Google-Chrome 进行调试。在 Chrome 中,您标记荧光笔开始失效的单词并右键单击和Inspect Element. 然后你看到的是底层的 html-highlight 代码。在那里,您可以看到每个令牌,并且您可以看到令牌的类型。这看起来像

<span class="tag">[</span>

您会看到左括号的类型是tag。这与我在lang-mma.js. 在 Chrome 中,甚至可以在重新加载页面时浏览 JS 代码、设置断点和调试它。


Google Chrome 和 Firefox 的本地安装

蒂姆·斯通(Tim Stone)非常好心地编写了一个脚本,该脚本在加载http://stackoverflow.com/questions/. 一旦打开了 google-code-prettify,mathematica.stackexchange.com它也应该在那里工作。我调整了这个脚本来使用我的词法扫描规则和颜色。我听说在 Firefox 中脚本并不总是有效,但这是安装它的方法:

版本

https://github.com/halirutan/Mathematica-Source-Highlighting/raw/master/mathematica-source-highlighter.user.js下,您总能找到最新版本。这是一些更改历史。- 02/23/2013将符号和关键字列表更新到Mathematica版本 9.0.1 - 09/02/2012修复了 Mathematica 图案着色的一些小问题。有关Pattern-operator功能的详细概述,:另请参阅此处的讨论

  • 2012年 2 月 2 日支持许多数字输入格式,例如.123`10.2or 1.2`100.3*^-12,and 的高亮显示In[23]Out[4]::usage其他消息,例如blub::boing,模式的高亮显示ProblemTest[prob:(findp_[pfun_, pvars_, {popts___}, ___]), opts___],错误修复(我根据 AddOns 目录中的 3500 行包代码检查了解析器。它花了大约运行 3-4 秒,这对于我们的目的来说应该足够快了。)
  • 2012 年 1 月 30 日修复了缺失的“?” 在运营商列表中。包含的命名字符喜欢\\[Gamma]为此类符号提供完全匹配。在关键字列表中添加了 $variables。改进了模式的匹配。添加了上下文结构的匹配,如 Developer`PackedArrayQ。由于许多请求而切换颜色方案。现在就像在 Mathematica 前端一样。关键词黑色,变量蓝色。
  • 2012年 1 月 29 日,Tim 被黑客入侵以注入代码。现在突出显示也适用于mathematica.stackexchange。
  • 2012 年 1 月 25 日添加了对 Mathematica 数字的识别。这现在应该突出显示{1, 1.0, 1., .12, 16^^1.34f, ...}. 此外,它应该识别数字后面的反引号。我将注释和字符串切换为灰色,并使用深红色作为数字。
  • 2012 年 1 月 23 日初始版本。功能在更新部分中进行了描述。
于 2012-01-22T05:54:11.017 回答
2

不完全符合您的要求,但我为MATLAB创建了一个类似的扩展(基于此处已经完成的出色工作)。该项目托管在github 上

该脚本应解决 Stack Overflow 上 MATLAB 代码常见的一些问题:

  • 评论(无需使用类似的技巧%# ..
  • 转置运算符(单引号)被正确识别(默认美化器与带引号的字符串混淆)
  • 突出流行的内置功能

请记住,语法突出显示并不完美;除其他外,它在嵌套块注释上失败(我现在可以忍受)。与往常一样,欢迎评论/修复/问题。

包含一个单独的用户脚本,它允许切换使用的语言,如下面的屏幕截图所示:

- - 前 - -

前

- - 后 - -

后

对于那些感兴趣的人,提供了第三个用户脚本,适用于“MATLAB Answers”网站。


TL;博士

直接从以下位置安装 SO 的用户脚本:

https://github.com/amroamroamro/prettify-matlab/raw/master/js/prettify-matlab.user.js

于 2012-05-04T11:38:54.503 回答