#!/usr/bin/env python3 # # Functions to generate basic documentation in HTML and LaTeX for CCPP metadata # # DH* TODO: create a Python module metadata.py with a class Metadata # and use this for ccpp_prebuild.py; create to_html and to_latex routines for it import logging import os from common import decode_container, escape_tex ############################################################################### def metadata_to_html(metadata, model, filename): """Create an HTML page with a table that lists each variable provided by the model. Contrary to metadata_to_latex below, this table does not include information on variables requested by schemes. The primary use of the HTML table is to help physics scheme developers to identify the variables they need when writing a CCPP-compliant scheme.""" shading = { 0 : 'darkgray', 1 : 'lightgray' } success = True # Header html = ''' CCPP variables provided by model {model}

CCPP variables provided by model {model}

'''.format(model=model, bgcolor = shading[0]) count = 0 for var_name in sorted(metadata.keys()): for var in metadata[var_name]: # Alternate shading, count is 0 1 0 1 ... count = (count+1) % 2 # ... create html row ... line = ''''''.format(v=var, rank=var.rank.count(':'), container = decode_container(var.container), bgcolor=shading[count]) html += line # Footer html += '''
standard_name long_name units rank type kind source {model} name
{v.standard_name} {v.long_name} {v.units} {rank} {v.type} {v.kind} {container} {v.local_name}
''' filepath = os.path.split(os.path.abspath(filename))[0] if not os.path.isdir(filepath): os.makedirs(filepath) with open(filename, 'w') as f: f.write(html) logging.info('Metadata table for model {0} written to {1}'.format(model, filename)) return success def metadata_to_latex(metadata_define, metadata_request, model, filename): """Create a LaTeX document with a table that lists each variable provided and/or requested. Uses the GMTB LaTeX templates and style definitons in gmtb.sty.""" shading = { 0 : 'darkgray', 1 : 'lightgray' } success = True var_names = sorted(list(set(list(metadata_define.keys()) + list(metadata_request.keys())))) styledir = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../doc/DevelopersGuide')) latex = '''\\documentclass[12pt,letterpaper,oneside,landscape]{{scrbook}} \\usepackage{{import}} \\import{{{styledir}/}}{{gmtb.sty}} \\renewcommand{{\\thesection}}{{\\arabic{{section}}}} \\renewcommand{{\\thesubsection}}{{\\arabic{{section}}.\\arabic{{subsection}}}} \\begin{{document}} \\section{{CCPP variables provided by model {model} vs requested by pool of physics}}\\label{{sec_ccpp_variables}} \\subsection{{List of variables}} \\begin{{longtable}}{{l}}'''.format(model=model, styledir=styledir) for var_name in var_names: if var_name in metadata_define.keys(): var = metadata_define[var_name][0] else: var = metadata_request[var_name][0] line = ''' \hyperlink{{{standard_name_ref}}}{{\\blue\\underline{{\\execout{{{standard_name}}}}}}} \\\\'''.format( standard_name=escape_tex(var.standard_name), standard_name_ref=var.standard_name) latex += line latex += ''' \\end{longtable}\\pagebreak \\subsection{Description of variables} {{\\small\\begin{description} ''' for var_name in var_names: if var_name in metadata_define.keys(): var = metadata_define[var_name][0] target = escape_tex(decode_container(var.container)) local_name = escape_tex(var.local_name) else: var = metadata_request[var_name][0] target = 'MISSING' local_name = 'MISSING' if var_name in metadata_request.keys(): requested_list = [ escape_tex(decode_container(v.container)) if v.container else 'none' for v in metadata_request[var_name] ] # for the purpose of the table, just output the name of the subroutine for i in range(len(requested_list)): entry = requested_list[i] requested_list[i] = entry[entry.find('SUBROUTINE')+len('SUBROUTINE')+1:] requested = '\\newline '.join(sorted(requested_list)) else: requested = 'NOT REQUESTED' # Create output text = ''' \\begin{{samepage}}\\item{{ \hypertarget{{{standard_name_ref}}}{{\\blue\\exec{{{standard_name}}}}}}}\\\\ \\nopagebreak \\begin{{tabular}}{{ll}} \\execout{{long\_name }} & \\execout{{{long_name} }} \\\\ \\execout{{units }} & \\execout{{{units} }} \\\\ \\execout{{rank }} & \\execout{{{rank} }} \\\\ \\execout{{type }} & \\execout{{{type} }} \\\\ \\execout{{kind }} & \\execout{{{kind} }} \\\\ \\execout{{source }} & \\execout{{{target} }} \\\\ \\execout{{local\_name}} & \\execout{{{local_name} }} \\\\ \\execout{{requested }} & \\execout{{\\vtop{{{requested}}}}} \\\\ \\end{{tabular}} \\vspace{{4pt}} \\end{{samepage}}'''.format(standard_name=escape_tex(var.standard_name), standard_name_ref=var.standard_name, long_name=escape_tex(var.long_name), units=escape_tex(var.units), rank=var.rank.count(':'), type=escape_tex(var.type), kind=escape_tex(var.kind), target=target, local_name=local_name, requested=requested) latex += text # Footer latex += ''' \\end{description}}} \\end{document} ''' filepath = os.path.split(os.path.abspath(filename))[0] if not os.path.isdir(filepath): os.makedirs(filepath) with open(filename, 'w') as f: f.write(latex) logging.info('Metadata table for model {0} written to {1}'.format(model, filename)) return success