Wolfram Computation Meets Knowledge

ReadableForm

Contributed by: Richard Hennigan (Wolfram Research)

Display an expression in a format intended to maximize readability

ResourceFunction["ReadableForm"][expr]

displays a version of expr similar to InputForm[expr] that's formatted to maximize readability.

Details and Options

ReadableForm has the following options:
"FormatHeads" Automatic a set of heads {h1,h2,} such that hi[] should be formatted in StandardForm
"IndentSize" 4 how many spaces to use for indenting
"PageWidth" 120 the target character count for each line
"RelativeWidth" False whether to count indentation in page width
$CharacterEncoding $CharacterEncoding character encoding to use for strings

Examples

Basic Examples

Retrieve the ResourceFunction:

In[1]:=
ResourceFunction["ReadableForm"]
Out[1]=

View the code underlying a formatted expression:

In[2]:=
\!\(\*
GraphicsBox[
{RGBColor[0, 1, 0], Thickness[Large], RectangleBox[{0, -1}, {2, 1}], 
{RGBColor[1, 0, 0], DiskBox[{0, 0}]}, 
{RGBColor[0, 0, 1], CircleBox[{2, 0}]}, 
{RGBColor[1, 1, 0], PolygonBox[{{2, 0}, {4, 1}, {4, -1}}]}, 
{RGBColor[0.5, 0, 0.5], Arrowheads[Large], ArrowBox[
       NCache[{{4, Rational[3, 2]}, {0, Rational[3, 2]}, {0, 0}}, {{
         4, 1.5}, {0, 1.5}, {0, 0}}]], 
{GrayLevel[0], Dashing[{Small, Small}], LineBox[{{-1, 0}, {4, 0}}]}}}]\) // ResourceFunction[
 "ReadableForm"]
Out[2]=

Visually inspect properties of formatted objects:

In[3]:=
ResourceObject[
Association[
  "Name" -> "LeNet Trained on MNIST Data", "UUID" -> "050b1a0a-f43a-4c28-b7e0-72607a918467", "ResourceType" -> "NeuralNet", "Version" -> "1.16.0", "Description" -> "Identify the handwritten digit in an image", "RepositoryLocation" -> URL[
    "https://www.wolframcloud.com/objects/resourcesystem/api/1.0"], "WolframLanguageVersionRequired" -> "11.1", "ContentElements" -> {
    "ConstructionNotebook", "ConstructionNotebookExpression", "EvaluationNet", "UninitializedEvaluationNet", "EvaluationExample"}], ResourceSystemBase -> "https://www.wolframcloud.com/objects/\
resourcesystem/api/1.0"] // ResourceFunction["ReadableForm"]
Out[3]=

Scope

Input-style syntax highlighting is used:

In[4]:=
ResourceFunction["ReadableForm"][Hold[f[x_] := Table[i + 1, {i, x}]]]
Out[4]=

Use Unevaluated to prevent the expression from evaluating:

In[5]:=
ResourceFunction["ReadableForm"][Unevaluated[Echo[\!\(
\*SubsuperscriptBox[\(\[Integral]\), \(0\), \(1\)]\(
\*FractionBox[\(Log[
\*FractionBox[\(1\), \(2\)]\ \((1 + 
\*SqrtBox[\(1 + 4\ x\)])\)]\), \(x\)] \[DifferentialD]x\)\)]]]
Out[5]=

Generalizations & Extensions

ToString will preserve the whitespace:

In[6]:=
if = ResourceFunction["ReadableForm"][
TestResultObject[
Association[
   "TestClass" -> None, "TestIndex" -> 1, "TestID" -> None, "Outcome" -> "MessagesFailure", "Input" -> HoldForm[1/0], "ExpectedOutput" -> HoldForm[
DirectedInfinity[]], "ActualOutput" -> HoldForm[
DirectedInfinity[]], "ExpectedMessages" -> {}, "ActualMessages" -> {
HoldForm[
Message[
MessageName[Power, "infy"], 
HoldForm[0^(-1)]]]}, "AbsoluteTimeUsed" -> Quantity[0``7.1505149978319915, "Seconds"], "CPUTimeUsed" -> Quantity[0., "Seconds"], "MemoryUsed" -> Quantity[1136, "Bytes"]]]]
Out[6]=
In[7]:=
ToString[if]
Out[7]=

CopyToClipboard will also preserve much of the formatting:

In[8]:=
CopyToClipboard[if];
Paste[]
In[9]:=
TestResultObject[
    <|
        "TestClass" -> None,
        "TestIndex" -> 1,
        "TestID" -> None,
        "Outcome" -> "MessagesFailure",
        "Input" -> HoldForm[1/0],
        "ExpectedOutput" -> HoldForm[ComplexInfinity],
        "ActualOutput" -> HoldForm[ComplexInfinity],
        "ExpectedMessages" -> { },
        "ActualMessages" -> {HoldForm[Message[Power::infy, HoldForm[0^(-1)]]]},
        "AbsoluteTimeUsed" -> Quantity[0``7.1505149978319915, "Seconds"],
        "CPUTimeUsed" -> Quantity[0., "Seconds"],
        "MemoryUsed" -> Quantity[1136, "Bytes"]
    |>
]

