If you take a look at the Combinatorica
package in Mathematica8 in (mathematicapath)/AddOns/LegacyPackages/DiscreteMath/Combinatorica.m
you wi
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]
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"
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.
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
)
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