ConTeXt 中的自定义漂亮打印机

ConTeXt 中的自定义漂亮打印机

我已经关注维基百科编写自定义漂亮打印机pret-ada.lua。我将其放在我的 tex 文件旁边。

维基百科我必须使用它\installprettytype来注册它。然而,它产生了未定义控制序列一些挖掘发现了邮件列表帖子这解释了它已在 MkIV 中被删除。但它没有解释我现在如何将我的漂亮打印机注册到 ConTeXt。

那么,我该如何让 ConTeXt 使用我的漂亮打印机呢?直接删除命令会导致完全没有漂亮打印:

%\installprettytype[ADA][ADA] % Undefined control sequence!
\definetyping[Ada][option=ADA]

\starttext
  \startAda
    A := "String";
  \stopAda
\stoptext

编辑

以下是我目前为词法分析器想出的内容。它很可能是错误的,因为我还无法测试它。我从以下网址复制了部分内容:pret-c.lua

local keywords = {
  "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
  "array", "at", "begin", "body", "case", "constant", "declare", "delay",
  "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
  "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
  "limited", "loop", "mod", "new", "not", "null", "of", "or", "others", "out",
  "overriding", "package", "pragma", "private", "procedure", "protected",
  "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
  "select", "separate", "some", "subtype", "synchronized", "tagged", "task",
  "terminate", "then", "type", "until", "use", "when", "while", "with", "xor"
}

local keyword_colors = {}
for _, n in ipairs(keywords) do
  keyword_colors[n] = "keyword"
end

local colors = {
  {name = "comment", color="gray"},
  {name = "keyword", color="blue"},
  {name = "string", color="green"}
}
local color

local function init()
  color = 0
  local def_colors = ""
  local palet = "\\definepalet[Ccolorpretty]["
  for _, c in ipairs(colors) do
    def_colors = format("%s\\doifcolorelese{C%s}{}{\\definecolor[C%s][%s]}",
        def_colors, c.name, c.name, c.color)
    palet = format("%s%s=C%s,", palet, c.name, c.name)
  end
  palet = palet:gsub("(.+),$", "%1]")
  texsprint(def_colors)
  texsprint(palet)
  buffers.currentcolors = {}
  for i, c in ipairs(colors) do
    buffers.currentcolors[i] = c.name
  end
end

local function finish_color()
  color = buffers.finishstate(color)
end

local function change_color(n)
  color = buffers.changestate(color_by_name[n], color)
end

local visualizer = buffers.newvisualizer('ada')

visualizer.begin_of_display = init
visualizer.begin_of_inline = init
visualizer.end_of_display = finish_color
visualizer.end_of_inline = finish_color

local function next_token(lexer)
  local buf = ""
  if lexer.c == " " or lexer.c == "\t" then
    buf = lexer.c
    lexer.c = lexer.next()
    while lexer.c == " " or lexer.c == "\t" do
      buf = buf .. lexer.c
      lexer.c = lexer.next()
    end
  elseif lexer.c = "\"" then
    while true do
      lexer.c = lexer.next()
      if lexer.c == nil then break end
      buf = buf .. lexer.c
      if lexer.c == "\"" then break end
    end
  elseif lexer.c == "-" then
    buf = buf .. lexer.c
    lexer.c = lexer.next()
    if lexer.c == "-" then
      while lexer.c ~= nil do
        buf = buf .. lexer.c
        lexer.c = lexer.next()
      end
    end
  elseif lexer.c:match("[%w_]") then
    while lexer.c != nil and lexer.c:match("[%w_]") do
      buf = buf .. lexer.c
      lexer.c = lexer.next()
    end
  else
    buf = lexer.c
    lexer.c = lexer.next()
  end
  return buf
end

function string.starts(String,Start)
  return string.sub(String,1,string.len(Start))==Start
end

function visualizer.flush_line(str, nested)
  local lexer = {
    next = utfcharacters(str)
  }
  lexer.c = lexer.next()
  while lexer.c ~= nil do
    local token = next_token(lexer)
    if token:starts("--") then
      change_color("comment")
      texsprint(token)
      finish_color()
    elseif token:starts("\"") then
      change_color("string")
      texsprint(token)
      finish_color()
    elseif keyword_colors[token] then
      change_color("keyword")
      texsprint(token)
      finish_color()
    else
      texsprint(token)
    end
  end
end

答案1

您使用的语法似乎非常古老。您引用的模块上次更新是在 2010 年,wiki 页面上次修改也是在 2010 年。我在当前源代码树中没有找到任何关于您使用的函数的提及。可能,这种方法已被弃用。

到目前为止,ConTeXt 中的所有词法分析器和解析器都使用 LPEG。我复制粘贴了 Lua 词法分析器以使其适应 ADA。由于我不会说 ADA,所以我无法判断突出显示是否正确。另外,我不是 LPEG 专家,因此解析可能也会很尴尬。

buff-imp-ada.mkiv

