From e54e6e5f90c60ca06adf567252be093f49f9b2d6 Mon Sep 17 00:00:00 2001 From: co1emi11er2 Date: Thu, 11 Apr 2024 19:42:21 -0500 Subject: [PATCH 1/5] Added ability to show parameters --- src/Handcalcs.jl | 6 ++++-- src/handcalc_marco.jl | 17 ++++++++++++++--- src/handcalcs_macro.jl | 25 +++++++++++++++++++++---- test/handcalcs_macro.jl | 32 +++++++++++++++++++++++++++++++- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/Handcalcs.jl b/src/Handcalcs.jl index 56e29cb..66e36f3 100644 --- a/src/Handcalcs.jl +++ b/src/Handcalcs.jl @@ -3,14 +3,16 @@ Module for better calc documentation. """ module Handcalcs -using Latexify: latexify, set_default, get_default, reset_default +using Latexify: latexify, set_default, get_default, reset_default, @latexdefine using MacroTools: postwalk, prewalk using MacroTools using LaTeXStrings using CodeTracking, Revise using InteractiveUtils -export @handcalc, @handcalcs, latexify, multiline_latex, set_default, get_default, reset_default, @handfunc, set_handcalcs, reset_handcalcs, get_handcalcs #, initialize_format +export @handcalc, @handcalcs, @handfunc, multiline_latex +export set_handcalcs, reset_handcalcs, get_handcalcs #, initialize_format +export latexify, @latexdefine, set_default, get_default, reset_default # function initialize_format() # @eval begin diff --git a/src/handcalc_marco.jl b/src/handcalc_marco.jl index 8b02330..77ad630 100644 --- a/src/handcalc_marco.jl +++ b/src/handcalc_marco.jl @@ -43,15 +43,26 @@ macro handcalc(expr, kwargs...) break end end - return esc( + return _handcalc(expr, expr_numeric, post, kwargs) +end + +# Handcalcs - Symbolic and Numeric return +# *************************************************** +function _handcalc(expr, expr_numeric, post, kwargs) + esc( Expr( :call, :latexify, - Expr(:parameters, _extractparam.(kwargs)...), - Expr(:call, :Expr, QuoteNode(:(=)), Meta.quot(expr), Expr(:call, :Expr, QuoteNode(:(=)), Meta.quot(expr_numeric), Expr(:call, post, _executable(expr)))), + Expr(:parameters, _extractparam.(kwargs)...), + Expr(:call, :Expr, + QuoteNode(:(=)), Meta.quot(expr), # symbolic portion + Expr(:call, :Expr, + QuoteNode(:(=)), Meta.quot(expr_numeric), # numeric portion + Expr(:call, post, _executable(expr)))), # defines variable ), ) end +# *************************************************** # Latexify Functions # *************************************************** diff --git a/src/handcalcs_macro.jl b/src/handcalcs_macro.jl index f40bb01..a89dadb 100644 --- a/src/handcalcs_macro.jl +++ b/src/handcalcs_macro.jl @@ -34,13 +34,22 @@ julia> d macro handcalcs(expr, kwargs...) expr = unblock(expr) expr = rmlines(expr) - exprs = [] + h_kwargs, kwargs = clean_kwargs(kwargs) # parse handcalc kwargs (h_kwargs) + + exprs = [] #initialize expression accumulator + + # If singular symbol + if typeof(expr) == Symbol + push!(exprs, :(@latexdefine $(expr) $(kwargs...))) + return _handcalcs(exprs, h_kwargs) + end + # If singular expression if expr.head == :(=) push!(exprs, :(@handcalc $(expr) $(kwargs...))) - return Expr(:block, esc(Expr(:call, :multiline_latex, exprs...))) + return _handcalcs(exprs, h_kwargs) end - h_kwargs, kwargs = clean_kwargs(kwargs) + # If multiple Expressions for arg in expr.args if typeof(arg) == String # type string will be converted to a comment @@ -48,11 +57,19 @@ macro handcalcs(expr, kwargs...) push!(exprs, comment) elseif typeof(arg) == Expr # type expression will be latexified push!(exprs, :(@handcalc $(arg) $(kwargs...))) + elseif typeof(arg) == Symbol # type symbol is a parameter that will be returned back + push!(exprs, :(@latexdefine $(arg) $(kwargs...))) else error("Code pieces should be of type string or expression") end end - return Expr(:block, esc(Expr(:call, :multiline_latex, Expr(:parameters, _extractparam.(h_kwargs)...), exprs...))) + return _handcalcs(exprs, h_kwargs) +end + +function _handcalcs(exprs, h_kwargs) + Expr(:block, esc( + Expr(:call, :multiline_latex, + Expr(:parameters, _extractparam.(h_kwargs)...), exprs...))) end function multiline_latex(exprs...; kwargs...) diff --git a/test/handcalcs_macro.jl b/test/handcalcs_macro.jl index f41bcb8..4ef7974 100644 --- a/test/handcalcs_macro.jl +++ b/test/handcalcs_macro.jl @@ -127,4 +127,34 @@ calc = @handcalcs begin end cols=3 spa=5 @test calc == expected -# *************************************************** \ No newline at end of file +# *************************************************** + + +# parameters test +# *************************************************** +# *************************************************** +expected = L"$\begin{aligned} +a &= 5 +\\[10pt] +b &= 6 +\end{aligned}$" + +a = 5 + +calc = @handcalcs begin # check mix of symbol and variable + a + b = 6 +end +@test calc == expected + +expected = L"$\begin{aligned} +a &= 5 +\end{aligned}$" + +calc = @handcalcs a # check single symbol +@test calc == expected + +calc = @handcalcs begin a end +@test calc == expected +# *************************************************** + From 75edcbb44092f14c4a915a299f5c40268f9cfb1c Mon Sep 17 00:00:00 2001 From: co1emi11er2 Date: Thu, 11 Apr 2024 19:57:45 -0500 Subject: [PATCH 2/5] update docs --- docs/src/index.md | 38 +++++++++++++++++++++++++++++++------- src/handcalcs_macro.jl | 6 ++++-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index 27a8879..bdb7e22 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -8,7 +8,10 @@ CurrentModule = Handcalcs This is the documentation for [Handcalcs.jl](https://github.com/co1emi11er2/Handcalcs.jl). 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. +**Note: This package now renders properly in Quarto/Weave!! You can change the default settings to your liking. See examples below.** + ## Examples + ### A single expression example: ```@example main @@ -18,12 +21,15 @@ b = -5 c = 2 @handcalcs x = (-b + sqrt(b^2 - 4*a*c))/ (2*a) ``` + The variable x is still evaluated: + ```@example main x ``` ### An example of multiple expressions: + ```@example main b = 5 # width h = 15 # height @@ -39,15 +45,21 @@ 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") ``` + ### 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"). +- h_env - change the environment (default = "aligned"). + +**Note: `@handcalcs` macro can also take symbols of defined variables. See below.** + ```@example main +a, b, c = 1, 2, 3 @handcalcs begin - a = 1 - b = 2 - c = 3 + a # see note above + b + c x = 4 y = 5 z = 6 @@ -55,36 +67,47 @@ end cols=3 spa=0 ``` ### An example for rendering expressions within a function: + ```@example main using TestHandcalcFunctions b = 5 # width h = 15 # height @handfunc Ix = calc_Ix(b, h) # function is defined in TestHandcalcFunctions package ``` + 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` + - 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 +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() ``` @@ -99,6 +122,7 @@ a = 2u"inch" b = -5u"inch" @handcalc c = sqrt(a^2 + b^2) ``` + 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](https://github.com/korsbo/Latexify.jl/pull/280). 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 @@ -106,10 +130,10 @@ You can see that it looks as though only the unit is being squared. This should There are a number of things that I would like to implement to the package. See [handcalcs.py](https://github.com/connorferster/handcalcs) 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 + ```@index ``` diff --git a/src/handcalcs_macro.jl b/src/handcalcs_macro.jl index a89dadb..c839696 100644 --- a/src/handcalcs_macro.jl +++ b/src/handcalcs_macro.jl @@ -19,10 +19,12 @@ julia> @handcalcs begin d = a - c end L"\$\\begin{aligned} -c &= a + b = 2 + 5 = 7\\text{ }(\\text{eq 1}) +c &= a + b = 2 + 5 = 7\\;\\text{ }(\\text{eq 1}) \\\\[10pt] d &= a - c = 2 - 7 = -5 -\\end{aligned}\$" +\\\\[10pt] +e &= 7 +\\end{aligned}$" julia> c 7 From 3d2089386037176f03d90d48c0b141244f96c224 Mon Sep 17 00:00:00 2001 From: co1emi11er2 Date: Thu, 11 Apr 2024 20:00:18 -0500 Subject: [PATCH 3/5] update handcalcs docstring --- src/handcalcs_macro.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/handcalcs_macro.jl b/src/handcalcs_macro.jl index c839696..9bf5bc1 100644 --- a/src/handcalcs_macro.jl +++ b/src/handcalcs_macro.jl @@ -12,11 +12,17 @@ Can also add comments to the end of equations. See example below. ```julia-repl julia> a = 2 2 + julia> b = 5 5 + +julia> e = 7 +7 + julia> @handcalcs begin c = a + b; "eq 1"; d = a - c + e end L"\$\\begin{aligned} c &= a + b = 2 + 5 = 7\\;\\text{ }(\\text{eq 1}) @@ -24,10 +30,11 @@ c &= a + b = 2 + 5 = 7\\;\\text{ }(\\text{eq 1}) d &= a - c = 2 - 7 = -5 \\\\[10pt] e &= 7 -\\end{aligned}$" +\\end{aligned}\$" julia> c 7 + julia> d -5 From 5084a22315dd90c948aefe70758acc5c5bf8c2fc Mon Sep 17 00:00:00 2001 From: co1emi11er2 Date: Thu, 11 Apr 2024 20:02:44 -0500 Subject: [PATCH 4/5] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 38853c1..92320c7 100644 --- a/README.md +++ b/README.md @@ -13,26 +13,35 @@ This is a package for generating LaTeX maths and designed to improve documentati 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. +**Note: This package now renders properly in Quarto/Weave!! You can change the default settings to your liking. See [docs](https://co1emi11er2.github.io/Handcalcs.jl/stable/) for more info.** + ## Basic Demo + ![handcalc demo](/assets/handcalcs_demo.gif) ## Basic example: + ### Single line expression + ```julia using Handcalcs a = 3 b = 4 @handcalcs c = sqrt(a^2 + b^2) ``` + or + ```julia @handcalcs begin c = sqrt(a^2 + b^2) end ``` + You may want to do the latter in Pluto. This will supress the assignment callout in the top left of the output cell. This generates a LaTeXString (from [LaTeXStrings.jl](https://github.com/stevengj/LaTeXStrings.jl)) which, when printed looks like: + ```LaTeX $c = \sqrt{a^{2} + b^{2}} = \sqrt{3^{2} + 4^{2}} = 5.0$ ``` From b9b8b549bcd967b986399d4bde7311b725f310d3 Mon Sep 17 00:00:00 2001 From: co1emi11er2 Date: Thu, 11 Apr 2024 20:07:37 -0500 Subject: [PATCH 5/5] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index d7a5630..f2d68a5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "Handcalcs" uuid = "e8a07092-c156-4455-ab8e-ed8bc81edefb" authors = ["Cole Miller"] -version = "0.2.0" +version = "0.2.1" [deps] CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"