【问题标题】:Formatting usage messages格式化使用消息
【发布时间】:2011-07-04 11:20:31
【问题描述】:

如果您查看(mathematicapath)/AddOns/LegacyPackages/DiscreteMath/Combinatorica.mMathematica8 中的Combinatorica 包,您会发现函数的定义。我有兴趣知道 Mathematica 如何知道如何格式化使用消息。有些东西告诉我,我没有查看正确的文件。无论如何,让我们尝试以下方法:

Cofactor::usage = "Cofactor[m, {i, j}] calculates the (i, j)th cofactor of matrix m."

这一行就是上面提到的文件中的682行。现在,如果我们在数学笔记本中运行它并使用?Cofactor,我们将看到完全相同的消息。但是如果我们得到包,那么消息就会被格式化。截图如下:

请注意函数中的 m、i 和 j 是如何变化的,并且消息中添加了一个双箭头。我认为箭头已添加到消息中,因为它存在文档。有人可以解释这种行为吗?


编辑: 这是我的笔记本文件的屏幕截图,它会自动保存到 m 文件中。

如您所见,LM 是斜体新罗马时代。现在我将加载包并查看使用情况。

到目前为止一切顺利。现在让我们看看文档中心。我会寻找函数LineDistance

如您所见,它显示了一条奇怪的消息。在这种情况下,我们只想显示没有任何样式的消息。我仍然无法弄清楚Combinatorica 包是如何做到这一点的。 我跟着this做索引,以便文档中心可以显示摘要。摘要本质上是使用情况显示。让我知道是否需要更具体。

