# Problem calling function defined with HoldFirst

V 12.1 on windows.

I am trying to use nice function from a recent post How to directly get the TeXForm of each steps from Rubi?

ps. to run MWE code below, requires Rubi package, which if you do not have it installed, the command to install it is

  PacletInstall["https://rulebasedintegration.org/Rubi-4.16.1.0.paclet"]


Now, Here it the function I am trying to use, the same exact code from the above post link written by wuyudi

SetAttributes[IntWithStepsOfTeXForm, {HoldFirst}];
IntWithStepsOfTeXForm[j_] :=
With[{TeX2Str = ConvertTeXExpressionToTeX},
Steps[j, RubiPrintInformation -> False] //
Flatten //
Most //
# /. RubiIntermediateResult[x_] -> x & //
(*ToString@*TeXForm is OK*)
Map["=&" <> (TeX2Str[HoldForm @@ #]) <> "\\\\" &] //
# /. {a___} -> {
"\\begin{aligned}",
TeX2Str@HoldForm@j,
a,
"\\end{aligned}"} & // StringRiffle
]


This is meant to be called as follows, and it works fine this way:

  <<Rubi
<<MaTeX (*needed just for formating the result*)
(*Not needed to see the problem, just makes it easier to see*)

result = IntWithStepsOfTeXForm[   Int[Log[1 + x], x ] ];

MaTeX[result, Magnification -> 2]


The problem is, I have my integrands in a long list, and my program runs as loop, reading the integrands from the list, so when doing the following, the call no longer works

  lst = {{Log[1 + x], x}}; (*very long list of integrands to process*)
result = IntWithStepsOfTeXForm[   Int[  lst[[1,1]], lst[[1,2]] ] ];
MaTeX[result, Magnification -> 2]


Because of the HoldFirst, the function does not see that lst[[1,1]]=Log[1 + x] and that lst[[1,2]]=x.

And I tried numbers of things, but have not found workaround so far. For example, I tried

lst = {{Log[1 + x], x}};
f = lst[[1, 1]];
x = lst[[1, 2]];
result = IntWithStepsOfTeXForm[ Int[ f, x  ]  ]


Removing the HoldFirst on the function also did not work, it broke it. Also changing Steps[j, RubiPrintInformation -> False] to Steps[Evaluate@j, RubiPrintInformation -> False] broke it as well.

Any suggestion for a work around to allow calling the above function using list as above?

• Try IntWithStepsOfTeXForm[Int[#, x]] & /@ {Sin[x], Cos[x]/x^2, Sin[x]/x^2} // MaTeX – wuyudi May 10 '20 at 4:03
• @wuyudi thanks. This helps a little. But the independent variable $x$ also some from the list, as it is not always $x$ and can by anything. So when I tried lst = {{Log[1 + x], x}}; result = IntWithStepsOfTeXForm[ Int[#1, lst[[1, 2]]]] & /@ {lst[[1, 1]]} it did not work. Then I tried result = MapThread[ IntWithStepsOfTeXForm[Int[#1, #2]] & , {lst[[1, 1]], lst[[1, 2]]} ] and this also did not work. Btw, I will be calling your function on each integral one at a time. Not on the whole list at once as you show. – Nasser May 10 '20 at 4:27
• ... Do you know why MapThread did not work here? Is it possible to make your function where one can call it giving it the integrand expression and also the variable of integrations, as separate parameters? i.e. have your API like this: IntWithSteps[ integrand_, var_] and then inside your function you can call Rubi any way then. Instead of current API IntWithSteps[ Int[integrand, var] ] and having to use HoldFirst? This might make it easier to use. – Nasser May 10 '20 at 4:28

Ok, here is it.

I use HoldAll,HoldFirst seems also ok.

I find that Attributes[Integrate] only has {Protected, ReadProtected} ,so I removed the HoldAll or HoldFirst

    IntWithStepsOfTeXForm[formula_, j_] :=
With[{TeX2Str = ConvertTeXExpressionToTeX},
Steps[Int[formula, j], RubiPrintInformation -> False] //
Flatten //
Most //
# /.  RubiIntermediateResult[x_] -> x & //
(*ToString@*TeXForm is OK*)
Map["=&" <> (TeX2Str[HoldForm @@ #]) <>  "\\\\" &] //
{"\\begin{aligned}", TeX2Str@HoldForm@Int[formula, j], Sequence @@ #,  "\\end{aligned}"} & //
StringRiffle
]


usage:

IntWithStepsOfTeXForm[Sin[x], x]

• I just tried it and it worked. This makes the API much easier to use ! Thank you. – Nasser May 10 '20 at 5:58
• @Nasser My pleasure : P – wuyudi May 10 '20 at 5:59
• @Nasser I update my answer. thx for pointing out it. – wuyudi May 10 '20 at 6:46
• I found another problem as I test it more. You problem can easily fix this since your know your function better. The way now Latex is generated from your function is one string. Which is correct ofcourse. But is it possible to insert '\n' at the end of each rule step you find from Rubi, so that the latex generated is not one very long line? The reason is, tex4ht which I use can't handle very long latex lines, It seems to have limit. If there was a CR at end of each step in the \begin{align*}, then it will be OK. Ie. replace .... &=.....\\....&=.... with .... &=.....\\\n.....&= .... – Nasser May 10 '20 at 8:26
• ..... This way also, when looking at latex generated in the editor, it will be easier to see as now it is all one very long line. I think the fix is somewhere in this line in your code {"\\begin{align*}", TeX2Str@HoldForm@Int[formula, j], Sequence @@ #, "\\end{align*}"} & // StringRiffle Just need to find where to insert \n at end of each rule/step. I hope I explained it ok for you. Thanks. – Nasser May 10 '20 at 8:28