from math import log10, floor
# needs the xstring package to be included in the tex document for IfEqCase to work
# ... BUT IfEqCase is depressingly slow, so I switched to pdfstrcmp. apparently, this only works with pdflatex (but who uses anything else around here?), but it's much faster
# tex using IfEqCase:
#
#headertex = "\\newcommand{\\paramvalue}[2][]{\\protect\\IfEqCase{#2}{%\n"
#valtex = "\\IfEqCase{#1}{{dec}{%(decstr)s}{sci}{%(scistr)s}{dec0}{%(decstr0)s}{dec1}{%(decstr1)s}{dec2}{%(decstr2)s}}[%(defstr)s]"
#keyvaltex = "{%(keystr)s}{%(valstr)s}%%\n"
#footer1tex = "}[\PackageError{paramvalue}{unknown param name: #2}{}]}%%\n"
#footerfitex = ""
#footer2tex = ""
# tex using pdfstrcmp and nested \ifnum - \fi blocks
headertex = "\\newcommand{\\paramvalue}[2][]{\\protect %\n"
valtex = "\\ifnum\\pdfstrcmp{#1}{dec}=0 %(decstr)s \\else\\ifnum\\pdfstrcmp{#1}{sci}=0 %(scistr)s \\else\\ifnum\\pdfstrcmp{#1}{dec0}=0 %(decstr0)s \\else\\ifnum\\pdfstrcmp{#1}{dec1}=0 %(decstr1)s \\else\\ifnum\\pdfstrcmp{#1}{dec2}=0 %(decstr2)s \\else %(defstr)s\\fi\\fi\\fi\\fi\\fi"
keyvaltex = "\\ifnum\\pdfstrcmp{#2}{%(keystr)s}=0 %(valstr)s \\else %%\n"
footer1tex = "\\PackageError{paramvalue}{unknown param name: #2}{} %%\n"
footerfitex = "\\fi"
footer2tex = "}\n"
def rmtr(s):
if s == "0": return s
else: return s.rstrip('0').rstrip('.')
class LatexParamValues:
def __init__(self):
self.prmsets = {}
def add(self, prmdict, prefix=None):
if not prefix:
prefix = len(self.prmsets.keys())
self.prmsets[prefix] = prmdict
def write(self, filename, prmdict=None):
if prmdict is not None:
self.add(prmdict)
fh = open(filename, "w")
fh.write(headertex)
printprfx = len(self.prmsets.keys()) > 1
num_needed_fis = 0
for pk in self.prmsets.keys():
prefix = str(pk) + ":" if printprfx else ""
p = self.prmsets[pk]
for k in p.keys():
keystr = prefix + str(k)
valstr = ""
if isinstance(p[k],float):
# we want scientific notation, plus decimal with various formattings
decstr = ""
scistr = ""
e = 1
if p[k] == 0:
decstr = "0"
scistr = "0"
else:
e = floor(log10(abs(p[k])))
b = p[k]/10.**e
decstr = rmtr("%f" % p[k])
scistr = "%s \\times 10^{%s}" % (rmtr("%.2f"%b), rmtr("%.0f"%e))
decstr0 = "%.0f" % p[k]
decstr1 = rmtr("%.1f" % p[k])
decstr2 = rmtr("%.2f" % p[k])
# which one should be the default?
defstr = scistr if abs(e) > 3 else decstr
valstr = valtex % {"decstr": decstr, "scistr": scistr, "decstr0": decstr0, "decstr1": decstr1, "decstr2": decstr2, "defstr": defstr}
else:
valstr = str(p[k])
fh.write(keyvaltex % {"keystr": keystr, "valstr": valstr})
num_needed_fis += 1
fh.write(footer1tex)
fh.write("".join([footerfitex for pk in range(num_needed_fis)]))
fh.write(footer2tex)
fh.close()