You could try using SpokenString:
SpokenString[HoldForm[x + y /. x->2]]
"x plus y slash dot x goes to 2"
Addendum
If you don't mind messing with internal functions, it is possible to customize the output of SpokenString. For this purpose, it is convenient to make use of my ExtractDownValues function reproduced below:
SetAttributes[ExtractDownValues, HoldAll]
ExtractDownValues[sym_[args__]] := ExtractDownValues[sym,args]
ExtractDownValues[sym_,args__] := Cases[
DownValues[sym],_[h_,_] /; MatchQ[Unevaluated[sym[args]],h]
]
The internal function that does most of the heavy lifting is SpokenStringDump`SSText:
TracePrint[SpokenString[HoldForm[x + y /. x -> 2]], _SpokenStringDump`SSText]
SpokenStringDump`SSText[x+y/. x->2]
SpokenStringDump`SSText[x+y]
SpokenStringDump`SSText[x]
SpokenStringDump`SSText[y]
SpokenStringDump`SSText[2]
SpokenStringDump`SSText[x->2]
SpokenStringDump`SSText[x]
SpokenStringDump`SSText[2]
"x plus y slash dot x goes to 2"
Using ExtractDownValues we find:
ExtractDownValues @ SpokenStringDump`SSText[x + y /. x -> 2]
{HoldPattern[
SpokenStringDump`SSText[SpokenStringDump`a_ /. SpokenStringDump`b_]] :>
SpokenStringDump`SpeakQuantity[SpokenStringDump`a, ReplaceAll, True] ~~
" slash dot " ~~
If[ListQ[Unevaluated[SpokenStringDump`b]],
SpokenStringDump`SpeakListContents[SpokenStringDump`b],
SpokenStringDump`SpeakQuantity[SpokenStringDump`b, ReplaceAll, True]],
HoldPattern[
SpokenStringDump`SSText[SpokenStringDump`f_[SpokenStringDump`a___]]] :>
Module[{SpokenStringDump`ans =
SpokenStringDump`SSText0[SpokenStringDump`f[SpokenStringDump`a]]},
If[Head[SpokenStringDump`ans] =!= SpokenStringDump`SSText0 && !
MemberQ[SpokenStringDump`ans, $Failed, {0, 1}], SpokenStringDump`ans,
SpokenStringDump`SSTextFallThrough[
Unevaluated[SpokenStringDump`f[SpokenStringDump`a]]]]]}
Notice the " slash dot " string. So, modifying this downvalue to:
SpokenStringDump`SSText[a_ /. b_] := SpokenStringDump`SpeakQuantity[a,ReplaceAll,True] ~~
" where " ~~
If[ListQ[Unevaluated[b]],
SpokenStringDump`SpeakListContents[b],
SpokenStringDump`SpeakQuantity[b,ReplaceAll,True]
]
will produce:
SpokenString[HoldForm[x + y /. x->2]]
"x plus y where x goes to 2"
->never makes it beyond the visual stage, never becomes an acoustic event. – Roman Apr 27 '19 at 09:16Speak@HoldForm[x + y /. x -> 2]. I find it interesting thatSpeaktranslates->well but has no understanding of what/.is. – bobthechemist Apr 27 '19 at 11:15Speak@HoldForm[x -> 2]is "x goes to 2", butSpeak@HoldForm[x :> 2]is "x colon goes to 2" instead of something more human like "x will go to 2". I think a collection of everybody's ideas would be a good thing to assemble. – Roman Apr 27 '19 at 12:49Out[127]= "Hold of the quantity x plus y slash dot x goes to 2"` Gould be a hair better on that "slash dot".
– Daniel Lichtblau Apr 27 '19 at 13:01