123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- from __future__ import print_function
- import sys
- import logging
- import os
- import re
- from pprint import pprint
- import traceback
- try:
- import bs4
- from bs4 import BeautifulSoup
- except ImportError:
- raise ImportError('Error: '
- 'Install BeautifulSoup (bs4) for adding'
- ' Python & Java signatures documentation')
- def load_html_file(file_dir):
- """ Uses BeautifulSoup to load an html """
- with open(file_dir, 'rb') as fp:
- data = fp.read()
- if os.name == 'nt' or sys.version_info[0] == 3:
- data = data.decode(encoding='utf-8', errors='strict')
- data = re.sub(r'(\>)([ ]+)', lambda match: match.group(1) + ('!space!' * len(match.group(2))), data)
- data = re.sub(r'([ ]+)(\<)', lambda match: ('!space!' * len(match.group(1))) + match.group(2), data)
- if os.name == 'nt' or sys.version_info[0] == 3:
- data = data.encode('utf-8', 'ignore')
- soup = BeautifulSoup(data, 'html.parser')
- return soup
- def update_html(file, soup):
- s = str(soup)
- s = s.replace('!space!', ' ')
- if os.name == 'nt' or sys.version_info[0] == 3:
- s = s.encode('utf-8', 'ignore')
- with open(file, 'wb') as f:
- f.write(s)
- def insert_python_signatures(python_signatures, symbols_dict, filepath):
- soup = load_html_file(filepath)
- entries = soup.find_all(lambda tag: tag.name == "a" and tag.has_attr('id'))
- for e in entries:
- anchor = e['id']
- if anchor in symbols_dict:
- s = symbols_dict[anchor]
- logging.info('Process: %r' % s)
- if s.type == 'fn' or s.type == 'method':
- process_fn(soup, e, python_signatures[s.cppname], s)
- elif s.type == 'const':
- process_const(soup, e, python_signatures[s.cppname], s)
- else:
- logging.error('unsupported type: %s' % s);
- update_html(filepath, soup)
- def process_fn(soup, anchor, python_signature, symbol):
- try:
- r = anchor.find_next_sibling(class_='memitem').find(class_='memproto').find('table')
- insert_python_fn_signature(soup, r, python_signature, symbol)
- except:
- logging.error("Can't process: %s" % symbol)
- traceback.print_exc()
- pprint(anchor)
- def process_const(soup, anchor, python_signature, symbol):
- try:
- #pprint(anchor.parent)
- description = append(soup.new_tag('div', **{'class' : ['python_language']}),
- 'Python: ' + python_signature[0]['name'])
- old = anchor.find_next_sibling('div', class_='python_language')
- if old is None:
- anchor.parent.append(description)
- else:
- old.replace_with(description)
- #pprint(anchor.parent)
- except:
- logging.error("Can't process: %s" % symbol)
- traceback.print_exc()
- pprint(anchor)
- def insert_python_fn_signature(soup, table, variants, symbol):
- description = create_python_fn_description(soup, variants)
- description['class'] = 'python_language'
- soup = insert_or_replace(table, description, 'table', 'python_language')
- return soup
- def create_python_fn_description(soup, variants):
- language = 'Python:'
- table = soup.new_tag('table')
- heading_row = soup.new_tag('th')
- table.append(
- append(soup.new_tag('tr'),
- append(soup.new_tag('th', colspan=999, style="text-align:left"), language)))
- for v in variants:
- #logging.debug(v)
- add_signature_to_table(soup, table, v, language, type)
- #print(table)
- return table
- def add_signature_to_table(soup, table, signature, language, type):
- """ Add a signature to an html table"""
- row = soup.new_tag('tr')
- row.append(soup.new_tag('td', style='width: 20px;'))
- row.append(append(soup.new_tag('td'), signature['name'] + '('))
- row.append(append(soup.new_tag('td', **{'class': 'paramname'}), signature['arg']))
- row.append(append(soup.new_tag('td'), ') -> '))
- row.append(append(soup.new_tag('td'), signature['ret']))
- table.append(row)
- def append(target, obj):
- target.append(obj)
- return target
- def insert_or_replace(element_before, new_element, tag, tag_class):
- old = element_before.find_next_sibling(tag, class_=tag_class)
- if old is None:
- element_before.insert_after(new_element)
- else:
- old.replace_with(new_element)
|