Handcalcs
Introduction
This is the documentation for Handcalcs.jl. This package supplies macros to generate $\LaTeX$ formatted strings from mathmatical formulas. This package takes inspiration from handcalcs.py which is a python package that works best in jupyter notebooks. The goal is to get the functionalities of that package and bring them to Julia. The current version of Handcalcs.jl is working for typical algebraic formulas. Future plans are to integrate the package with Unitful.jl, be able to render the algebraic expressions within a function, and many other things. This package is an extension of Latexify.jl. The @latexdefine
macro is similar to the main @handcalcs
macro, but instead of only a symbolic rendering it also renders the numeric substitution.
Examples
A single expression example:
using Handcalcs
a = 2
b = -5
c = 2
@handcalcs x = (-b + sqrt(b^2 - 4*a*c))/ (2*a)
\[\begin{align} x &= \frac{ - b + \sqrt{b^{2} - 4 \cdot a \cdot c}}{2 \cdot a} = \frac{ + 5 + \sqrt{\left( -5 \right)^{2} - 4 \cdot 2 \cdot 2}}{2 \cdot 2} = 2.0 \end{align}\]
The variable x is still evaluated:
x
2.0
An example of multiple expressions:
b = 5 # width
h = 15 # height
@handcalcs begin
I_x = (b*h^3)/12; "moment of inertia about x";
I_y = (h*b^3)/12; "moment of inertia about y";
end
\[\begin{align} I_{x} &= \frac{b \cdot h^{3}}{12} = \frac{5 \cdot 15^{3}}{12} = 1406.25\;\text{ }(\text{moment of inertia about x}) \\[10pt] I_{y} &= \frac{h \cdot b^{3}}{12} = \frac{15 \cdot 5^{3}}{12} = 156.25\;\text{ }(\text{moment of inertia about y}) \end{align}\]
The I_x
and I_y
variables are still evaluated:
println("The moment of inertia about the x direction is: $I_x\n
The moment of inertia about the y direction is: $I_y\n")
The moment of inertia about the x direction is: 1406.25
The moment of inertia about the y direction is: 156.25
You can edit the layout of the returned LaTeX expression with cols
and spa
:
- cols - change the number of columns the expression returns (default = 1).
- spa - change the vertical line spacing between expressions (default = 10).
@handcalcs begin
a = 1
b = 2
c = 3
x = 4
y = 5
z = 6
end cols=3 spa=0
\[\begin{align} a &= 1& b &= 2& c &= 3 \\[0pt] x &= 4& y &= 5& z &= 6 \end{align}\]
An example for rendering expressions within a function:
using TestHandcalcFunctions
b = 5 # width
h = 15 # height
@handfunc Ix = calc_Ix(b, h) # function is defined in TestHandcalcFunctions package
\[\begin{align} Ix &= \frac{b \cdot h^{3}}{12} = \frac{5 \cdot 15^{3}}{12} = 1406.25 \end{align}\]
The Ix
variable is evaluated. Ix being the variable assigned in the @handfunc part (variables within function are not defined in the global name space). If you assign it to a different variable then that will be the variable defined (although you will still see it as Ix in the latex portion). Also note that return statements are filtered out of the function body, so keep relevant parts separate from return statements.
Current Limitations for @handfunc
- You must pass numbers or symbols (not fields of objects). This is also a current limitation of the @handcalcs macro.
- I believe the function needs to be defined in another package. The @code_expr macro from CodeTracking.jl does not see functions in Main for some reason.
- If the function has other function calls within it's body that are not available in Main, then the macro will error.
Using Unitful with UnitfulLatexify
The package has plans to work with the packages Unitful.jl and UnitfulLatexify.jl. The only issue known is the rendering of units under exponents. Parenthesis need to wrap the numerical value and the unit for it to display correctly. See example below.
using Unitful, UnitfulLatexify
a = 2u"inch"
b = -5u"inch"
@handcalc c = sqrt(a^2 + b^2)
\[c = \sqrt{a^{2} + b^{2}} = \sqrt{2\;\mathrm{inch}^{2} -5\;\mathrm{inch}^{2}} = 5.385\;\mathrm{inch}\]
You can see that it looks as though only the unit is being squared. This should be an easy fix. See pull request made in Latexify.jl here. The pull request has been up for a while, so not sure if it will get updated soon. You can always dev Latexify
and add the one line change for now.
Future Plans
There are a number of things that I would like to implement to the package. See handcalcs.py for potential features. Here is a list of features I hope to add:
- Get recursion working for @handfunc macro
- A parameters macro similar to python package
- A way to break down a $\LaTeX$ equation that is too long to multiple lines
References
Handcalcs.Handcalcs
— ModuleModule for better calc documentation.
Handcalcs.@handcalc
— Macro@handcalc expression
Create LaTeXString
representing expression
. The expression being a vaiable followed by an equals sign and an algebraic equation. Any side effects of the expression, like assignments, are evaluated as well. The RHS can be formatted or otherwise transformed by supplying a function as kwarg post
.
Examples
julia> a = 2
2
julia> b = 5
5
julia> @handcalc c = a + b
L"$c = a + b = 2 + 5 = 7$"
julia> c
7
Handcalcs.@handcalcs
— Macro@handcalcs expressions
Create LaTeXString
representing expressions
. The expressions representing a number of expressions. A single expression being a vaiable followed by an equals sign and an algebraic equation. Any side effects of the expression, like assignments, are evaluated as well. The RHS can be formatted or otherwise transformed by supplying a function as kwarg post
. Can also add comments to the end of equations. See example below.
Examples
julia> a = 2
2
julia> b = 5
5
julia> @handcalcs begin
c = a + b; "eq 1";
d = a - c
end
L"$\begin{align}
c &= a + b = 2 + 5 = 7\text{ }(\text{eq 1})
\\[10pt]
d &= a - c = 2 - 7 = -5
\end{align}$"
julia> c
7
julia> d
-5
Handcalcs.@handfunc
— Macro@handfunc expression
Create LaTeXString
representing expressions
. These expressions represent a number of expressions that exist within the function that was called. A single expression being a variable followed by an equals sign and the function being called. The expression is evaluated as well (not the expressions within the function). The RHS can be formatted or otherwise transformed by supplying a function as kwarg post
.
Examples
julia> @handfunc Iy = calc_Ix(5, 15)
L"$\begin{align}
Ix &= \frac{b \cdot h^{3}}{12} = \frac{5 \cdot 15^{3}}{12} = 1406.25
\end{align}$"
julia> Iy
1406.25
Note how Iy is evaluated but Ix is not.