【问题标题】:Can prettify.js be extended to support Mathematica?可以扩展 prettify.js 以支持 Mathematica 吗?
【发布时间】:2012-02-15 23:29:46
【问题描述】:

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

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

基本要求

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

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

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

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

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

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

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

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

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

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

额外的好东西:

  1. 在上面第 3 点的模式对象中,如果下划线后面跟着一个 ? 和一些字母,那么 _ 后面的部分应该是黑色的。例如,在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。一个真实的例子

这是来自this answer of mine 的一个示例,它也表明了我在“其他优点”部分中的第 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 美元(如果部分由不同的人)——我将依靠你对答案的投票/cmets/输出来决定什么是重要的(如果他们做了所有的工作,可能会给一个人不止一笔赏金)。 无论之前的赏金如何,实施“额外的好东西”都会自动获得 +500,因此即使您不做前半部分,您也可以在其他人的工作的基础上再接再厉。我也可能会定期设置较小的赏金来吸引可能没有看到这个问题的用户,所以如果你碰巧获得了这些赏金,它们将是“奖励现有答案的赏金”的补充,这将在最后决定.

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

【问题讨论】:

  • 关于锦上添花的项目 #2:我敢肯定,开发流行的 Mathematica 软件包的人确实遵守大写约定,但在我的圈子里,他们只是简单地使用对于研究而言,这种约定几乎是闻所未闻的——从字面上看,没有人知道它。所以我不确定依赖它是否安全。话虽如此,也许在语法突出显示中“强制执行”约定可能会转换一些人。
  • @DavidZaslavsky 我的经验正好相反——开发流行包的人实际上确实使用大写名称(大部分情况下)。当然,这是在他们进行了彻底的测试以确保没有碰撞和阴影之后。从我在Stack Overflow 上看到的情况来看,大多数人都坚持使用小写字母,并且很快就会向其他人指出这个约定。我想这取决于他们是否看过 Mathematica 书——这是 Wolfram 建议的第一件事 :)
  • 啊,这很有道理。我的印象是,Mathematica 书并不像人们想象的那样“在野外”流行。
  • 你能再添加一个“很高兴拥有”吗?任何区分索引 (a[[i]]) 和函数 (f[x]) 的方法都非常好!如果可以处理嵌套的 cmets,这应该是可能的。
  • 另一个不错的选择:自动缩进 ala Mma?

标签: javascript css wolfram-mathematica prettify


【解决方案1】:

前言

由于 google-code-prettify 的 Mathematica support 主要是为新的 Mathematica.Stackexchange 站点开发的,请参阅讨论 here

简介

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

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

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

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

prettify.js 和 Mathematica 代码

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

此外,您可能会注意到一些以橙色突出显示的变量 - I 故意没有将其作为要求,因为我认为那是 如果没有一个知道的解析器,将很难做到 数学。

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

破解 prettify.js

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

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

让我们从 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]*?\*\)/

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

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

我们有类似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 前端中的荧光笔一起使用。模式只有在与 blub__Integera1_b34_Integer32 中的变量组合时才会显示为绿色。 num_?NumericQ 中的模式的测试函数只有问号前面的绿色。
  • 注释和字符串具有相同的颜色。注释和字符串可以跨越几行。字符串可以包含反斜杠引号。评论不能嵌套。
  • 对于着色,我一直使用ColorData[1] 方案,以确保颜色并排看起来很漂亮。

目前看起来是这样的:

测试与调试

Szabolcs 询问是否以及如何进行测试。这很简单:您需要我的 google-code-prettify 源(我可以把它放在哪里,以便每个人都可以访问?)。解压源代码并在网络浏览器中打开文件tests/mathematica_test.html。此文件会自行加载文件src/prettify.jssrc/lang-mma.jssrc/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/ 下的网站期间注入荧光笔。一旦为mathematica.stackexchange.com 启用了google-code-prettify,它也应该在那里工作。 我调整了这个脚本来使用我的词法扫描规则和颜色。我听说在 Firefox 中脚本并不总是有效,但这是安装它的方法:

