8

How could we go about creating a function that behaves like those?

After a while thinking, my best try is with CellPrint printing an Output cell with the famous CellLabel of Out[blah]//myForm. This solution is good enough for me for now, but I'm using it as an excuse to understand all these issues better... This mimics the behaviour, its not the same... For example, you have to manually get the $Line, you get the GeneratedCell option to True, and I don't know what else I'm missing. In fact, the kernel actually doesn't seem to do anything in the real form functions. So this solution would behave wrongly, for example, if I wrapped it other things... FullForm[myForm[stuff]] should return myForm[stuff] in a FullForm-tagged cell..

Rojo
  • 42,601
  • 7
  • 96
  • 188

3 Answers3

4

This is far from fully integrated into the system but it is a first order approximation of the behavior of other forms. Perhaps it will inspire someone else with a better method.

formfunc =
  StringReplace[
    ToString @ #,
    {"[" -> "(", "]" -> ")", x : DigitCharacter .. :> "-->" <> x <> "<--"}
  ] &;

MakeBoxes[myForm[expr_], StandardForm] := 
  InterpretationBox[#, expr] & @ ToBoxes @ formfunc @ expr

ToString[expr_, myForm] ^:= formfunc[expr]

This provides output that can be re-evaluated to recover the original expression:

2^(1/2) // myForm
"Sqrt(-->2<--)"

This produces a normal String:

ToString[2^(1/2), myForm]
"Sqrt(-->2<--)"
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
2

This might be of help:

$OutputForms is a list of the formatting functions that get stripped off when wrapped around the output.

$OutputForms= {InputForm,OutputForm,TextForm,CForm,Short,Shallow,MatrixForm,TableForm,TreeForm,FullForm,NumberForm,EngineeringForm,ScientificForm,QuantityForm,PaddedForm,AccountingForm,BaseForm,DisplayForm,StyleForm,FortranForm,MathMLForm,TeXForm,StandardForm,TraditionalForm}

I recently discovered while working on a way to better show rational matrices.

unlikely
  • 7,103
  • 20
  • 52
  • 1
    They include the PrintForms which include the BoxForms. I did some digging at the time. Thanks! I think the output forms are those heads that end up showing applied to the cell label such as in mmaOut[34]//InputForm. Try Unprotect@$OutputForms;AppendTo[$OutputForms, la]; la[5] – Rojo Feb 08 '15 at 14:33
  • @Rojo Nice! I tried to figure out those cell tags once and failed. Handy! Thanks, unlikely. – Mr.Wizard Feb 08 '15 at 16:34
  • unlikely, this solves something I wondered about for a while: (44189) -- you can now answer this question. Please do so! – Mr.Wizard Feb 08 '15 at 16:39
1

Understanding now that you want to define a completely new format, but still not sure what you want that format to look like, perhaps this does what you want:

Format[myForm[x_]] := {x, x}
x = blah;
y = myForm[x]
Head[y]
{blah,blah}
myForm

Note that the result printed as {blah,blah} but the Head of the result is myForm.

First attempt

I'm not sure exactly how you want myForm to behave but the standard way to do this is to define a value of Format. For example,

Unprotect[Log];
Format[Log[x_], TraditionalForm] := ln[x]
Protect[Log];

Now, TraditionalForm[Log[x]] will print like $ln(z)$:

enter image description here

Alternatively, you could define an UpValue for Log:

Unprotect[Log];
Log /: MakeBoxes[Log[x_], TraditionalForm] :=
  RowBox[{"ln", "(", MakeBoxes[x, TraditionalForm], ")"}];
Protect[Log];

The result should be the same. Of course, you could do something similar of your myForm.

Mark McClure
  • 32,469
  • 3
  • 103
  • 161
  • I was actually thinking of another form. In fact, the Format documentation suggests "You can add your own forms for formatted output. " apart from CForm, FortranForm, and friends... – Rojo Mar 01 '12 at 00:28
  • @Rojo I'm not sure I understand your comment. Does my edit help clarify? – Mark McClure Mar 01 '12 at 00:32
  • Mark, MakeBoxes is assignable without the need to use UpValues. Just use MakeBoxes[something] = somethingElse (see the docs). I also found it less confusing than format, but never managed to figure out either of them completely. – Szabolcs Mar 01 '12 at 00:33
  • 2
    @Mark He means make a MyForm so that ToString[expr, MyForm] will work. E.g. make a PythonForm which outputs things formatted correctly for Python, or something similar. – Szabolcs Mar 01 '12 at 00:34
  • @Szabolcs I see. Yes my suggestion is not quite sufficient. – Mark McClure Mar 01 '12 at 00:42
  • @MarkMcClure it clarifies a little, yes. But, I'm still wondering, if I defined my own form like that Format[_, myform], then how could I actually use it? (naturally, not calling Format explicitly)... For example, how would I make a function like TraditionalForm[stuff] that outputs as it should, with the "//myForm" in the cell label? – Rojo Mar 01 '12 at 00:42
  • or the many other uses real forms have in Matheamtica... In fact, my string of doubts started when I realised that by specifying the default format type of a cell style, to either InputForm, TextForm, StandardForm, etc, you were actually defining if you would be typing in boxes or just plain strings. One thing led to the other and I soon had to accept that I barely know what forms are and the issue makes me dizzy – Rojo Mar 01 '12 at 00:45
  • In fact it started when I wanted to create a form that output as some kind of tweaked TeXForm... I don't really recall, I've been having these kinds of doubts for a while – Rojo Mar 01 '12 at 00:48