Skip to content

Commit

Permalink
Merge pull request #7 from co1emi11er2/params
Browse files Browse the repository at this point in the history
Add params ability
  • Loading branch information
co1emi11er2 authored Apr 12, 2024
2 parents 87b0634 + b9b8b54 commit 71d9803
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 19 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.2.0"
version = "0.2.1"

[deps]
CodeTracking = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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$
```
Expand Down
38 changes: 31 additions & 7 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -39,52 +45,69 @@ 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
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()
```
Expand All @@ -99,17 +122,18 @@ 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

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
```

Expand Down
6 changes: 4 additions & 2 deletions src/Handcalcs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 14 additions & 3 deletions src/handcalc_marco.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
# ***************************************************
Expand Down
36 changes: 31 additions & 5 deletions src/handcalcs_macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,29 @@ 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})
c &= a + b = 2 + 5 = 7\\;\\text{ }(\\text{eq 1})
\\\\[10pt]
d &= a - c = 2 - 7 = -5
\\\\[10pt]
e &= 7
\\end{aligned}\$"
julia> c
7
julia> d
-5
Expand All @@ -34,25 +43,42 @@ 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
comment = latexstring("\\;\\text{ }(\\text{", arg, "})")
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...)
Expand Down
32 changes: 31 additions & 1 deletion test/handcalcs_macro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,34 @@ calc = @handcalcs begin
end cols=3 spa=5

@test calc == expected
# ***************************************************
# ***************************************************


# 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
# ***************************************************

2 comments on commit 71d9803

@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:

  • Adds the ability to accept parameters

For example:

julia> a, b  = 1, 2
(1, 2)

julia> @handcalcs a, b
L"$\begin{aligned}
a &= 1
\\[10pt]
b &= 2
\end{aligned}$"

@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/104744

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.1 -m "<description of version>" 71d98030862b821f4c50f76e9374722abc9d3031
git push origin v0.2.1

Please sign in to comment.