簡易HTMLの作成ライブラリ¶
簡易HTMLによる実験データの整理など¶
データをHTMLで見やすくしたい.
csv や json、png などの形式のデータを HTMLに変換する.
使用方法¶
呼び出し¶
import nkUtilities.generate__html as ght
ght.generate__html( html_config="dat/html_config.json" )
入力コンフィグファイル¶
{
"settings":{
"title" : "test page",
"cssFile" : "dat/style.css",
"paramsFile" : "dat/ri_prod.json",
"htmlFile" : "html/output.html",
"csvFile" : "dat/sample.csv",
},
"images":{
"image1":{
filepath : "png/dice.jpg",
width : "100px",
},
"image2":{
filepath : "png/dice.jpg",
width : "400px",
},
},
}
paramsFile はjson ファイル形式
コード¶
#!/usr/bin/env python3
import os, sys, json5, argparse, shutil
import nkUtilities.json__formulaParser as jso
import pandas as pd
# ========================================================= #
# === translate__json2html === #
# ========================================================= #
def translate__json2html( data ):
# ------------------------------------------------- #
# --- [1] recursive translation --- #
# ------------------------------------------------- #
if isinstance( data, type(None) ): # -- None -- #
return( '<div class="bool-true">None</div>\n' )
elif isinstance( data, bool ): # -- bool -- #
sval = str(data)
return( '<div class="bool-{0}">{1}</div>\n'.format( sval.lower(), sval ) )
elif isinstance( data, str ): # -- str -- #
if ( len(data) == 0):
return( '<span class="string empty">(Empty Text)</span>\n' )
else:
return( f'<span class="string">{data}</span>\n' )
elif isinstance(data, (int, float)):
# INT or FLOAT
if isinstance(data, int):
class_name = "int number"
else:
class_name = "float number"
return f'<span class="{class_name}">{data}</span>\n'
elif isinstance(data, list):
# ARRAY
if len(data) > 0:
html = '<table class="array">\n'
for i, item in enumerate(data):
html += '<tr>\n'
html += '<td class="value array-value">\n'
html += translate__json2html( data=item )
html += '</td></tr>\n'
html += '</table>\n'
return html
else:
return '<span class="array empty">(Empty List)</span>\n'
elif isinstance( data, dict ):
# OBJECT
html = '<table class="object">\n'
for key, value in data.items():
html += '<tr>\n'
html += f'<th class="key object-key">{key}</th>\n'
html += '<td class="value object-value">\n'
html += translate__json2html( data=value )
html += '</td></tr>\n'
html += '</table>\n'
return html
elif callable(data):
# FUNCTION
return f'<span class="function">{data}</span>\n'
else:
# UNKNOWN
return f'<span class="unknown">{data}</span>\n'
# ========================================================= #
# === generate__html === #
# ========================================================= #
def generate__html( html_lines=[], html_config=None, silent=False ):
if ( html_config is None ): sys.exit( "[generate__html.py] html_config == ???" )
title, paramsFile = None, None
cssFile, htmlFile = None, None
config = jso.json__formulaParser( inpFile=html_config )
settings, images = config["settings"], config["images"]
if ( "cssFile" in settings ): cssFile = settings[ "cssFile" ]
if ( "title" in settings ): title = settings[ "title" ]
if ( "paramsFile" in settings ): paramsFile = settings[ "paramsFile" ]
if ( "htmlFile" in settings ): htmlFile = settings[ "htmlFile" ]
if ( "csvFile" in settings ): csvFile = settings[ "csvFile" ]
# ------------------------------------------------- #
# --- [1] html header part --- #
# ------------------------------------------------- #
html_lines += [ "<html>", "<head>" ]
if ( title ):
html_lines += [ f"<title>{title}</title>" ]
if ( cssFile ):
if ( htmlFile ):
css_filepath = os.path.basename( cssFile )
out_dirpath = os.path.dirname ( htmlFile )
css_copypath = os.path.join( out_dirpath, css_filepath )
shutil.copy( cssFile, css_copypath )
html_lines += [ f'<link rel="stylesheet" type="text/css" href="{css_filepath}"/>\n' ]
html_lines += [ "</head>", "<body>" ]
# ------------------------------------------------- #
# --- [2] html body part --- #
# ------------------------------------------------- #
if ( title ):
html_lines += [ f'<h1>{title}</h1>\n' ]
if ( paramsFile ):
if ( os.path.exists( paramsFile ) ):
data = jso.json__formulaParser( inpFile=paramsFile )
else:
print( "[generate__html.py] cannot find paramsFile... {} ".format( paramsFile ) )
sys.exit()
translation = translate__json2html( data )
html_lines += [ translation ]
# ------------------------------------------------- #
# --- [3] html image file --- #
# ------------------------------------------------- #
if ( csvFile ):
csvData = pd.read_csv( csvFile )
csvData = csvData.set_index( csvData.columns[0] )
html_lines += [ csvData.to_html( classes='table_design', index_names=False ) ]
# ------------------------------------------------- #
# --- [4] html image file --- #
# ------------------------------------------------- #
imgtag = '<img src="../{0}" width="{1}">'
for key,obj in images.items():
command = imgtag.format( obj["filepath"], obj["width"] )
if ( not( "line_break" in obj ) ): obj["line_break"] = True
if ( obj["line_break"] is True ): command = f"<p> {command} </p>"
html_lines += [ command ]
# ------------------------------------------------- #
# --- [5] html closing part / save html file --- #
# ------------------------------------------------- #
html_lines += [ "</body>", "</html>" ]
html_strings = "\n".join( html_lines )
if ( htmlFile ):
with open( htmlFile, "w" ) as f:
f.write( html_strings )
if not( silent ):
print( "[generate__html.py] output file :: {}".format( htmlFile ) )
return( html_strings )
# ========================================================= #
# === Execution of Pragram === #
# ========================================================= #
if ( __name__=="__main__" ):
default_html_config = "dat/html_config.json"
# ------------------------------------------------- #
# --- [1] arguments --- #
# ------------------------------------------------- #
import argparse
parser = argparse.ArgumentParser()
parser.add_argument( "--html_config", help="system config file for html." )
parser.add_argument( "-s","--silent", help="no display", \
default=False, action="store_true" )
args = parser.parse_args()
if args.html_config:
html_config = args.html_config
else:
html_config = default_html_config
# ------------------------------------------------- #
# --- [2] call arguments --- #
# ------------------------------------------------- #
generate__html( html_config=html_config, silent=args.silent )
実行結果¶
<html>
<head>
<title>test page</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<h1>test page</h1>
<table class="object">
<tr>
<th class="key object-key">results.summaryFile</th>
<td class="value object-value">
<span class="string">dat/summary.dat</span>
</td></tr>
<tr>
<th class="key object-key">results.time.unit</th>
<td class="value object-value">
<span class="string">d</span>
</td></tr>
<tr>
<th class="key object-key">results.yieldFile</th>
<td class="value object-value">
<span class="string">dat/yield.dat</span>
</td></tr>
<tr>
<th class="key object-key">target.g/cm3</th>
<td class="value object-value">
<span class="float number">19.3</span>
</td></tr>
<tr>
<th class="key object-key">target.g/mol</th>
<td class="value object-value">
<span class="float number">197.0</span>
</td></tr>
<tr>
<th class="key object-key">target.mass.mg</th>
<td class="value object-value">
<span class="float number">4.75</span>
</td></tr>
<tr>
<th class="key object-key">target.activity.Bq</th>
<td class="value object-value">
<div class="bool-true">None</div>
</td></tr>
<tr>
<th class="key object-key">target.halflife</th>
<td class="value object-value">
<table class="object">
<tr>
<th class="key object-key">value</th>
<td class="value object-value">
<div class="bool-true">None</div>
</td></tr>
<tr>
<th class="key object-key">unit</th>
<td class="value object-value">
<span class="string">y</span>
</td></tr>
</table>
</td></tr>
<tr>
<th class="key object-key">product.halflife</th>
<td class="value object-value">
<table class="object">
<tr>
<th class="key object-key">value</th>
<td class="value object-value">
<span class="float number">6.16</span>
</td></tr>
<tr>
<th class="key object-key">unit</th>
<td class="value object-value">
<span class="string">d</span>
</td></tr>
</table>
</td></tr>
<tr>
<th class="key object-key">decayed.halflife</th>
<td class="value object-value">
<table class="object">
<tr>
<th class="key object-key">value</th>
<td class="value object-value">
<div class="bool-true">None</div>
</td></tr>
<tr>
<th class="key object-key">unit</th>
<td class="value object-value">
<span class="string">d</span>
</td></tr>
</table>
</td></tr>
<tr>
<th class="key object-key">target.thick.type</th>
<td class="value object-value">
<span class="string">fluence-mass</span>
</td></tr>
<tr>
<th class="key object-key">target.thick.direct.mm</th>
<td class="value object-value">
<span class="float number">1.0</span>
</td></tr>
<tr>
<th class="key object-key">target.area.type</th>
<td class="value object-value">
<span class="string">disk</span>
</td></tr>
<tr>
<th class="key object-key">target.area.direct.cm2</th>
<td class="value object-value">
<span class="float number">0.0707</span>
</td></tr>
<tr>
<th class="key object-key">target.area.diameter.mm</th>
<td class="value object-value">
<span class="float number">3.0</span>
</td></tr>
<tr>
<th class="key object-key">integral.method</th>
<td class="value object-value">
<span class="string">simpson</span>
</td></tr>
<tr>
<th class="key object-key">integral.EAxis.min</th>
<td class="value object-value">
<span class="float number">0.0</span>
</td></tr>
<tr>
<th class="key object-key">integral.EAxis.max</th>
<td class="value object-value">
<span class="float number">50.0</span>
</td></tr>
<tr>
<th class="key object-key">integral.EAxis.num</th>
<td class="value object-value">
<span class="int number">501</span>
</td></tr>
<tr>
<th class="key object-key">photon.filetype</th>
<td class="value object-value">
<span class="string">phits-out</span>
</td></tr>
<tr>
<th class="key object-key">photon.filename</th>
<td class="value object-value">
<span class="string">out/fluence_energy.dat</span>
</td></tr>
<tr>
<th class="key object-key">photon.bin2point.convert</th>
<td class="value object-value">
<span class="string">edge</span>
</td></tr>
<tr>
<th class="key object-key">photon.fit.method</th>
<td class="value object-value">
<span class="string">linear</span>
</td></tr>
<tr>
<th class="key object-key">photon.fit.p0</th>
<td class="value object-value">
<div class="bool-true">None</div>
</td></tr>
<tr>
<th class="key object-key">photon.fit.Eth</th>
<td class="value object-value">
<span class="float number">6.4</span>
</td></tr>
<tr>
<th class="key object-key">photon.beam.current.sim</th>
<td class="value object-value">
<span class="float number">100.0</span>
</td></tr>
<tr>
<th class="key object-key">photon.beam.current.use</th>
<td class="value object-value">
<span class="float number">6.2</span>
</td></tr>
<tr>
<th class="key object-key">photon.beam.duration</th>
<td class="value object-value">
<span class="float number">0.1667</span>
</td></tr>
<tr>
<th class="key object-key">xsection.filename</th>
<td class="value object-value">
<span class="string">dat/xs__JENDL_Au197_gn_Au196.dat</span>
</td></tr>
<tr>
<th class="key object-key">xsection.database</th>
<td class="value object-value">
<span class="string">JENDL</span>
</td></tr>
<tr>
<th class="key object-key">xsection.fit.Eth</th>
<td class="value object-value">
<span class="float number">8.07</span>
</td></tr>
<tr>
<th class="key object-key">xsection.fit.method</th>
<td class="value object-value">
<span class="string">linear</span>
</td></tr>
<tr>
<th class="key object-key">xsection.fit.p0</th>
<td class="value object-value">
<div class="bool-true">None</div>
</td></tr>
<tr>
<th class="key object-key">plot.filename</th>
<td class="value object-value">
<span class="string">png/dYield__RIproduction.png</span>
</td></tr>
<tr>
<th class="key object-key">plot.xRange</th>
<td class="value object-value">
<table class="array">
<tr>
<td class="value array-value">
<span class="float number">0.0</span>
</td></tr>
<tr>
<td class="value array-value">
<span class="float number">20.0</span>
</td></tr>
<tr>
<td class="value array-value">
<span class="int number">11</span>
</td></tr>
</table>
</td></tr>
<tr>
<th class="key object-key">plot.yRange</th>
<td class="value object-value">
<table class="array">
<tr>
<td class="value array-value">
<span class="float number">0.0</span>
</td></tr>
<tr>
<td class="value array-value">
<span class="float number">10.0</span>
</td></tr>
<tr>
<td class="value array-value">
<span class="int number">11</span>
</td></tr>
</table>
</td></tr>
<tr>
<th class="key object-key">plot.xsection.norm</th>
<td class="value object-value">
<span class="float number">100.0</span>
</td></tr>
<tr>
<th class="key object-key">plot.photon.norm</th>
<td class="value object-value">
<span class="float number">10000.0</span>
</td></tr>
<tr>
<th class="key object-key">plot.dYield.norm</th>
<td class="value object-value">
<span class="float number">10000.0</span>
</td></tr>
<tr>
<th class="key object-key">plot.norm.auto</th>
<td class="value object-value">
<div class="bool-true">True</div>
</td></tr>
</table>
<table border="1" class="dataframe table_design">
<thead>
<tr style="text-align: right;">
<th></th>
<th>math</th>
<th>english</th>
<th>physics</th>
<th>geology</th>
</tr>
</thead>
<tbody>
<tr>
<th>tom</th>
<td>90</td>
<td>100</td>
<td>80</td>
<td>95</td>
</tr>
<tr>
<th>bob</th>
<td>80</td>
<td>70</td>
<td>60</td>
<td>98</td>
</tr>
<tr>
<th>jessy</th>
<td>50</td>
<td>50</td>
<td>60</td>
<td>80</td>
</tr>
</tbody>
</table>
<p> <img src="../png/dice.jpg" width="100px"> </p>
<p> <img src="../png/dice.jpg" width="400px"> </p>
</body>
</html>