Skip to content

Commit

Permalink
Bug fixes, added some units, improved printing
Browse files Browse the repository at this point in the history
  • Loading branch information
JWock82 committed Dec 2, 2023
1 parent d18ab68 commit 0bf84c4
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 12 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ Here are a few useful things to keep in mind when using `ipycalc`:
* Square roots can be displayed using `sqrt`.
* Prime characters can be displayed using `^prime`.
* If a line gets too long for printing, you can add a line break to the description, equation, or reference by inserting `\\`.
* US units are built in via `Pint`. Basic support is available for some more common metric units.
* `ipycalc` has a built in `nbconvert` template called `ipycalc` that works just like the `webpdf` template, except it fixes the the bad margins in the `webpdf` template.
* `ipycalc` has a built in `nbconvert` template called `ipycalc` that works just like the `webpdf` template, except it fixes the the bad margins in the `webpdf` template, reduces the print size to 85% to fit more calcs on a single sheet, and avoids page breaks right after headers.

IPycalc is still in its infancy. I'm sure there are bugs, so be cautious and use your head. A special thanks to @connorferster for `handcalcs` which inspired this project: https://github.com/connorferster/handcalcs
17 changes: 17 additions & 0 deletions ipycalc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
import os
from nbconvert.exporters import WebPDFExporter
from nbconvert.preprocessors import TagRemovePreprocessor

class ipycalcExporter(WebPDFExporter):
"""
A custom PDF exporter for ipycalc.
"""

# This is the name of the folder containing the template in `ipycalc`
custom_template_name = 'nbconvert_template'

# This is the directory where ipycalc is installed on the user's machine
pkg_dir = os.path.dirname(__file__)

# This is the location where the `ipycalc` template is installed on the user's machine
template_dir = os.path.join(pkg_dir, custom_template_name)

def __init__(self):

# Run the WebPDFExporter constructor
super().__init__()

# Set up preprocessors
trp = TagRemovePreprocessor()
trp.remove_cell_tags=['hide_cell']
trp.remove_input_tags=['hide_input']
self.register_preprocessor(trp, enabled=True)

@property
def _extra_template_basedirs(self):
return super()._default_extra_template_basedirs() + [self.template_dir]
Expand Down
35 changes: 26 additions & 9 deletions ipycalc/calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
lbf = ureg.force_pound
lbm = ureg.pound
kip = ureg.kip
ton = ureg.ton
tonf = ureg.force_ton
plf = ureg.plf
klf = ureg.klf
psi = ureg.force_pound/ureg.inch**2
Expand Down Expand Up @@ -55,6 +57,8 @@
km = ureg.kilometer
N = ureg.newton
kN = ureg.kilonewton
ton = ureg.metric_ton
tonnef = ureg.force_metric_ton
Pa = ureg.pascal
kPa = ureg.kilopascal
MPa = ureg.megapascal
Expand Down Expand Up @@ -116,6 +120,8 @@ def sync_namespaces(local_ns):
local_ns['lbm'] = ureg.pound
local_ns['kip'] = ureg.kip
local_ns['k']= ureg.kip
local_ns['ton'] = ureg.ton
local_ns['tonf'] = ureg.force_ton
local_ns['plf'] = ureg.plf
local_ns['klf'] = ureg.klf
local_ns['psi'] = ureg.force_pound/ureg.inch**2
Expand Down Expand Up @@ -143,10 +149,13 @@ def sync_namespaces(local_ns):
local_ns['km'] = ureg.kilometer
local_ns['N'] = ureg.newton
local_ns['kN'] = ureg.kilonewton
local_ns['kg'] = ureg.kilogram
local_ns['Pa'] = ureg.pascal
local_ns['kPa'] = ureg.kilopascal
local_ns['MPa'] = ureg.megapascal
local_ns['GPa'] = ureg.gigapascal
local_ns['tonne'] = ureg.metric_ton
local_ns['tonnef'] = ureg.force_metric_ton

# Provide the IPython console with access to the `funit` method
local_ns['funit'] = funit
Expand All @@ -156,8 +165,7 @@ def process_line(calc_line, local_ns):

# Ampersand symbols will mess with latex table formatting unless they have a `\` in front of
# them
if '&' in calc_line:
calc_line = calc_line.replace('&', '\&')
calc_line = calc_line.replace('&', '\&')

# Break up the line into components: `description`, `variable`, `equation`, `value` and `reference`
if '#' in calc_line:
Expand Down Expand Up @@ -197,8 +205,8 @@ def process_line(calc_line, local_ns):
variable = variable.replace('^prime', '_prime')

# Make a latex copy of the equation and variable before we switch out square root symbols
latex_variable = to_latex(variable)
latex_equation = to_latex(equation)
latex_variable = python_to_latex(variable)
latex_equation = python_to_latex(equation)

# `Pint` prefers exponents to the 1/2 power instead of square roots
equation = alt_sqrt(equation)
Expand Down Expand Up @@ -334,7 +342,14 @@ def process_line(calc_line, local_ns):
return latex_text

#%%
def to_latex(text):
def python_to_latex(text):
"""Converts python equations to latex equations
:param text: Python text to be converted to latex.
:type text: str
:return: Latex text
:rtype: str
"""

# Change spaces we want to keep to the '@' symbol temporarily
text = text.replace(' if ', '@if@')
Expand All @@ -343,6 +358,9 @@ def to_latex(text):
# Add any prime symbols back in
text = text.replace('_prime', '^{\\prime}')

# Switch out Python's exponent symbols for Latex's
text = text.replace('**', '^')

# Add brackets to superscripts and subscripts if they are missing
text = sscript_curly('^', text)
text = sscript_curly('_', text)
Expand Down Expand Up @@ -375,8 +393,7 @@ def to_latex(text):
# Take care of any lower case greek psi characters. This is necessary because 'psi' is also a unit
text = text.replace('grpsi', '\\psi')

# Switch out Python's exponent symbols for Latex's
text = text.replace('**', '^')
#

# Convert common functions to latex
text = text.replace('sin', '\\sin')
Expand All @@ -395,7 +412,7 @@ def to_latex(text):
text = text.replace('*', ' \\cdot{}')
text = text.replace('sqrt', '\\sqrt')

# Change any parentheses to brackets
# Change any parentheses to brackets for `sqrt`, `^`, and `_`
text = curly_brackets('sqrt', text)
text = curly_brackets('^', text)
text = curly_brackets('_', text)
Expand Down Expand Up @@ -496,7 +513,7 @@ def sscript_curly(symbol, text):
term_list = []
for i, char in enumerate(text):

# Find any lone symbols
# Find any instances of `symbol` that have not already been formatted properly
if char == symbol and text[i:i+2] != symbol + '(' and text[i:i+2] != symbol + '{':

# Initialize the term after the symbol
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="ipycalc",
version="0.0.48",
version="0.0.49",
author="D. Craig Brinck, PE, SE",
author_email="[email protected]",
description="Clean looking engineering calculations for IPython",
Expand Down

0 comments on commit 0bf84c4

Please sign in to comment.