pinout.vvzero.com/generate-html.py

397 lines
11 KiB
Python
Raw Normal View History

2015-02-24 17:59:29 +08:00
#!/usr/bin/env python
import json
2015-02-25 06:07:11 +08:00
import markdown
2015-02-24 17:59:29 +08:00
import unicodedata
import re
2015-02-26 01:29:06 +08:00
import os
2015-03-22 05:11:54 +08:00
import time
2015-02-24 17:59:29 +08:00
2015-03-26 07:26:46 +08:00
lang = "en-GB"
2015-03-22 05:11:54 +08:00
base_url = '/pinout/'
resource_url = '/resources/'
2015-03-22 01:27:02 +08:00
default_desc = 'The comprehensive Raspberry Pi GPIO Pinout guide for the original Raspberry Pi, B+ and Pi 2'
default_title = 'Raspberry Pi GPIO Pinout - Pi 1, B+, Pi 2'
title_suffix = ' at Raspberry Pi GPIO Pinout'
pins = None
2015-03-22 05:11:54 +08:00
overlays = [
'spi',
'uart',
'i2c',
'wiringpi',
'arduino-spi',
'rtk-000-001',
'piborg-ledborg',
'piglow',
2015-03-22 05:11:54 +08:00
'pibrella',
'unicorn-hat',
'skywriter-hat',
2015-03-22 05:11:54 +08:00
'explorer-hat-pro',
'explorer-hat',
'display-o-tron',
'dots'
]
2015-02-25 01:28:00 +08:00
2015-03-26 07:26:46 +08:00
template = open('src/{}/template/layout.html'.format(lang)).read()
2015-02-24 17:59:29 +08:00
2015-02-26 01:29:06 +08:00
pages = {}
2015-03-22 01:27:02 +08:00
navs = {}
select_overlays = []
2015-03-22 02:35:46 +08:00
overlays_html = ''
2015-02-26 01:29:06 +08:00
2015-03-22 05:11:54 +08:00
try:
os.mkdir('output')
2015-03-26 07:26:46 +08:00
os.mkdir('output/{}'.format(lang))
os.mkdir('output/{}/pinout'.format(lang))
2015-03-22 05:11:54 +08:00
except OSError:
exit("Failed to create required directories!")
2015-03-22 05:11:54 +08:00
def cssify(value):
value = slugify(value);
if value[0] == '3' or value[0] == '5':
value = 'pow' + value
return value
2015-02-24 17:59:29 +08:00
def slugify(value):
"""
Normalizes string, converts to lowercase, removes non-alpha characters,
and converts spaces to hyphens.
"""
value = unicode(value)
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii')
value = re.sub('[^\w\s-]', '', value).strip().lower()
return re.sub('[-\s]+', '_', value)
def load_overlay(overlay):
try:
2015-03-26 07:26:46 +08:00
loaded = json.load(open('src/{}/overlay/{}.json'.format(lang,overlay)))
2015-02-24 17:59:29 +08:00
except IOError:
return None
2015-03-26 07:26:46 +08:00
loaded['long_description'] = load_md('src/{}/description/overlay/{}.md'.format(lang,overlay))
2015-03-22 01:27:02 +08:00
details = []
if 'manufacturer' in loaded:
details.append('* Made by ' + loaded['manufacturer'])
if 'pincount' in loaded:
pincount = int(loaded['pincount'])
if pincount == 40:
details.append('* HAT form-factor')
elif pincount == 26:
details.append('* Classic 26-pin')
else:
details.append('* {} pin header'.format(pincount))
if 'pin' in loaded:
#uses = len(loaded['pin'])
uses_5v = False
uses_3v = False
uses = 0
for pin in loaded['pin']:
if pin.startswith('bcm'):
pin = pin[3:]
for idx in pins:
compare_pin = pins[idx]
#print(compare_pin)
if 'scheme' in compare_pin:
if 'bcm' in compare_pin['scheme']:
if compare_pin['scheme']['bcm'] == int(pin):
print("Mapping BCM{} to {}".format(pin, str(idx)))
pin = str(idx)
break
if pin in pins:
actual_pin = pins[pin]
if actual_pin['type'] in ['+3v3','+5v','GND']:
if actual_pin['type'] == '+3v3':
uses_3v = True
if actual_pin['type'] == '+5v':
uses_5v = True
else:
uses += 1
2015-03-22 01:27:02 +08:00
details.append('* Uses {} GPIO pins'.format(uses))
if '3' in loaded['pin'] and '5' in loaded['pin']:
pin_3 = loaded['pin']['3']
pin_5 = loaded['pin']['5']
if 'mode' in pin_3 and 'mode' in pin_5:
if pin_3['mode'] == 'i2c' and pin_5['mode'] == 'i2c':
details.append('* Uses I2C')
2015-03-22 01:27:02 +08:00
if 'url' in loaded:
details.append('* [More Information]({url})'.format(url=loaded['url']))
if 'github' in loaded:
details.append('* [GitHub Repository]({url})'.format(url=loaded['github']))
if 'buy' in loaded:
details.append('* [Buy Now]({url})'.format(url=loaded['buy']))
2015-03-22 01:27:02 +08:00
loaded['long_description'] = '{}\n{}'.format(loaded['long_description'],markdown.markdown('\n'.join(details)))
if not 'page_url' in loaded:
loaded['page_url'] = slugify(loaded['name'])
loaded['rendered_html'] = render_overlay_page(loaded)
pages[loaded['page_url']] = loaded
2015-03-22 01:27:02 +08:00
navs[loaded['page_url']] = render_nav(loaded['page_url'], overlay=loaded)
select_overlays.append((loaded['page_url'], loaded['name']))
2015-03-22 01:27:02 +08:00
return loaded
2015-02-25 01:28:00 +08:00
2015-02-25 06:07:11 +08:00
def load_md(filename):
2015-02-25 01:28:00 +08:00
try:
2015-02-25 06:07:11 +08:00
html = markdown.markdown(open(filename).read(), extensions=['fenced_code'])
return html
#return markdown.markdown(open(filename).read(), extensions=[gfm.HiddenHiliteExtension([]),'fenced_code'])
2015-02-25 01:28:00 +08:00
except IOError:
2015-03-22 05:11:54 +08:00
return ''
2015-02-25 01:28:00 +08:00
def render_pin_text(pin_num, pin_url, pin_name, pin_functions, pin_subtext):
return '<article class="{pin_url}"><h1>{pin_name}</h1>{pin_functions}{pin_subtext}{pin_text}</article>'.format(
pin_url=pin_url,
pin_name=pin_name,
pin_functions=pin_functions,
pin_subtext=pin_subtext,
2015-03-26 07:26:46 +08:00
pin_text=load_md('src/{}/description/pins/pin-{}.md'.format(lang,pin_num)))
2015-02-25 06:07:11 +08:00
2015-02-25 01:28:00 +08:00
def render_overlay_page(overlay):
if overlay == None:
return ''
2015-02-25 06:07:11 +08:00
return '<article class="page_{}">{}</article>'.format(slugify(overlay['name']),overlay['long_description'])
2015-02-25 01:28:00 +08:00
2015-02-26 01:29:06 +08:00
#pages += map(render_overlay_page,overlays)
2015-02-25 06:07:11 +08:00
2015-02-24 17:59:29 +08:00
def render_alternate(handle, name):
handle = slugify(handle.lower())
return '<span class="alternate legend_{}">{}</span>'.format(handle,name)
2015-03-22 01:27:02 +08:00
def render_pin_page(pin_num):
2015-02-24 17:59:29 +08:00
pin = pins[str(pin_num)]
pin_url = pin['name']
2015-02-25 06:07:11 +08:00
pin_text_name = pin['name']
pin_subtext = []
2015-02-24 17:59:29 +08:00
2015-02-25 06:07:11 +08:00
pin_subtext.append('Physical pin {}'.format(pin_num))
2015-02-24 17:59:29 +08:00
if 'scheme' in pin:
if 'bcm' in pin['scheme']:
bcm = pin['scheme']['bcm']
pin_url = 'gpio{}'.format(bcm)
#pin_subname_text = ''
#pin_text_name = 'BCM {} {}'.format(bcm, pin_subname_text)
pin_text_name = 'BCM {}'.format(bcm)
2015-02-24 17:59:29 +08:00
if pin['name'] != '':
2015-02-25 06:07:11 +08:00
pin_subname_text = '({})'.format(pin['name'])
pin_subtext.append('BCM pin {}'.format(bcm))
2015-02-24 17:59:29 +08:00
if 'wiringpi' in pin['scheme']:
wiringpi = pin['scheme']['wiringpi']
2015-02-25 06:07:11 +08:00
pin_subtext.append('Wiring Pi pin {}'.format(wiringpi))
if 'bcmAlt' in pin['scheme']:
bcmAlt = pin['scheme']['bcmAlt']
pin_subtext.append('BCM pin {} on Rev 1 ( very early ) Pi'.format(bcmAlt))
if 'description' in pin:
pin_text_name = '{} ({})'.format(pin_text_name, pin['description'])
fn_headings = []
fn_functions = []
pin_functions = ''
if 'functions' in pin:
for x in range(6):
fn_headings.append( 'Alt' + str(x) )
function = ''
if 'alt' + str(x) in pin['functions']:
function = pin['functions']['alt' + str(x)]
fn_functions.append( function )
pin_functions = '''<table class="pin-functions">
<thead>
<tr>
<th>{headings}</th>
</tr>
</thead>
<tbody>
<tr>
<td>{functions}</td>
</tr>
</tbody>
</table>'''.format(headings='</th><th>'.join(fn_headings), functions='</td><td>'.join(fn_functions))
2015-02-24 17:59:29 +08:00
2015-02-25 06:07:11 +08:00
pin_url = slugify('pin{}_{}'.format(pin_num,pin_url))
pin_text = render_pin_text(
pin_num,
pin_url,
pin_text_name,
pin_functions,
'<ul><li>{}</li></ul>'.format('</li><li>'.join(pin_subtext))
)
2015-03-22 01:27:02 +08:00
#if pin_text != None:
return (pin_url, pin_text, pin_text_name) #pages[pin_url] = pin_text
2015-03-22 01:27:02 +08:00
def render_pin(pin_num, selected_url, overlay=None):
pin = pins[str(pin_num)]
pin_type = list([x.strip() for x in pin['type'].lower().split('/')])
pin_url = pin['name']
pin_name = pin['name']
pin_used = False
pin_link_title = []
bcm_pin = None
if 'scheme' in pin:
if 'bcm' in pin['scheme']:
bcm_pin = 'bcm' + str(pin['scheme']['bcm'])
2015-03-22 01:27:02 +08:00
if overlay != None and ( str(pin_num) in overlay['pin'] or bcm_pin in overlay['pin']):
if str(pin_num) in overlay['pin']:
overlay_pin = overlay['pin'][str(pin_num)]
else:
overlay_pin = overlay['pin'][bcm_pin]
2015-03-22 01:27:02 +08:00
pin_used = True
#print(overlay)
if 'name' in overlay_pin:
pin_name = overlay_pin['name']
if 'description' in overlay_pin:
pin_link_title.append(overlay_pin['description'])
2015-03-22 01:27:02 +08:00
#alternates = []
#for overlay in overlays:
# if overlay != None:
# if str(pin_num) in overlay['pin']:
# alternates.append(render_alternate(overlay['name'],overlay['pin'][str(pin_num)]['name']))
if 'scheme' in pin:
if 'bcm' in pin['scheme']:
bcm = pin['scheme']['bcm']
pin_subname = ''
#pin_subname_text = ''
#if pin_url == '':
pin_url = 'gpio{}'.format(bcm)
if pin_name != '': #pin['name'] != '':
pin_subname = '<small>({})</small>'.format(pin_name) #pin['name'])
# pin_subname_text = '({})'.format(pin['name'])
pin_name = 'BCM {} {}'.format(bcm, pin_subname)
# pin_text_name = 'BCM {} {}'.format(bcm, pin_subname_text)
if 'wiringpi' in pin['scheme']:
wiringpi = pin['scheme']['wiringpi']
pin_link_title.append('Wiring Pi pin {}'.format(wiringpi))
2015-03-22 01:27:02 +08:00
# alternates.append(render_alternate('wiringpi','Wiring Pi pin {}'.format(wiringpi)))
#print(pin_type)
2015-03-22 05:11:54 +08:00
pin_url = base_url + slugify('pin{}_{}'.format(pin_num,pin_url))
2015-03-22 01:27:02 +08:00
#print(selected_url)
selected = ''
2015-03-22 05:11:54 +08:00
if base_url + selected_url == pin_url:
2015-03-22 01:27:02 +08:00
selected = ' active'
if pin_used:
selected += ' overlay-pin'
2015-02-25 06:07:11 +08:00
return '<li class="pin{pin_num} {pin_type}{pin_selected}"><a href="{pin_url}" title="{pin_title}"><span class="default"><span class="phys">{pin_num}</span> {pin_name}</span><span class="pin"></span></a></li>\n'.format(
pin_num = pin_num,
pin_type = ' '.join(map(cssify,pin_type)),
pin_selected = selected,
pin_url = pin_url,
pin_title = ', '.join(pin_link_title),
pin_name = pin_name
2015-02-24 17:59:29 +08:00
)
2015-03-22 01:27:02 +08:00
def render_nav(url, overlay=None):
html_odd = ''
html_even = ''
2015-02-26 01:29:06 +08:00
for odd in range(1,len(pins),2):
2015-03-22 01:27:02 +08:00
html_odd += render_pin(odd, url,overlay)
html_even += render_pin(odd+1,url,overlay)
2015-02-25 01:28:00 +08:00
2015-02-26 01:29:06 +08:00
return '''<ul class="bottom">
2015-02-25 01:28:00 +08:00
{}</ul>
<ul class="top">
{}</ul>'''.format(html_odd, html_even)
2015-02-24 17:59:29 +08:00
2015-02-26 01:29:06 +08:00
2015-03-22 01:27:02 +08:00
2015-03-26 07:26:46 +08:00
db = json.load(open('src/{}/pi-pinout.json'.format(lang)))
2015-03-22 01:27:02 +08:00
pins = db['pins']
overlays = map(load_overlay,overlays)
for url, name in select_overlays:
overlays_html += '<option value="{}">{}</option>'.format(url, name)
2015-03-22 02:35:46 +08:00
2015-03-22 01:27:02 +08:00
pages['pinout'] = {}
pages['pinout']['rendered_html'] = render_overlay_page({'name':'Index','long_description':load_md('description/index.md')})
2015-03-22 05:11:54 +08:00
navs['pinout'] = render_nav('pinout')
2015-03-22 01:27:02 +08:00
print('Rendering pin pages...')
for pin in range(1,len(pins)+1):
(pin_url, pin_html, pin_title) = render_pin_page(pin)
2015-03-22 01:27:02 +08:00
pin_nav = render_nav(pin_url)
pin_html = template.replace('{{nav}}',pin_nav).replace('{{content}}',pin_html)
pin_html = pin_html.replace('{{resource_url}}',resource_url)
pin_html = pin_html.replace('{{overlays}}',overlays_html).replace('{{v}}',str(int(time.time())))
pin_html = pin_html.replace('{{description}}',default_desc)
pin_html = pin_html.replace('{{title}}',pin_title + title_suffix)
2015-03-22 01:27:02 +08:00
print('Outputting page {}'.format(pin_url))
2015-03-26 07:26:46 +08:00
with open(os.path.join('output',lang,'pinout','{}.html'.format(pin_url)),'w') as f:
2015-03-22 01:27:02 +08:00
f.write(pin_html)
#nav = render_nav()
print('Rendering overlay and index pages...')
for url in pages:
content = pages[url]['rendered_html']
2015-03-22 01:27:02 +08:00
nav = navs[url]
if not 'description' in pages[url]:
pages[url]['description'] = default_desc
if 'name' in pages[url]:
pages[url]['name'] = pages[url]['name'] + title_suffix
else:
pages[url]['name'] = default_title
2015-03-22 01:27:02 +08:00
print('Outputting page {}'.format(url))
html = template.replace('{{nav}}',nav).replace('{{content}}',content)
html = html.replace('{{resource_url}}',resource_url).replace('{{overlays}}',overlays_html)
html = html.replace('{{v}}',str(int(time.time())))
html = html.replace('{{description}}',pages[url]['description'])
html = html.replace('{{title}}',pages[url]['name'])
2015-03-22 05:11:54 +08:00
if url != 'pinout':
url = os.path.join('pinout',url)
2015-03-26 07:26:46 +08:00
with open(os.path.join('output',lang,'{}.html'.format(url)),'w') as f:
2015-02-26 01:29:06 +08:00
f.write(html)