Можно ли расширить prettify.js для поддержки Mathematica? - PullRequest
55 голосов
/ 22 января 2012

mathematica.SE в настоящее время находится в частной бета-версии и будет открыт для общественности через несколько дней. Переполнение стека и связанные сайты используют 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 @@@ # &

enter image description here

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]

enter image description here

Это возможно? Перебор? Слишком сложно? Невозможно?

Откровенно говоря, я не знаю ответа ни на один из них. Я просто перечислил некоторые базовые функции, которые все хотели бы иметь на mathematica.SE, и некоторые дополнительные вещи, которые были бы вишней на вершине. Тем не менее, дайте мне знать, если они слишком сложны для реализации. Мы можем выработать меньшее подмножество функций.

В знак признательности за эту помощь вы все обладаете вечной благодарностью сообщества Mathematica и, кроме того, Я присуждаю 500 наград каждому человеку, который вносит значительный вклад в эту (если это сделано по частям разными ребята) - я буду полагаться на ваши голоса / комментарии / вывод на ответы, чтобы решить, что является значительным (возможно, более одного вознаграждения одному человеку, если они сделают всю работу). Реализация «дополнительных приятных имений» автоматически получает +500 независимо от предыдущих наград , так что вы также можете опираться на работу других, даже если вы не выполняете первую половину. Я также мог бы периодически назначать меньшие вознаграждения, чтобы привлечь пользователей, которые, возможно, не видели этот вопрос, поэтому, если вам удастся заработать эти вознаграждения, они будут в дополнение к «вознаграждению за существующий ответ», которое будет принято к концу ,

Наконец, я не спешу. Поэтому, пожалуйста, не торопитесь с этим вопросом. Награда всегда является опцией, пока она не будет реализована SE (или если будет установлено, что существующие ответы полностью удовлетворяют требованиям). В идеале, я надеюсь получить это 2/3 нашего пути в бета-версии, которая через 2 месяца.

Ответы [ 2 ]

43 голосов
/ 22 января 2012

Предисловие

Поскольку поддержка Mathematica для google-code-prettify была в основном разработана для нового сайта Mathematica.Stackexchange , см. Также обсуждение здесь .

Введение

У меня нет глубоких знаний обо всем этом, но были случаи, когда я писал плагин cweb для Idea, чтобы мой код был выделен там.В IDE все это не одношаговый процесс.Он разделен на несколько шагов, и каждый шаг имеет больше возможностей выделения.Позвольте мне объяснить это немного, чтобы позже объяснить некоторые причины, по которым некоторые вещи (imho) невозможны для нужного нам средства подсветки кода.

Сначала код разбивается на токены, которые являются отдельными частямиязык программирования.После этого лексера вы можете классифицировать интервалы вашего кода, например, через пробел, литерал, строку, комментарий и т. Д.Этот лексер ест исходный код, проверяя регулярные выражения, сохраняя тип токена для текстового промежутка и продвигаясь вперед в коде.

После этого лексического сканирования исходный код можетбыть проанализирован с использованием правил языка программирования, токенов и основного кода.Например, если у нас есть токен Plus типа Keyword, мы знаем, что должны следовать скобки и параметр.Если нет, синтаксис неправильный.То, что вы можете построить с помощью этого синтаксического анализа, называется абстрактным синтаксическим деревом AST и выглядит в основном как TreeForm синтаксиса Mathematica.

С хорошо разработанным языком, таким как, например, Java, возможнопроверяйте код во время ввода и делайте практически невозможным синтаксически неправильный код.

prettify.js и Mathematica Code

Во-первых, prettify.js реализует только лексический сканер, но не анализатор.Я почти уверен, что это все равно невозможно из-за временных ограничений на отображение веб-страницы.Итак, позвольте мне объяснить, какие функции невозможны / выполнимы с prettify.js:

Кроме того, вы можете заметить некоторые переменные, выделенные оранжевым - я специально не включил это в качестве требования, так какЯ думаю, что будет намного сложнее обойтись без парсера, который знает Mathematica.

Верно, потому что выделение этих переменных зависит от контекста.Вы должны знать, что вы находитесь внутри Table конструкции или чего-то в этом роде.

Взлом prettify.js

Я думаю, что взломать расширение для prettify.js не так сложно.Я абсолютное регулярное выражение noob, так что будьте готовы к тому, что следует.

Нам не нужно так много вещей для простого лексера Mathematica.У нас есть пробелы, комментарии, строковые литералы, фигурные скобки, множество операторов, обычные литералы, такие как переменные, и гигантский список ключевых слов.