版本

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

  • 02/02/2012 支持多种数字输入格式,如.123`10.21.2`100.3*^-12,突出显示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 日 蒂姆入侵注入代码。现在突出显示也适用于mathematica.stackexchange。
  • 01/25/2012 增加了对 Mathematica-numbers 的识别。现在应该突出显示{1, 1.0, 1., .12, 16^^1.34f, ...} 之类的内容。此外,它应该识别数字后面的反引号。我将 cmets 和 strings 切换为灰色,并使用深红色作为数字。
  • 01/23/2012 初始版本。 更新部分描述了功能。

【讨论】:

  • 你能给我们解释一下 JavaScript 外行如何测试这个吗?
  • 在你的更新中,为什么有些系统功能是蓝色的而有些是黑色的?你打算让他们那样吗?
  • 这些函数是用户函数。他们只是以大写字母开头。如帖子中所述,我匹配来自Names[RegularExpression["[A-Z].*"]] 的所有内容。有了这个,每个人都看到了用户函数和内核函数之间的区别。
  • @halirutan 哦……没关系。我的错。我已经习惯看到用户定义的蓝色和系统的黑色,我没有意识到你已经翻转它们=)
  • @Szabolcs,我是美化维护者。 Halirutan 和我都希望数学模式最终出现在 prettify 的主存储库中,因此任何使用最新版本 prettify 的 prettify 用户脚本都会得到它。
【解决方案2】:

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

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

  • cmets(无需使用%# ..之类的技巧)
  • 转置运算符(单引号)被正确识别(与默认修饰符带引号的字符串混淆)
  • 流行的内置函数高亮显示

请记住,语法高亮并不完美;除其他外,它在 nested 块 cmets 上失败(我现在可以忍受)。一如既往,欢迎 cmets/fixes/issues。

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

--- 之前 ---

--- 之后---

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


TL;DR

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

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

【讨论】:

  • 这太棒了!糟糕的突出显示支持曾经让我很恼火......非常感谢!如果您查看 halirutan 的答案,您会看到 Mike Samuels 的评论。他是美化维护者,您可以直接与他交谈,看看他是否会将其包含在他的 repo 中。然后,SO 可以在没有脚本的情况下直接使用你的荧光笔(顺便说一句,他们在 mathematica.se 上安装了 halirutan 的自定义荧光笔)。
  • 已经使用了一段时间了,现在我真的很喜欢用这个用户脚本浏览 MATLAB 标签。我希望 IDE 也像您一样突出显示内置功能。这将立即减少他们使用 max/min/std/var 等作为变量函数的所有情况
  • @Bringbackspy:很高兴你发现它很有用。我希望它成为官方美化的一部分,现在我希望对其进行测试并从 SO 的好人那里获得更多反馈。由于您在其他一些 SE 网站上担任版主有一些经验,所以请你有什么建议/建议可以在 SO 上向 MATLAB 社区推广吗? (很遗憾我们没有你们MM那么活跃!)
  • 很久以前我尝试让 MATLAB 社区更多地参与by creating a chatroom,但没有人加入(当时我也不知道如何推广)。我建议先对常客发表评论,然后将他们引导到这里并让他们使用您的脚本。可能会有问题、建议和错误,因此请使用聊天室。我会找一个版主来恢复那个 MATLAB 房间,我们可以让它重新运行。我发现,更积极地聊天有助于建立一个更好、更紧密的社区
  • 此外,halirutan 的荧光笔现在已完全集成到 Mathematica 引擎中,不再需要用作脚本。在meta post 上的cmets 中,balpha(SE 开发人员)提到了脚本不会在SO 上实现的几个原因——最重要的原因是文件的大小。由于 MATLAB 的关键字/函数比 Mathematica 少(我假设您没有包含 all 工具箱),因此它应该相当小。如果您的文件大小与 prettify.js 包中的 SQL/PHP 相当,那么就有机会
猜你喜欢
  • 2020-12-31
  • 2018-04-12
  • 1970-01-01
  • 1970-01-01
  • 2011-07-31
  • 2012-06-13
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
相关资源
最近更新 更多