格式化使用消息

发布于 2024-11-18 12:12:02 字数 1251 浏览 6 评论 0原文

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

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

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

在此处输入图像描述

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


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

在此处输入图像描述

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

在此处输入图像描述

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

在此处输入图像描述

正如您所看到的,它显示了一条奇怪的消息。在这种情况下,我们只想显示没有任何样式的消息。我仍然不明白 Combinatorica 包是如何做到这一点的。 我按照这个制作索引,以便文档中心可以显示摘要。摘要本质上是使用情况显示。如果我需要更具体,请告诉我。

If you take a look at the Combinatorica package in Mathematica8 in (mathematicapath)/AddOns/LegacyPackages/DiscreteMath/Combinatorica.m you will find the definitions of functions. What I'm interested to know is how Mathematica knows how to format the usage messages. Something tells me that I'm not looking at the right file. In any case, lets try the following:

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

This line is the 682 line in the file mentioned above. Now if we run it in a mathematica notebook and we use ?Cofactor we will see the exact same message. But if we get the package then the message is formatted. Here is a screenshot:

enter image description here

Notice how the m, i and j inside the function changed and a double arrow was added to the message. I think the arrow was added to the message because there exists documentation for it. Can someone explain this behavior?


EDIT:
This is a screenshot of my notebook file that autosaves to an m file.

enter image description here

As you can see, the L and M are in italic times new roman. Now I will load the package and see the usage.

enter image description here

So far so good. Now lets look at the Documentation center. I will look for the function LineDistance.

enter image description here

As you can see, it shows a weird message. In this case we only want to display the message without any styles. I still can't figure out how the Combinatorica package does this.
I followed this to make the index so that the doc center can display the summary. The summary is essentially the usage display. Let me know if I need to be more specific.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

離殇 2024-11-25 12:12:02

好的,这是解释。

深入 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 提到的所有丑陋的盒子内容。

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

OK, here's the explanation.

Digging in the Combinatorica source reveals this:

(* 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;
]

It is loading messages from ToFileName[{System`Private`$MessagesDir,$Language},"Usage.m"], which on my machine is SystemFiles\Kernel\TextResources\English\Usage.m. This is why all usage messages are created conditionally in Combinatorica.m (only if they don't exist yet). If you look in Usage.m you'll see it has all the ugly boxes stuff that @ragfield mentioned.

I guess the simplest way to have formatted messages is to edit them in the front end in a notebook, and create an auto-save package. This way you can use all the front end's formatting tools, and won't need to deal with boxes.

还如梦归 2024-11-25 12:12:02

我将回答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"

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

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

I will answer on how the link in the Message is generated. Tracing Message printing shows a call to undocumented Documentation`CreateMessageLink function which returns the URL to the corresponding Documentation page if this page exists:

Trace[Information[Sin], Documentation`CreateMessageLink]

In[32]:= Documentation`CreateMessageLink["System", "Sin", "argx", "English"]

Out[32]= "paclet:ref/message/General/argx"

In some cases we can also see calls to Internal`MessageButtonHandler which further calls Documentation`CreateMessageLink:

Trace[Message[Sin::argx, 1, 1], 
 Internal`MessageButtonHandler | Documentation`CreateMessageLink, 
 TraceInternal -> True]
一袭水袖舞倾城 2024-11-25 12:12:02

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

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"

The way to embed style information in a String expression is to use linear syntax. For a box expression such as:

StyleBox["foo", FontSlant->Italic]

You can embed this inside of a String by adding \* to the front of it and escaping any special characters such as quotes:

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

This should work for any box expression, no matter how complicated:

"blah \*RowBox[{SubsuperscriptBox[\"\[Integral]\",\"0\",\"1\"],RowBox[{FractionBox[\"1\",RowBox[{\"x\",\"+\",\"1\"}]],RowBox[{\"\[DifferentialD]\",\"x\"}]}]}] blah"
谢绝鈎搭 2024-11-25 12:12:02

我目前正在努力重写您的 ApplicationMaker 以获取具有附加功能的较新 Mathematica 版本并在这里提出了完全相同的问题。

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

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

这个有趣的命名工具将字符串输入解析为真正未更改的 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

first Output formatted fancy str0, secondary simple flat str2

代码说明:

str0 是包含所有样式框的格式化使用字符串以及其他格式盒子。

str1

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

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

添加了更多案例,例如 StringReplace::usage。这种情况包括字符串表示形式 "" ,其中样式位于用法字符串内,而 "args" 必须作为字符串给出。

str2

在这段代码中,我只从字符串 str1 中删除不需要的 WhitespaceCharacter ,并在 之后添加换行符 "/n" “.”,因为他们在解析过程中迷路了。在 3 种不同的情况下可以删除 WhitespaceCharacter
1 从像 "[" 这样的字符中删除左侧和右侧的 WithespaceCharacter
2.和3.从左(2)或右(3)侧删除WithespaceCharacter。

摘要

而不是摘要-> mySymbol::usage,使用summary -> unformatString[mySymbol::usage] 其中 unformatString 是执行上述取消格式化操作的适当函数。

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

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

使用摘要 -> mySymbol::usage2

I am currently working on rewriting your ApplicationMaker for newer Mathematica-Versions with added functionalities and came to the exact same question here.

My answer is simple: Mathematica dont allowes you to use formated summaries for your symbols (or even build in symbols), so we have to unformate the usage-strings for the summaries. The usagestring itself can still have formatting, but one needs to have a function that removes all the formatingboxes from a string.

i have a solution that uses the UndocumentedTestFEParserPacket as described by John Fultz! in this question.

This funny named Tool parses a String Input into the real unchanged Mathematica BoxForm.

This is my example code:

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"}]

and this is how the Output looks like (first Output formatted fancy str0, second simple flat str2)

first Output formatted fancy str0, second simple flat str2

Code Explanation:

str0 is the formatted usagestring with all the StyleBoxes and other formatting boxes.

str1:

UndocumentedTestFEParserPacket[str0, True] gives Boxes and strips off all StyleBoxes, thats because the second argument is True.
First Replacement removes all RowBoxes. The outer BoxForm changed to a List of strings. Whitespaces are inserted between these strings the by Riffle. SubscriptBox gets a special treatment. The last line replaces every remaining FormatBox such as UnderoverscriptBox and it does that by adding Whitespaces between the arguments, and returning the arguments as a flat Sequence.

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

was added to include more cases such as StringReplace::usage. This cases include string representations "" with Styles inside of a the usage-string, when "args" has to be given as strings.

str2:

In this block of code i only remove unwanted WhitespaceCharacter from the string str1 and i add linebreaks "/n" after the ".", because they got lost during the Parsing. There are 3 different cases where WhitespaceCharacter can be removed.
1 removing left-and right sided WithespaceCharacter from a character like "[".
2. and 3. removing WithespaceCharacter from left(2) or right(3) side.

Summary

Istead of summary-> mySymbol::usage, use summary -> unformatString[mySymbol::usage] with unformatString being an appropriate function that performes the unformating like descriped above.

Alternatively you can define another usage message manually like

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

than use summary -> mySymbol::usage2

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文