Давайте начнем с ключевых слов в форме регулярного выражения java-script:

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].*"]], сопоставляются и подсвечиваются синим
  • Подтяжки и скобки черного цвета, но жирный шрифт. Это было предложение от Сабольча, и мне оно очень нравится, поскольку оно определенно добавляет энергии к появлению кода
  • Шаблоны, как они появляются в определениях функций, а слоты чистых функций выделены зеленым цветом. Это было предложено Йодой и идет вместе с маркером в интерфейсе Mathematica. Шаблоны только зеленого цвета в сочетании с переменной, как в blub__Integer, a1_ или в b34_Integer32. Тестовые функции для шаблона, как в num_?NumericQ, помечены зеленым перед знаком вопроса.
  • Комментарии и строки имеют одинаковый цвет. Комментарии и строки могут занимать несколько строк. Строки могут содержать кавычки с обратной косой чертой. Комментарии не могут быть вложенными.
  • Для раскраски я последовательно использовал схему ColorData[1], чтобы цвета хорошо выглядели рядом.

В настоящее время это выглядит так:

enter image description here

Тестирование и отладка

Сабольч спросил, можно ли и как это проверить. Это просто: вам нужен мой источник gt-code-prettify ( Где я могу это разместить, чтобы у всех был доступ? ). Распакуйте исходники и откройте файл tests/mathematica_test.html в веб-браузере. Этот файл загружает самостоятельно файлы src/prettify.js, src/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-подсветки. Там вы можете увидеть каждый токен, и вы увидите, какой тип токен. Это выглядит тогда как

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

Вы видите, что открытая скобка имеет тип tag. Это соответствует определению регулярного выражения, которое я сделал в lang-mma.js. В Chrome даже можно просматривать код JS, устанавливать точки останова и отлаживать его при перезагрузке страницы.


Локальная установка для Google Chrome и Firefox

Тим Стоун любезно написал скрипт, который вставляет маркер при загрузке сайтов под http://stackoverflow.com/questions/. Как только google-code-prettify включен для mathematica.stackexchange.com, он также должен работать там. Я адаптировал этот скрипт, чтобы использовать мои лексические правила сканирования и цвета. Я слышал, что в Firefox скрипт не всегда работает, но вот как его установить:

  • Chrome: перейдите по этой ссылке https://github.com/halirutan/Mathematica-Source-Highlighting/raw/master/mathematica-source-highlighter.user.js, и вам будет предложено установить это расширение.
  • Firefox: убедитесь, что у вас установлен плагин Greasemonkey. Затем загрузите ту же ссылку, что и для Chrome.
  • Теперь вы настроены, и при перезагрузке этой страницы комментарии, функции ядра, строки и шаблоны должны быть выделены правильно.

Версия

Под 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 -оператором : см. Также обсуждение здесь

  • 02/02/2012 поддержка многих форматов ввода чисел, таких как .123`10.2 или 1.2`100.3*^-12, выделение In[23] и Out[4], ::usage или других сообщений, таких как blub::boing, выделение таких шаблонов, как ProblemTest[prob:(findp_[pfun_, pvars_, {popts___}, ___]), opts___], исправление ошибок (я проверил парсер на 3500 строк кода пакета из каталога AddOns. Для запуска потребовалось около 3-4 секунд, что должно быть более чем достаточно быстро для наших целей.)
  • 01/30/2012 Исправлено пропущенное '?' в списке операторов. Включены именованные символы, такие как \\[Gamma], чтобы дать полное совпадение для таких символов. Добавлены переменные $ в списке ключевых слов. Улучшено соответствие шаблонов. Добавлено сопоставление контекстных конструкций, таких как Developer`PackedArrayQ. Переключение цветовой схемы связано с большим количеством запросов. Теперь это как в Mathematica-интерфейсе. Ключевые слова черный, переменные синие.
  • 01/29/2012 Тим взломал код для инъекций. Теперь подсветка работает и на mathematica.stackexchange.
  • 01/25/2012 Добавлено распознавание чисел Mathematica. Теперь это должно выделить такие вещи, как {1, 1.0, 1., .12, 16^^1.34f, ...}. Кроме того, он должен распознавать обратную черту за номером. Я переключил комментарии и строки на серый и использовал темно-красный для чисел.
  • 01/23/2012 Начальная версия. Возможности описаны в разделе Обновление .
2 голосов
/ 04 мая 2012

Не совсем то, что вы просите, но я создал аналогичное расширение для MATLAB (основываясь на превосходной работе, уже проделанной здесь). Проект размещен на github .

Скрипт должен решить некоторые проблемы, общие для кода MATLAB при переполнении стека:

  • комментариев (не нужно использовать такие трюки, как %# ..)
  • Оператор транспонирования (одинарная кавычка) правильно распознается как таковой (путается с префиксом по умолчанию для строк в кавычках)
  • Подсветка популярных встроенных функций

Имейте в виду, что подсветка синтаксиса не идеальна; кроме всего прочего, он терпит неудачу при вложенных комментариях к блоку (я могу жить с этим сейчас). Как всегда, комментарии / исправления / проблемы приветствуются.

Включен отдельный пользовательский скрипт, который позволяет переключать используемый язык, как показано на скриншоте ниже:

--- до ---

before

--- после ---

after

Для тех, кто заинтересован, предоставляется третий пользовательский скрипт, адаптированный для работы на «Ответах MATLAB» .


TL; DR

Установить скрипт пользователя для SO напрямую из:

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

...