Skip to content

Commit

Permalink
Merge pull request #6 from co1emi11er2/default_kwargs
Browse files Browse the repository at this point in the history
Update to work with Weave.jl
  • Loading branch information
co1emi11er2 authored Apr 9, 2024
2 parents 664b55b + 3b04d77 commit 87b0634
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Handcalcs"
uuid = "e8a07092-c156-4455-ab8e-ed8bc81edefb"
authors = ["Cole Miller"]
version = "0.1.8"
version = "0.2.0"

[deps]
CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

This is a package for generating LaTeX maths and designed to improve documentation for your calculations. This package was designed to work in both jupyter and pluto.

This package supplies macros to generate ``\LaTeX`` formatted strings from mathmatical formulas. This package takes inspiration from [handcalcs.py](https://github.com/connorferster/handcalcs) 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](https://painterqubits.github.io/Unitful.jl/stable/), be able to render the algebraic expressions within a function, and many other things. This package is an extension of [Latexify.jl](https://github.com/korsbo/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.
This package supplies macros to generate ``\LaTeX`` formatted strings from mathmatical formulas. This package takes inspiration from [handcalcs.py](https://github.com/connorferster/handcalcs) 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](https://painterqubits.github.io/Unitful.jl/stable/), and get recursion working for function calls. This package is an extension of [Latexify.jl](https://github.com/korsbo/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.

## Basic Demo
![handcalc demo](/assets/handcalcs_demo.gif)
Expand Down Expand Up @@ -59,11 +59,11 @@ end
```

```LaTeX
$\begin{align}
$\begin{aligned}
c &= a + b = 2 + 5 = 7\;\text{ }(\text{eq 1})
\\[10pt]
d &= a - c = 2 - 7 = -5
\end{align}$
\end{aligned}$
```

[<img src="./assets/handcalcs_latex_render.png" width="300"/>](image.png)
Expand All @@ -79,9 +79,9 @@ h = 15
```

```LaTeX
$\begin{align}
$\begin{aligned}
Ix &= \frac{b \cdot h^{3}}{12} = \frac{5 \cdot 15^{3}}{12} = 1406.25
\end{align}$
\end{aligned}$
```

[<img src="./assets/handfunc_latex_render_remove.png" width="300"/>](image.png)
Expand Down
24 changes: 23 additions & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ The moment of inertia about the y direction is: $I_y\n")
### 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).
- h_env - change the environment (default = "aligned").
```@example main
@handcalcs begin
a = 1
Expand All @@ -63,10 +64,31 @@ h = 15 # height
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.

### An example of changing default settings:
You can change the default settings using the `set_handcalcs` function *(similar to the `set_default` function in Latexify)*.
```julia
set_handcalcs(cols=3)
```
Note that this changes Handcalcs.jl from within and should therefore only be used in your own Julia sessions (do not call this from within your packages).

The calls are additive so that a new call with
```julia
set_handcalcs(spa = 5)
```
will not cancel out the changes we just made to `cols`.

To view your changes, use
```julia
get_handcalcs()
```
and to reset your changes, use
```julia
reset_handcalcs()
```

## Using Unitful with UnitfulLatexify

The package has plans to work with the packages [Unitful.jl](https://painterqubits.github.io/Unitful.jl/stable/) and [UnitfulLatexify.jl](https://gustaphe.github.io/UnitfulLatexify.jl/stable/). 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.
Expand Down
5 changes: 3 additions & 2 deletions src/Handcalcs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ using LaTeXStrings
using CodeTracking, Revise
using InteractiveUtils

export @handcalc, @handcalcs, latexify, multiline_latex, set_default, get_default, reset_default, @handfunc #, initialize_format
export @handcalc, @handcalcs, latexify, multiline_latex, set_default, get_default, reset_default, @handfunc, set_handcalcs, reset_handcalcs, get_handcalcs #, initialize_format

# function initialize_format()
# @eval begin
Expand All @@ -19,8 +19,9 @@ export @handcalc, @handcalcs, latexify, multiline_latex, set_default, get_defaul
# end
# end
const math_syms = [:*, :/, :^, :+, :-, :%, :.*, :./, :.^, :.+, :.-, :.%, :sqrt, :sin, :cos, :tan]
const h_syms = [:cols, :spa]
const h_syms = [:cols, :spa, :h_env]

include("default_h_kwargs.jl")
include("handcalc_marco.jl")
include("handcalcs_macro.jl")
include("handfunc_macro.jl")
Expand Down
41 changes: 41 additions & 0 deletions src/default_h_kwargs.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const default_h_kwargs = Dict{Symbol, Any}()

"""
set_default(; kwargs...)
Set default kwarg values for handcalcs.
This works for all keyword arguments. It is additive such that if
you call it multiple times, defaults will be added or replaced, but not reset.
Example:
```julia
set_handcalcs(cols = 2, spa = 5)
```
To reset the defaults that you have set, use `reset_handcalcs`.
To see your specified defaults, use `get_handcalcs`.
"""
function set_handcalcs(; kwargs...)
for key in keys(kwargs)
default_h_kwargs[key] = kwargs[key]
end
end

"""
reset_handcalcs()
Reset user-specified default kwargs for handcalcs, set by `set_handcalcs`.
"""
reset_handcalcs() = empty!(default_h_kwargs)

"""
get_handcalcs
Get a Dict with the user-specified default kwargs for handcalcs, set by `set_handcalcs`.
"""
function get_handcalcs end
get_handcalcs() = default_h_kwargs
get_handcalcs(arg::Symbol) = default_h_kwargs[arg]
get_handcalcs(args::AbstractArray) = map(x->default_h_kwargs[x], args)
get_handcalcs(args...) = Tuple(get_handcalcs(arg) for arg in args)
48 changes: 25 additions & 23 deletions src/handcalcs_macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ julia> @handcalcs begin
c = a + b; "eq 1";
d = a - c
end
L"\$\\begin{align}
L"\$\\begin{aligned}
c &= a + b = 2 + 5 = 7\\text{ }(\\text{eq 1})
\\\\[10pt]
d &= a - c = 2 - 7 = -5
\\end{align}\$"
\\end{aligned}\$"
julia> c
7
Expand All @@ -41,7 +41,6 @@ macro handcalcs(expr, kwargs...)
return Expr(:block, esc(Expr(:call, :multiline_latex, exprs...)))
end
h_kwargs, kwargs = clean_kwargs(kwargs)
# h_kwargs = merge(default_h_kwargs, h_kwargs)
# If multiple Expressions
for arg in expr.args
if typeof(arg) == String # type string will be converted to a comment
Expand All @@ -56,25 +55,9 @@ macro handcalcs(expr, kwargs...)
return Expr(:block, esc(Expr(:call, :multiline_latex, Expr(:parameters, _extractparam.(h_kwargs)...), exprs...)))
end

function multiline_latex(exprs...; cols=1, spa=10, h_env="aligned", kwargs...)
cols_start = cols
multi_latex = "\\begin{$h_env}"
for (i, expr) in enumerate(exprs)
if occursin("text{ }", expr)
multi_latex *= expr[2:end-1] # remove the $ from end and beginning of string
else
cleaned_expr = clean_expr(expr)
if cols == 0
cols = cols_start
multi_latex *= "\n" * (i ==1 ? "" : "\\\\[$spa" * "pt]\n") * cleaned_expr
else
multi_latex *= (i ==1 ? "\n" : "&\n") * cleaned_expr
end
cols -= 1
end
end
multi_latex *= "\n" * "\\end{$h_env}"
return latexstring(multi_latex)
function multiline_latex(exprs...; kwargs...)
h_kwargs = merge(default_h_kwargs, kwargs)
return process_multiline_latex(exprs...;h_kwargs...)
end

function clean_expr(expr)
Expand All @@ -100,4 +83,23 @@ end
_split_kwarg(arg::Symbol) = arg
_split_kwarg(arg::Expr) = arg.args[1]

# function process_multiline_latex()
function process_multiline_latex(exprs...;cols=1, spa=10, h_env="aligned", kwargs...)
cols_start = cols
multi_latex = "\\begin{$h_env}"
for (i, expr) in enumerate(exprs)
if occursin("text{ }", expr)
multi_latex *= expr[2:end-1] # remove the $ from end and beginning of string
else
cleaned_expr = clean_expr(expr)
if cols == 0
cols = cols_start
multi_latex *= "\n" * (i ==1 ? "" : "\\\\[$spa" * "pt]\n") * cleaned_expr
else
multi_latex *= (i ==1 ? "\n" : "&\n") * cleaned_expr
end
cols -= 1
end
end
multi_latex *= "\n" * "\\end{$h_env}"
return h_env == "aligned" ? latexstring(multi_latex) : LaTeXString(multi_latex)
end
4 changes: 2 additions & 2 deletions src/handfunc_macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ The RHS can be formatted or otherwise transformed by supplying a function as kwa
# Examples
```julia-repl
julia> @handfunc Iy = calc_Ix(5, 15)
L"\$\\begin{align}
L"\$\\begin{aligned}
Ix &= \\frac{b \\cdot h^{3}}{12} = \\frac{5 \\cdot 15^{3}}{12} = 1406.25
\\end{align}\$"
\\end{aligned}\$"
julia> Iy
1406.25
Expand Down
33 changes: 33 additions & 0 deletions test/default_h_kwargs.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# using Handcalcs
# using LaTeXStrings, Unitful, UnitfulLatexify
# using Test

# use set_handcalcs
# ***************************************************
# ***************************************************
expected =L"\begin{aligned}
x &= 5
\\[5pt]
y &= 4
\end{aligned}"
set_handcalcs(spa=5)
calc = @handcalcs begin
x = 5
y = 4
end
@test calc == expected
@test Dict(:spa => 5) == get_handcalcs()
reset_handcalcs()

expected =LaTeXString("\\begin{align}
x &= 5
\\\\[10pt]
y &= 4
\\end{align}")
set_handcalcs(h_env="align")
calc = @handcalcs begin
x = 5
y = 4
end
@test calc == expected
reset_handcalcs()
1 change: 1 addition & 0 deletions test/handcalc_macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ calc = @handcalc x = (-b + sqrt(b^2 - 4*a*c))/(2*a)
calc2 = @handcalc begin x = (-b + sqrt(b^2 - 4*a*c))/(2*a) end

@test calc == expected
@test x == 2.0
@test calc2 == expected
# ***************************************************
2 changes: 2 additions & 0 deletions test/handcalcs_macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ c = 2
calc = @handcalcs x = (-b + sqrt(b^2 - 4*a*c))/(2*a)
calc2 = @handcalcs begin x = (-b + sqrt(b^2 - 4*a*c))/(2*a) end
@test calc == expected
@test x == 2.0
@test calc2 == expected
# ***************************************************

Expand All @@ -34,6 +35,7 @@ calc = @handcalcs begin
Ix = b*h^3/12; "moment of inertia x";
end
@test calc == expected
@test Iy == 104.16666666666667
# ***************************************************


Expand Down
1 change: 1 addition & 0 deletions test/handfunc_macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ a = 5
b = 15
calc_4 = @handfunc x = calc_Ix(a, b) # check positional parameters with b = a and h = b. Make sure b is not redfined
@test calc_4 == expected_1
@test x == 1406.25
# ***************************************************


Expand Down
3 changes: 2 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ using TestHandcalcFunctions
@testset "Latexify kwargs " begin include("latexify_kwargs_test.jl") end
@testset "UnitfulLatexify " begin include("unitful_test.jl") end
@testset "handcalcs macro " begin include("handcalcs_macro.jl") end
@testset "handfunc macro " begin include("handfunc_macro.jl") end
@testset "handfunc macro " begin include("handfunc_macro.jl") end
@testset "defaults macro " begin include("default_h_kwargs.jl") end

2 comments on commit 87b0634

@co1emi11er2
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register

Release notes:
This update adds the following:

  • The package will now work in Weave.jl
  • An ability to change default handcalcs settings was added.

Breaking changes

  • In order to get the package to work in Weave.jl, the latexify string for the @handcalcs macro was changed.
    -- Now instead of the begin{align} environment, the begin{aligned} environment is used
    -- You can still change back to the begin{align} environment if you prefer by: set_handcalcs(h_env="align")
    -- The reason it was changed was my preference for the equations to be left aligned in the document instead of centered

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/104521

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.2.0 -m "<description of version>" 87b0634316f45add42d0de7efb013cb647a1032e
git push origin v0.2.0

Please sign in to comment.