Skip to content
Snippets Groups Projects
Commit e568d84b authored by Vanessa Stehr's avatar Vanessa Stehr
Browse files

Restructure to using dsiTree class

parent 56c0419b
No related branches found
No related tags found
No related merge requests found
import re
import warnings
def toLatex(dsiString: str):
"""parses a D-SI unit string and converts it to LaTeX
class dsiTree:
def __init__(self, dsiString: str):
(self.tree, self.warnings) = _parseDsi(dsiString)
self.valid = len(self.warnings) == 0
Args:
dsiString (str): D-SI unit raw string
def toLatex(self):
"""parses a D-SI unit string and converts it to LaTeX
Returns:
str: the corresponding LaTeX code
"""
tree = _parseDsi(dsiString)
if tree == []:
return ""
latexArray = []
if len(tree) == 1: # no fractions
for node in tree[0]:
latexArray.append(_nodeToLatex(node))
return r'\,'.join(latexArray)
elif len(tree) == 2: # one fraction
latexString = ""
latexString += r'\frac'
for frac in tree:
latexString += r'{'
nodeArray = []
for node in frac:
nodeArray.append(_nodeToLatex(node))
latexString += r'\,'.join(nodeArray)
latexString += r'}'
return latexString
else: # more than one fraction
latexString = ""
for i in range(len(tree)):
nodeArray = []
if i > 0:
latexString += r'{\color{red}/}'
for node in tree[i]:
nodeArray.append(_nodeToLatex(node))
latexString += r'\,'.join(nodeArray)
return latexString
def _nodeToLatex(node: list):
Returns:
str: the corresponding LaTeX code
"""
if self.tree == []:
return ""
latexArray = []
if len(self.tree) == 1: # no fractions
for node in self.tree[0]:
latexArray.append(_nodeToLatex(node))
return r'\,'.join(latexArray)
elif len(self.tree) == 2: # one fraction
latexString = ""
latexString += r'\frac'
for frac in self.tree:
latexString += r'{'
nodeArray = []
for node in frac:
nodeArray.append(_nodeToLatex(node))
latexString += r'\,'.join(nodeArray)
latexString += r'}'
return latexString
else: # more than one fraction
latexString = ""
for i in range(len(self.tree)):
nodeArray = []
if i > 0:
latexString += r'{\color{red}/}'
for node in self.tree[i]:
nodeArray.append(_nodeToLatex(node))
latexString += r'\,'.join(nodeArray)
return latexString
def _nodeToLatex( node: list):
"""generates a latex string from a node with three elements: prefix, unit, power
Args:
......@@ -79,23 +80,26 @@ def _parseDsi(dsiString: str):
dsiString (str): D-SI unit raw string
Returns:
list: list tree containing the D-SI unit
list: tree containing the D-SI unit
list: warning messages of problems encountered while parsing
"""
warningMessages = []
# Catch any double (triple...) \ before they annoy us
while r'\\' in dsiString:
warnings.warn(f"Double backslash found in string, treating as one backslash: \"{dsiString}\"", RuntimeWarning)
warningMessages.append(_warn(f"Double backslash found in string, treating as one backslash: \"{dsiString}\"", RuntimeWarning))
dsiString = dsiString.replace(r'\\', '\\')
if dsiString == "":
warnings.warn("Given D-SI string is empty!", RuntimeWarning)
return []
warningMessages.append(_warn("Given D-SI string is empty!", RuntimeWarning))
return ([], warningMessages)
tree = []
tree = _parseDsiFraction(dsiString)
(tree, fractionWarnings) = _parseDsiFraction(dsiString)
warningMessages += fractionWarnings
for i, node in enumerate(tree):
tree[i] = _parseFractionlessDsi(node)
return tree
(tree[i], fractionlessWarnings) = _parseFractionlessDsi(node)
warningMessages += fractionlessWarnings
return (tree, warningMessages)
def _parseDsiFraction(dsiString: str):
"""parses D-SI fraction into list of fraction elements
......@@ -108,15 +112,17 @@ def _parseDsiFraction(dsiString: str):
as defined in the D-SI specs
Returns:
list: List containing the strings separated by the \per
list: strings separated by the \per
list: warning messages of problems encountered while parsing
"""
tree = []
warningMessages = []
tree = dsiString.split("\per")
if len(tree) > 2:
warnings.warn(f"The dsi string contains more than one \per, does not "+
f"match specs! Given string: {dsiString}",
RuntimeWarning)
return tree
warningMessages.append(_warn(f"The dsi string contains more than one \per, does not "+
f"match specs! Given string: {dsiString}",
RuntimeWarning))
return (tree, warningMessages)
def _parseFractionlessDsi(dsiString:str):
"""parses D-SI unit string without fractions
......@@ -129,12 +135,14 @@ def _parseFractionlessDsi(dsiString:str):
Returns:
list: list of three-item lists; containing prefix, unit, power
list: warning messages of problems encountered while parsing
"""
warningMessages = []
items = dsiString.split("\\")
if items[0] == '': #first item of List should be empty, remove it
items.pop(0)
else:
warnings.warn(f"string should start with \\, string given was \"{dsiString}\"", RuntimeWarning)
warningMessages.append(_warn(f"string should start with \\, string given was \"{dsiString}\"", RuntimeWarning))
nodes = []
tuple = ['','','']
......@@ -164,20 +172,24 @@ def _parseFractionlessDsi(dsiString:str):
item = items.pop(0)
except IndexError:
item = ''
warnings.warn(f"The identifier \"{tuple[1]}\" does not match any D-SI units!", RuntimeWarning)
warningMessages.append(_warn(f"The identifier \"{tuple[1]}\" does not match any D-SI units!", RuntimeWarning))
elif tuple[1] == '':
itemStr = ""
if tuple[0] != "":
itemStr = itemStr + "\\" + tuple[0]
if tuple[2] != "":
itemStr = itemStr + r"\tothe{" + tuple[2] + r"}"
warnings.warn(f"This unit seems to be missing the base unit! \"{itemStr}\"", RuntimeWarning)
warningMessages.append(_warn(f"This unit seems to be missing the base unit! \"{itemStr}\"", RuntimeWarning))
nodes.append(tuple)
if (len(items) == 0) and (item == ''): break
tuple = ['','','']
return nodes
return (nodes, warningMessages)
def _warn(message: str, warningClass):
warnings.warn(message, warningClass)
return message
# mapping D-SI prefixes to latex
_dsiPrefixesLatex = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment