Original Answer
Since you are not asking for efficiency, I find it more productive to deconstruct the polynomial and use HoldForm instead of boxes to handle the ordering. From there, the standard TeXForm does the job well. The tricky part is to hold the Plus inside the HoldForm. Another aspect that I find important is the handling of negative signs inside parenthesis, as one would not like to have y + y x - x print as y + (-1 + y) x but rather as y - (1 - y) x.
The code needs three auxiliary functions: GetSign, to obtain the sign of an expression, HoldTerms, to perform the multiplication of two terms holding its ordering and hiding possible 1s, and PolyForm, which does the bulk of the job by reconstructing the polynomial using HoldForm to preserve the desired ordering. Here they are:
GetSign[a_?NumberQ] := If[a < 0, -1, 1]; GetSign[a_Times | a_Plus] := GetSign[a[[1]]]; GetSign[a_] = 1; HoldTerms[coeff_, mon_] := If[coeff === 1, mon, If[mon === 1, coeff, HoldForm[Times[coeff, mon]]]]; PolyForm[p_, x_Symbol, formatCoefficient_ : Identity] := Module[ {coeff, sign, mon}, (* get polynomial coefficients *) coeff = CoefficientList[Collect[p, x], x]; (* calculate corresponding monomial and remove zero coefficients *) {coeff, mon} = Transpose[ DeleteCases[ Transpose[{coeff, Table[x^i, {i, 0, Length[coeff] - 1}]}], _?(PossibleZeroQ[#[[1]]] &)] ]; (* factor sign of coefficients out *) sign = GetSign /@ coeff; coeff *= sign; (* format coefficients *) coeff = formatCoefficient /@ coeff; (* multiply by monomials and hold, then multiply by sign *) coeff = sign*MapThread[HoldTerms, {coeff, mon}]; (* return *) Return[If[ Length[coeff] > 1, (* Apply Plus inside hold and return *) With[{z = coeff}, HoldForm[z]] /. List -> Plus, (* first entry if list of one *) coeff[[1]] ]]; ];
From these, PolyToTeX basically applies TeXForm to the result of PolyForm. In the case of multiple variables it uses PolyForm to format the coefficients first. This can be extended to more than 2 variables if wanted.
PolyToTeX[p_, x_Symbol] := TeXForm[PolyForm[p, x]]; PolyToTeX[p_, x_Symbol, y_Symbol] := TeXForm[PolyForm[p, x, PolyForm[#, y] &]];
Some examples.
PolyToTeX[y + y x - x, x] (* factors negative sign *)
y-(1-y) x
PolyToTeX[y + y x - x, y] (* keeps ordering in the sum *)
-x+(1+x) y
PolyToTeX[y + y x/2 - x, x] (* uses \frac and factor negative sign *)
y-\left(1-\frac{y}{2}\right) x
or
$y-\left(1-\frac{y}{2}\right) x$
PolyToTeX[y + y^2 z x - x + y x - y^2 x, x, y] (* format coefficients as poly in y *)
y-\left(1-y+(1-z) y^2\right) x
or
$y-\left(1-y+(1-z) y^2\right) x$
p = (w^5/2) + w^4 (-1/4 + z/2) + w^3 z + z^4 + w^2 (1 + z^2 + z^3) + w (2 z^2 + z^4); PolyToTeX[p, w] (* the test polynomial with a flipped minus sign *)
z^4+\left(2 z^2+z^4\right) w+\left(1+z^2+z^3\right) w^2+z w^3-\left(\frac{1}{4}-\frac{z}{2}\right) w^4+\frac{w^5}{2}
or
$z^4+\left(2 z^2+z^4\right) w+\left(1+z^2+z^3\right) w^2+z w^3-\left(\frac{1}{4}-\frac{z}{2}\right) w^4+\frac{w^5}{2}$
Look at
InputForm[PolyForm[p, w]]
to see how PolyForm works
HoldForm[z^4 + HoldForm[(2*z^2 + z^4)*w] + HoldForm[(1 + z^2 + z^3)w^2] + HoldForm[zw^3] - HoldForm[(1/4 - z/2)*w^4] + HoldForm[w^5/2]]
Modified Answer
The requirements added on the comments change the code significantly, hence a new section. The main difficulty is that the rules for the formatting the coefficients are different than the rules for formatting the polynomial, which requires handling different options in each case. Moreover, the requirement for forcing parentheses is also not handled natively by TeXForm, but is handled nicely by the package TexUtilities, which is now a dependence.
Needs["TeXUtilities`"] (* https://github.com/jkuczm/MathematicaTeXUtilities *)
The updated auxiliary functions are:
GetSign[a_?NumberQ] := If[a < 0, -1, 1]; GetSign[a_Times | a_Plus] := GetSign[a[[1]]]; GetSign[a_] = 1; HoldTerms[1, mon_, sign_ : 1] := sign*mon; HoldTerms[coeff_, 1, sign_ : 1] := sign*coeff; HoldTerms[coeff_Rational, mon_, sign_ : 1] := sign*HoldForm[Times[HoldForm[coeff], mon]]; HoldTerms[coeff_, mon_, sign_ : 1] := Times[sign, HoldForm[Times[coeff, mon]]]; Format[ParenthesizeTeX[x__], TeXForm] := TeXDelimited["\\left(", x, "\\right)", "DelimSeparator" -> ""]; ParenthesizeTeXOptional[ a_Plus | a_Symbol | a : (Power[_, _Integer]) | a_?(NumberQ[#] && Positive[#] &)] := a; ParenthesizeTeXOptional[a_] := ParenthesizeTeX[a]; Options[PolyForm] = { FactorSign -> False, ParenthesizeAll -> True, FormatCoefficient -> Identity }; PolyForm[p_, x_Symbol, opts : OptionsPattern[PolyForm]] := Module[ {coeff, sign, mon}, (* get polynomial coefficients *) coeff = CoefficientList[Collect[p, x], x]; (* calculate corresponding monomial and remove zero coefficients *) {coeff, mon} = Transpose[ DeleteCases[ Transpose[{coeff, Table[x^i, {i, 0, Length[coeff] - 1}]}], _?(PossibleZeroQ[#[[1]]] &)]]; (* factor sign of coefficients out *) If[OptionValue[FactorSign] === True, sign = GetSign /@ coeff; coeff *= sign; ]; (* format coefficients *) coeff = OptionValue[FormatCoefficient] /@ coeff; (* wrap all terms in parenthesis *) coeff = If[OptionValue[ParenthesizeAll], ParenthesizeTeX /@ coeff , ParenthesizeTeXOptional /@ coeff ]; (* multiply by monomials and hold *) coeff = If[OptionValue[FactorSign] === True, (* first term might still factor *) Prepend[MapThread[HoldTerms, Rest /@ {coeff, mon, sign}], HoldTerms[sign[[1]]*coeff[[1]], mon[[1]]]] , MapThread[HoldTerms, {coeff, mon}] ]; Return[If[Length[coeff] > 1, (* Apply Plus inside hold and return *) With[{z = coeff}, HoldForm[z]] /. List -> Plus , (* first entry if list of one *) coeff[[1]]] ]; ]; PolyForm[p_, {x_Symbol}, opts : OptionsPattern[PolyForm]] := PolyForm[p, x, opts]; PolyForm[p_, {x_Symbol, y__Symbol}, opts : OptionsPattern[PolyForm]] := PolyForm[p, x, FormatCoefficient -> (PolyForm[#, {y}, FactorSign -> True, ParenthesizeAll -> False, opts] &), opts];
The drivers are also different in order to interfere with the options.
PolyToTeX[p_, x_Symbol, opts___ : OptionsPattern[PolyForm]] := TeXForm[PolyForm[p, x, opts]]; PolyToTeX[p_, {x__Symbol}, opts___ : OptionsPattern[PolyForm]] := TeXForm[PolyForm[p, {x}, opts]];
For the first example in the comments:
p = (-1/2 + 3 z + 4/5 z^3) + (-3/5 z^4) w^3 + 1/5 w^4; PolyToTeX[p, {w, z}]
produce
\left(-\frac{1}{2}+3 z+\frac{4}{5} z^3\right)+\left(-\frac{3}{5} z^4\right) w^3+\left(\frac{1}{5}\right) w^4
or
$\left(-\frac{1}{2}+3 z+\frac{4}{5} z^3\right)+\left(-\frac{3}{5} z^4\right) w^3+\left(\frac{1}{5}\right) w^4$
For the second example in the comments:
p = 1 + (1 - z + 3/5 z^4 + z^5) w - w^2 - z^3 w^5 + (-2/3 z^3 + z^5) w^6 PolyToTeX[p, {w, z}]
produce
\left(1\right)+\left(1-z+\frac{3}{5} z^4+z^5\right) w+\left(-1\right) w^2+\left(-z^3\right) w^5+\left(-\frac{2}{3} z^3+z^5\right) w^6
or
$\left(1\right)+\left(1-z+\frac{3}{5} z^4+z^5\right) w+\left(-1\right) w^2+\left(-z^3\right) w^5+\left(-\frac{2}{3} z^3+z^5\right) w^6$
One can also use options to obtain other formats. For example:
PolyToTeX[p, {w, z}, FactorSign->True, ParenthesizeAll->False]
produces
1+\left(1-z+\frac{3}{5} z^4+z^5\right) w-w^2-z^3 w^5-\left(\frac{2}{3} z^3-z^5\right) w^6
or
$1+\left(1-z+\frac{3}{5} z^4+z^5\right) w-w^2-z^3 w^5-\left(\frac{2}{3} z^3-z^5\right) w^6$
which is similar to the format of the original answer.
The new code should also works for more than two variables, as in:
p = (-1/2 + (x^2 + 1/2) 3 z + x 4/5 z^3) + (-3/5 z^4 - x) w^3 + 1/5 w^4; PolyToTeX[p, {w, z, x}]
which produces
\left(-\frac{1}{2}+\left(\frac{3}{2}+3 x^2\right) z+\left(\frac{4}{5} x\right) z^3\right)+\left(-x-\frac{3}{5} z^4\right) w^3+\left(\frac{1}{5}\right) w^4
or
$\left(-\frac{1}{2}+\left(\frac{3}{2}+3 x^2\right) z+\left(\frac{4}{5} x\right) z^3\right)+\left(-x-\frac{3}{5} z^4\right) w^3+\left(\frac{1}{5}\right) w^4$
I haven't tested it enough though.
With[{e = polyForm[poly, w]}, TeXForm@HoldForm@e]works for me, at least the TeXForm matchestheVal; however,theValdoes not have the fractions out in front of the power ofzas shown in the TeX example. $\endgroup$TeXFormin the comment is wrong, then so itpolyForm; however, you indicate that "polyFormformats it correctly." I noticed the parens, too, and thought you didn't care. I can get the fractions out in front, $\frac{7}{3}z^{25}$ instead of $\frac{7z^{25}}{3}$, but only by constructing the boxes. It's a bit of a pain and didn't think it was worth it. The basic idea is simple (well, much like yours), but the darn signs (negatives to become minus unless first). $\endgroup$