Options

FormatHeads

By default, some expressions are formatted in StandardForm in order to enhance readability:

In[10]:=
data = <|"Image" -> RandomImage[1, {5, 5}], "Time" -> Now, "Graphics" -> \!\(\*
GraphicsBox[
{RGBColor[0, 1, 0], Thickness[Large], RectangleBox[{0, -1}, {2, 1}], 
{RGBColor[1, 0, 0], DiskBox[{0, 0}]}, 
{RGBColor[0, 0, 1], CircleBox[{2, 0}]}, 
{RGBColor[1, 1, 0], PolygonBox[{{2, 0}, {4, 1}, {4, -1}}]}, 
{RGBColor[0.5, 0, 0.5], Arrowheads[Large], ArrowBox[
          NCache[{{4, Rational[3, 2]}, {0, Rational[3, 2]}, {0, 0}}, {{4, 1.5}, {0, 1.5}, {0, 0}}]], 
{GrayLevel[0], Dashing[{Small, Small}], LineBox[{{-1, 0}, {4, 0}}]}}}]\)|>;
ResourceFunction["ReadableForm"][data]
Out[11]=

Use "FormatHeads" to control which expressions are formatted in StandardForm:

In[12]:=
ResourceFunction["ReadableForm"][data, "FormatHeads" -> {Image, Graphics}]
Out[12]=

Use Automatic to include the defaults:

In[13]:=
ResourceFunction["ReadableForm"][data, "FormatHeads" -> {Automatic, Graphics}]
Out[13]=

IndentSize

Change the size of indentation in the output:

In[14]:=
ResourceFunction["ReadableForm"][SystemInformation["Small"], "IndentSize" -> 1, "FormatHeads" -> None]
Out[14]=

PageWidth

Set a desired page width to control line breaks:

In[15]:=
ResourceFunction["ReadableForm"][SystemInformation["Small"], "PageWidth" -> 60, "FormatHeads" -> None]
Out[15]=

RelativeWidth

By default, measuring "PageWidth" per line includes the leading whitespace:

In[16]:=
expr = <|
   "Test1" -> <|"Name" -> "First", "Data" -> Range[10]|>,
   "Test2" -> <|"Name" -> "Second", "Data" -> {}|>
   |>;
ResourceFunction["ReadableForm"][expr, "IndentSize" -> 12, "PageWidth" -> 40]
Out[17]=

Set "RelativeWidth" to True if you don't want to count the leading whitespace:

In[18]:=
ResourceFunction["ReadableForm"][expr, "IndentSize" -> 12, "PageWidth" -> 40, "RelativeWidth" -> True]
Out[18]=

Applications

Copy expressions to the clipboard that will be formatted nicely when pasting into emails, etc.:

In[19]:=
SystemInformation["Small"] // ResourceFunction["ReadableForm"] // CopyToClipboard;
Paste[]
In[20]:=
{
    "Kernel" -> {
        "SystemID" -> "Windows-x86-64",
        "ReleaseID" -> "11.3.0.0 (5968278, 2018041902)",
        "CreationDate" -> DateObject[{2018, 4, 19, 20, 38, 51.}, "Instant", "Gregorian", -4.]
    },
    "FrontEnd" -> {
        "OperatingSystem" -> "Windows",
        "ReleaseID" -> "11.3.0.0 (5968278, 2018041902)",
        "CreationDate" -> DateObject[{2018, 4, 19, 20, 16, 25}, "Instant", "Gregorian", -4.]
    }
}

Create readable log files with lots of metadata:

In[21]:=
logEvent[event_] := PutAppend[
   ResourceFunction[
    "ReadableForm"][<|"Time" -> DateString[], "Event" -> event, "Metadata" -> ResourceFunction["SessionInformation"][]|>], "log.txt"];
In[22]:=
logEvent["A thing just happened"]
In[23]:=
FilePrint["log.txt"]

Properties and Relations

For expressions that only require a single line to display, the output will be very similar to InputForm:

In[24]:=
InputForm[x/Sqrt[5] + y^2 + 1/z]
Out[24]=
In[25]:=
ResourceFunction["ReadableForm"][x/Sqrt[5] + y^2 + 1/z]
Out[25]=

Possible Issues

ReadableForm is just a formatting wrapper; it doesn't evaluate on its own:

In[26]:=
FullForm[ResourceFunction["ReadableForm"][x]]
Out[26]=

The head is not visible to InputForm:

In[27]:=
InputForm[ResourceFunction["ReadableForm"][x]]
Out[27]=

Resource History