【问题讨论】:

    标签: wolfram-mathematica mathematica-8 usage-message


    【解决方案1】:

    好的,这就是解释。

    挖掘 Combinatorica 源代码揭示了这一点:

    (* get formatted Combinatorica messages, except for special cases *)
    If[FileType[ToFileName[{System`Private`$MessagesDir,$Language},"Usage.m"]]===File,
    Select[FindList[ToFileName[{System`Private`$MessagesDir,$Language},"Usage.m"],"Combinatorica`"],
    StringMatchQ[#,StartOfString~~"Combinatorica`*"]&&
    !StringMatchQ[#,"Combinatorica`"~~("EdgeColor"|"Path"|"Thin"|"Thick"|"Star"|"RandomInteger")~~__]&]//ToExpression;
    ]
    

    它正在从ToFileName[{System`Private`$MessagesDir,$Language},"Usage.m"] 加载消息,在我的机器上是SystemFiles\Kernel\TextResources\English\Usage.m。这就是为什么在Combinatorica.m 中有条件地创建所有使用消息的原因(仅当它们尚不存在时)。如果您查看Usage.m,您会发现它包含@ragfield 提到的所有丑陋的盒子。

    我想最简单的格式化消息的方法是在笔记本的前端编辑它们,然后创建一个自动保存包。这样你就可以使用前端所有的格式化工具,不需要处理盒子。

    【讨论】:

    • 这就是我正在做的。我正在格式化笔记本中的消息并将它们自动保存到包中。一切似乎都很好,但令我困扰的是,如果您在文档中心搜索它,那么您也会看到所有框。我想知道我是否必须有一个带有格式化版本的单独的Usage.m 文件。如果是这种情况,它会放在哪里?
    • @jmlopez 我不明白你在这里的意思:“如果你在文档中心搜索它,那么你也会看到所有的框”。如果您从不直接编辑 .m 文件,则没有理由为消息创建单独的文件。如果你这样做了,那么你可以只为消息保留自动保存包,将生成的 .m 文件放在你的包所在的同一目录中(或它的子目录),然后从你的主包文件中读取它。
    • 让我编辑我的帖子并添加屏幕截图,以便您了解我的意思。
    • 截图已上传。
    • @jmlopez 我明白了。所以现在这是一个不同的问题,关于如何正确地与新的文档查看器集成。不幸的是,我没有这方面的经验......
    【解决方案2】:

    我将回答Message 中的链接是如何生成的。跟踪Message 打印显示对未记录的Documentation`CreateMessageLink 函数的调用,如果该页面存在,该函数将URL 返回到相应的文档页面:

    Trace[Information[Sin], Documentation`CreateMessageLink]
    
    In[32]:= Documentation`CreateMessageLink["System", "Sin", "argx", "English"]
    
    Out[32]= "paclet:ref/message/General/argx"
    

    在某些情况下,我们还可以看到对Internal`MessageButtonHandler 的调用进一步调用Documentation`CreateMessageLink

    Trace[Message[Sin::argx, 1, 1], 
     Internal`MessageButtonHandler | Documentation`CreateMessageLink, 
     TraceInternal -> True]
    

    【讨论】:

      【解决方案3】:

      在字符串表达式中嵌入样式信息的方法是使用线性语法。对于框表达式,例如:

      StyleBox["foo", FontSlant->Italic]
      

      您可以通过在字符串前面添加\* 并转义任何特殊字符(例如引号)来将其嵌入到字符串中:

      "blah \*StyleBox[\"foo\", FontSlant->Italic] blah"
      

      这应该适用于任何盒子表达式,无论多么复杂:

      "blah \*RowBox[{SubsuperscriptBox[\"\[Integral]\",\"0\",\"1\"],RowBox[{FractionBox[\"1\",RowBox[{\"x\",\"+\",\"1\"}]],RowBox[{\"\[DifferentialD]\",\"x\"}]}]}] blah"
      

      【讨论】:

      • 我意识到了这一点。问题是,如果我记录我的函数并格式化我的使用消息,那么当我搜索它们时,我获得的摘要包含所有\*StyleBox[...。就在那时我注意到在包Combinatorica 他们没有格式化任何东西,所以他们的总结出来时没有任何格式。但是,当您使用 ?NameofFunction 时,您就有了很好的格式。这是怎么做到的?
      【解决方案4】:

      我目前正在重写您的 ApplicationMaker 以使用具有附加功能的较新的 Mathematica-Versions,并在这里遇到了完全相同的问题。

      我的答案很简单:Mathematica 不允许您对符号使用格式化摘要(甚至是内置符号),因此我们必须取消格式化摘要的使用字符串。使用字符串本身仍然可以进行格式化,但需要有一个函数可以从字符串中删除所有格式化框。

      我有一个使用UndocumentedTestFEParserPacket 的解决方案,如John Fultz 所述!在this 问题中。

      这个有趣的命名工具将字符串输入解析为真正未更改的 Mathematica BoxForm。

      这是我的示例代码:

      str0 = Sum::usage
      
      str1=StringJoin[ToString[StringReplace[#, "\\\"" -> "\""]]& /@
      (Riffle[MathLink`CallFrontEnd[
      FrontEnd`UndocumentedTestFEParserPacket[str0, True]]〚1〛
      //. RowBox[{seq___}] :> seq /. BoxData -> List, " "]
      /. SubscriptBox[a_, b_] :> a<>"_"<>b
      /. Except[List, _Symbol][args__] :> Sequence@@Riffle[{args}, " "])];
      
      str2 = Fold[StringReplace, str1, 
      {((WhitespaceCharacter...)~~br:("["|"("|"=") ~~ (WhitespaceCharacter ...)) :> br,
      ((WhitespaceCharacter ...) ~~ br:("]"|"}"|","|".")) :> br, 
      (br:("{") ~~ (WhitespaceCharacter ...)) :> br, 
      ". " ~~ Except[EndOfString] -> ". \n"}]
      

      这就是输出的样子(第一个输出格式为花哨str0,第二个简单平面str2

      代码说明:

      str0 是带有所有样式框和其他格式框的格式化用法字符串。

      str1

      UndocumentedTestFEParserPacket[str0, True] 给出 Boxes 并剥离所有 StyleBoxes,这是因为第二个参数是 True。 第一次替换删除所有RowBoxes。外部BoxForm 更改为字符串列表。 Riffle 在这些字符串之间插入空格。 SubscriptBox 得到特殊处理。最后一行替换了所有剩余的 FormatBox,例如 UnderoverscriptBox,它通过在参数之间添加空格并将参数作为平面序列返回来实现。

      ToString[StringReplace[#, "\\\"" -> "\""]]& /@
      

      已添加以包含更多案例,例如StringReplace::usage。这种情况包括字符串表示 "",其 Styles 位于使用字符串中,而 "args" 必须以字符串形式给出。

      str2

      在这段代码中,我只从字符串 str1 中删除不需要的WhitespaceCharacter,并在"." 之后添加换行符"/n",因为它们在解析过程中丢失了。有 3 种不同的情况可以删除 WhitespaceCharacter。 1 从"[" 之类的字符中删除左右两侧的WithespaceCharacter。 2. 和 3. 从左侧 (2) 或右侧 (3) 移除 WithespaceCharacter。

      总结

      代替summary-&gt; mySymbol::usage,使用summary -&gt; unformatString[mySymbol::usage]unformatString 是一个合适的函数,可以执行如上所述的取消格式化。

      或者,您可以手动定义另一个使用消息,例如

      f::usage = "fancy string with formating";
      f::usage2 = "flat string without formating";
      

      比使用摘要 -> mySymbol::usage2

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-18
        • 2019-10-11
        • 2012-07-03
        相关资源
        最近更新 更多