Skip to main content
1 of 2
einbandi
  • 4.1k
  • 2
  • 24
  • 42

The following can be used as a starting point. It transforms the usage string to its TeXForm, the replaces certain substrings to obtain a more readable string. After some iterations, the string no longer changes and has hopefully become something that looks like a simple string representations of the usage message.

transform = StringReplace[
    StringReplace[
     StringReplace[
      StringReplace[
       StringReplace[
        StringReplace[
         StringReplace[
          StringReplace[
           StringReplace[
            StringReplace[
             #,
             "\\text{. $\\backslash $n}" -> ".\n"],
            "$" ~~ a : Except["$"] .. ~~ "$" :> a],               
           "\\textit{" ~~ b___ ~~ "}" /; StringFreeQ[b, "{" | "}"] :> b],
          "\\text{" ~~ c___ ~~ "}" /; StringFreeQ[c, "{" | "}"] :> c],
         "\\left" ~~ d_ :> If[StringMatchQ[d, "]" | "["], d, ""]],
        "\\right" ~~ d_ :> If[StringMatchQ[d, "]" | "["], d, ""]],
       "_{" ~~ e___ ~~ "}" /; StringFreeQ[e, "{" | "}"] :> "_" <> e],
      "^{" ~~ e___ ~~ "}" /; StringFreeQ[e, "{" | "}"] :> "^" <> e],
     "\\int " -> "\[Integral] "],
    "\\ldots" -> "\[Ellipsis]"] &;

usageString[s_] := FixedPoint[transform, ToString@TeXForm[s]]

For many functions with simple usage messages it works:

usageString[Minus::usage]

-x is the arithmetic negation of x.

It sort of works for more complicated usage messages (note that I designed this first version explicitly with Integrate in mind:

usageString[Integrate::usage]

Integrate[f,x] gives the indefinite integral \[Integral] f dx.

Integrate[f,{x,x_\min ,x_\max }] gives the definite integral \[Integral] _x_\min ^x_\max f dx.

Integrate[f,{x,x_\min ,x_\max },{y,y_\min ,y_\max },\[Ellipsis] ] gives the multiple integral \[Integral] _x_\min ^x_\max dx\[Integral]_y_\min ^y_\max dy \[Ellipsis] f.

Of course there are still many problems with special symbols and their TeXForm, as well as with basic layouting. For example, just try usageString[D::usage]. I will try to fix some of those issues. In the meantime, I hope this can serve as a starting point for other people's approaches.

einbandi
  • 4.1k
  • 2
  • 24
  • 42