How to convert expression to String, but keep it looking similar to input form?
My approach for this sort of thing is to define conditioned Format
rules for the problematic symbols, and then to Block
the condition true when using ToString
. In addition, I like to use SequenceForm
as a substitute for HoldForm
. In your example, I would do:
Format[Derivative[n_?Positive][f_], InputForm] /; $Nasser :=
SequenceForm[f, OutputForm@StringJoin[ConstantArray["'", n]]]
Then, I would define a special tostring function:
SetAttributes[tostring, HoldFirst]
tostring[expr_] := Internal`InheritedBlock[{$Nasser = True, SequenceForm},
SetAttributes[SequenceForm, HoldFirst];
ToString[SequenceForm[expr], InputForm]
]
A couple examples:
tostring[y'[x] == a/y[x]] // InputForm
(* "y'[x] == a/y[x]" *)
tostring[x''[t] + c0 x'[t]^2 + c1 x[t]] // InputForm
(* "x''[t] + c0*x'[t]^2 + c1*x[t]" *)
This is pure string hackery and I don't know how robust it is, but it works on your test case and one other that I tried.
helper[l_, d_] := l <> StringJoin @@ ConstantArray["'", ToExpression[d]]
SetAttributes[toPrimedForm, HoldFirst]
toPrimedForm[expr_] :=
Module[{str},
str[1] = ToString[HoldForm[expr], FormatType -> InputForm];
str[2] = StringReplace[str[1], {"HoldForm[" -> "", "]" ~~ EndOfString -> ""}];
StringReplace[
str[2],
"Derivative[" ~~ d : DigitCharacter ~~ "][" ~~ l : LetterCharacter ~~ "]" :>
helper[l, d]]]
toPrimedForm[y'[x] == 1/y[x]]
"y'[x] == 1/y[x]"
toPrimedForm[x''[t] + c0 x'[t]^2 + c1 x[t]]
"x''[t] + c0*x'[t]^2 + c1*x[t]"
Certainly it needs more testing and probably more work, but I'm short on time at the moment. Perhaps it will give you something you can develop further.
Update
Here is version written to work when passed an argument that is an ODE expression or a variables holding such an expression.
helper[l_, d_] := l <> StringJoin @@ ConstantArray["'", ToExpression[d]]
SetAttributes[toPrimedForm, HoldFirst]
toPrimedForm[expr_Symbol] :=
Module[{str},
str[1] = ToString[HoldForm[Evaluate@expr], FormatType -> InputForm];
str[2] = StringReplace[str[1], {"HoldForm[" -> "", "]" ~~ EndOfString -> ""}];
StringReplace[
str[2],
"Derivative[" ~~ d : DigitCharacter ~~ "][" ~~ l : LetterCharacter ~~ "]" :>
helper[l, d]]]
toPrimedForm[expr_] := Module[{xpr = expr}, toPrimedForm[xpr]]
expr = y'[x] == a/f[x];
toPrimedForm[expr]
"y'[x] == a/f[x]"
toPrimedForm[y'[x] == a/f[x]]
"y'[x] == a/f[x]"