diff --git a/interfaces/cython/cantera/ck2yaml.py b/interfaces/cython/cantera/ck2yaml.py index 425efd571df..582951f39d5 100644 --- a/interfaces/cython/cantera/ck2yaml.py +++ b/interfaces/cython/cantera/ck2yaml.py @@ -16,8 +16,6 @@ [--bibtex=] [--output=] [--permissive] - [--quiet] - [--no-validate] [-d | --debug] Example: @@ -35,9 +33,9 @@ 'surface'. The '--permissive' option allows certain recoverable parsing errors (e.g. -duplicate transport data) to be ignored. Further, the '--name=' option -is used to override default phase names (i.e. 'gas'). The '--bibtex=' -option attaches references to the yaml output, where fields are based on BibTeX +duplicate transport data) to be ignored. Further, the '--name=' option +is used to override default phase names (i.e. 'gas'). The '--bibtex=' +option attaches references to the yaml output, where fields are based on BibTeX style input. """ @@ -1338,32 +1336,50 @@ def load_bibtex_file(self, path): """ Load and separate BibTeX-formatted entries from ``path`` on disk. """ - with open(path, 'r', errors='ignore') as bib_file: + def parsecitation(entry): + # split entry into tagged key/value blocks and retrieve entry type + blocks = '\n'.join([e.strip() for e in entry[1:]]).rstrip('}\n ').split(',\n') + out = {'entry_type': entry[0].split('{')[0].strip(' ').lower()} + + for block in blocks: + # retrieve key + parts = block.split('=') + key = parts[0].strip().lower() + block = '='.join(parts[1:]) + # build value + value = [] + for t in block.split('\n'): + value.append(' '.join([v.strip(' "{}') for v in t.split('#')])) + + out[key] = value if len(value) > 1 else value[0] + return out + + def readcitation(bib_file): + entry = [] + count = 0 + while not(entry) or count > 0: + line = strip_nonascii(bib_file.readline()).rstrip() + count += line.count('{') - line.count('}') + count -= line.count('\{') - line.count('\}') + entry.append(line) + if line == "": + break - def readcitation(): - block = [] - count = 0 - while not(block) or count > 0: - line = strip_nonascii(bib_file.readline()).rstrip() - count += line.count('{') - line.count('}') - count -= line.count('\{') - line.count('\}') - block.append(line) - if line == "": - break - - if block[0]: - regex = r"^@+([a-zA-z]+){+(\w+)[ ,]" - bib = re.findall(regex, block[0].strip()) - if bib and block[-1].rstrip()[-1] == '}' and count == 0: - return bib[0][1], block - else: - raise InputError("Encountered invalid syntax in " - "BibTeX entry:\n{}".format('\n'.join(block))) + if entry[0]: + regex = r"^@+([a-zA-z]+){+(\w+)[ ,]" + bib = re.findall(regex, entry[0].strip()) + if bib and entry[-1].rstrip()[-1] == '}' and count == 0: + return bib[0][1], parsecitation(entry) else: - return None, None + raise InputError("Encountered invalid syntax in " + "BibTeX entry:\n{}".format('\n'.join(entry))) + else: + return None, None + + with open(path, 'r', errors='ignore') as bib_file: while True: - label, entry = readcitation() + label, entry = readcitation(bib_file) if label is not None: self.bibtex[label] = entry else: @@ -1888,18 +1904,24 @@ def write_yaml(self, name='gas', out_name='mech.yaml'): # bibtex entries if self.bibtex: - entries = [] + entries = BlockMap() for key, val in self.bibtex.items(): - desc = '\n'.join(val) - desc = yaml.scalarstring.PreservedScalarString(desc) - entries.append((key, desc)) - bib = BlockMap([('references', BlockMap(entries))]) + tags = [] + comment = val.pop('entry_type') + for k, v in val.items(): + if isinstance(v, list): + desc = '\n'.join(v) + desc = yaml.scalarstring.PreservedScalarString(desc) + elif v.isdigit(): + desc = int(v) + else: + desc = v + tags.append((k, desc)) + entries[key] = BlockMap(tags) + entries.yaml_add_eol_comment(comment, key) + bib = BlockMap([('references', entries)]) if desc.strip(): - bib.yaml_set_comment_before_after_key( - 'references', - before='\n', - after='references use BibTeX format' - ) + bib.yaml_set_comment_before_after_key('references', before='\n') emitter.dump(bib, dest) # Additional information regarding conversion