\registerctxluafile{buff-imp-ada.lua}{1.001}

\unprotect

\definestartstop
    [AdaSnippet]
    [DefaultSnippet]

\definestartstop
    [AdaSnippetName]
    [\c!color=,
     \c!style=boldface]

\definestartstop
    [AdaSnippetNameKeyword]
    [\c!color=darkgreen,
     \c!style=boldface]

\definestartstop
    [AdaSnippetBoundary]
    [\c!color=darkblue,
     \c!style=boldface]

\definestartstop
    [AdaSnippetString]
    [AdaSnippet]

\definestartstop
    [AdaSnippetQuote]
    [AdaSnippetBoundary]

\definestartstop
    [AdaSnippetSpecial]
    [\c!color=darkred,
     \c!style=boldface]

\definestartstop
    [AdaSnippetComment]
    [\c!color=darkyellow,
     \c!style=boldface]

\definetyping
    [ADA]
    [\c!option=ada]

\protect \endinput

buff-imp-ada.lua

local format, tohash = string.format, table.tohash
local P, S, V, patterns = lpeg.P, lpeg.S, lpeg.V, lpeg.patterns

local context                 = context
local verbatim                = context.verbatim
local makepattern             = visualizers.makepattern

local AdaSnippet              = context.AdaSnippet
local startAdaSnippet         = context.startAdaSnippet
local stopAdaSnippet          = context.stopAdaSnippet

local AdaSnippetBoundary      = verbatim.AdaSnippetBoundary
local AdaSnippetQuote         = verbatim.AdaSnippetQuote
local AdaSnippetString        = verbatim.AdaSnippetString
local AdaSnippetSpecial       = verbatim.AdaSnippetSpecial
local AdaSnippetComment       = verbatim.AdaSnippetComment
local AdaSnippetNameKeyword   = verbatim.AdaSnippetNameKeyword
local AdaSnippetName          = verbatim.AdaSnippetName

local keywords = tohash {
   "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
   "array", "at", "begin", "body", "case", "constant", "declare", "delay",
   "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
   "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
   "limited", "loop", "mod", "new", "not", "null", "of", "or", "others", "out",
   "overriding", "package", "pragma", "private", "procedure", "protected",
   "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
   "select", "separate", "some", "subtype", "synchronized", "tagged", "task",
   "terminate", "then", "type", "until", "use", "when", "while", "with", "xor"
}

local function visualizename(s)
    if keywords[s] then
        AdaSnippetNameKeyword(s)
    else
        AdaSnippetName(s)
    end
end

local handler = visualizers.newhandler {
    startinline  = function() AdaSnippet(false,"{") end,
    stopinline   = function() context("}") end,

    startdisplay = function() startAdaSnippet() end,
    stopdisplay  = function() stopAdaSnippet() end ,

    boundary     = function(s) AdaSnippetBoundary(s) end,
    special      = function(s) AdaSnippetSpecial(s) end,
    comment      = function(s) AdaSnippetComment(s) end,
    quote        = function(s) AdaSnippetQuote(s) end,
    string       = function(s) AdaSnippetString(s) end,

    name         = visualizename,
}

local comment     = P("--")
local name        = (patterns.letter + S("_"))^1
local boundary    = S('()[]:=<>;"')
local special     = S("-+/*|`!?^&%.,")

local grammar = visualizers.newgrammar("default", { "visualizer",

    comment     = makepattern(handler,"comment",comment)
                * (V("space") + V("content"))^0,
    dstring     = makepattern(handler,"quote",patterns.dquote)
                * makepattern(handler,"string",patterns.nodquote)
                * makepattern(handler,"quote",patterns.dquote),
    name        = makepattern(handler,"name",name),
    boundary    = makepattern(handler,"boundary",boundary),
    special     = makepattern(handler,"special",special),

    pattern     =
        V("comment") + V("dstring") + V("name") + V("boundary") + V("special")
      + V("newline") * V("emptyline")^0 * V("beginline")
      + V("space")
      + V("default"),

    visualizer  =
        V("pattern")^1

} )

local parser = P(grammar)

visualizers.register("ada", { parser = parser, handler = handler, grammar = grammar } )

测试

\loadmarkfile{buff-imp-ada}

\starttext
  \startADA
    with Ada.Text_IO; use Ada.Text_IO;
    procedure Hello is
    begin
      Put_Line ("Hello, world!");
    end Hello;
  \stopADA
\stoptext

在此处输入图片描述

答案2

另一种选择是使用t-vim使用 vim 编辑器进行语法高亮的模块。它比使用基于 lua 的词法分析器要慢,但结果会被缓存,因此从长远来看,速度损失很小。优点是您可以获得对 vim 支持的所有语言的支持。

定义 Ada 语法高亮环境的方法如下:

\usemodule[vim]
\definevimtyping[Ada][syntax=ADA]

\starttext
  \startAda
    A := "String";
  \stopAda
\stoptext

这使

在此处输入图片描述

相关内容