|
|
@ -1,7 +1,10 @@ |
|
|
|
from __future__ import print_function |
|
|
|
from __future__ import print_function |
|
|
|
|
|
|
|
import sys |
|
|
|
|
|
|
|
|
|
|
|
import logging |
|
|
|
import logging |
|
|
|
import os |
|
|
|
import os |
|
|
|
from pprint import pprint |
|
|
|
from pprint import pprint |
|
|
|
|
|
|
|
import traceback |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
try: |
|
|
|
import bs4 |
|
|
|
import bs4 |
|
|
@ -13,195 +16,110 @@ except ImportError: |
|
|
|
|
|
|
|
|
|
|
|
def load_html_file(file_dir): |
|
|
|
def load_html_file(file_dir): |
|
|
|
""" Uses BeautifulSoup to load an html """ |
|
|
|
""" Uses BeautifulSoup to load an html """ |
|
|
|
with open(file_dir) as fp: |
|
|
|
with open(file_dir, 'rb') as fp: |
|
|
|
soup = BeautifulSoup(fp, 'html.parser') |
|
|
|
soup = BeautifulSoup(fp, 'html.parser') |
|
|
|
return soup |
|
|
|
return soup |
|
|
|
|
|
|
|
|
|
|
|
def add_item(soup, new_row, is_parameter, text): |
|
|
|
def update_html(file, soup): |
|
|
|
""" Adds a new html tag for the table with the signature """ |
|
|
|
s = str(soup) |
|
|
|
new_item = soup.new_tag('td') |
|
|
|
if os.name == 'nt' or sys.version_info[0] == 3: # if Windows |
|
|
|
if is_parameter: |
|
|
|
s = s.encode('utf-8', 'ignore') |
|
|
|
new_item = soup.new_tag('td', **{'class': 'paramname'}) |
|
|
|
with open(file, 'wb') as f: |
|
|
|
new_item.append(text) |
|
|
|
f.write(s) |
|
|
|
new_row.append(new_item) |
|
|
|
|
|
|
|
return new_row, soup |
|
|
|
|
|
|
|
|
|
|
|
def insert_python_signatures(python_signatures, symbols_dict, filepath): |
|
|
|
def add_signature_to_table(soup, tmp_row, signature, language, type): |
|
|
|
soup = load_html_file(filepath) |
|
|
|
""" Add a signature to an html table""" |
|
|
|
entries = soup.find_all(lambda tag: tag.name == "a" and tag.has_attr('id')) |
|
|
|
new_item = soup.new_tag('td', style="padding-left: 0.5cm;") |
|
|
|
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) |
|
|
|
|
|
|
|
|
|
|
|
if str(signature.get('ret', None)) != "None": |
|
|
|
|
|
|
|
new_item.append(signature.get('ret') + ' =') |
|
|
|
|
|
|
|
tmp_row.append(new_item) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tmp_name = signature.get('name', None) |
|
|
|
def insert_python_fn_signature(soup, table, variants, symbol): |
|
|
|
if type is not "method": |
|
|
|
description = create_python_fn_description(soup, variants) |
|
|
|
tmp_name = "cv2." + tmp_name |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
tmp_name = "obj." + tmp_name |
|
|
|
|
|
|
|
tmp_row, soup = add_item(soup, tmp_row, False, tmp_name + '(') |
|
|
|
|
|
|
|
tmp_row, soup = add_item(soup, tmp_row, True, signature['arg']) |
|
|
|
|
|
|
|
tmp_row, soup = add_item(soup, tmp_row, False, ')') |
|
|
|
|
|
|
|
return tmp_row, soup |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def new_line(soup, tmp_table, new_row): |
|
|
|
|
|
|
|
""" Adds a new line to the html table """ |
|
|
|
|
|
|
|
tmp_table.append(new_row) |
|
|
|
|
|
|
|
new_row = soup.new_tag('tr') |
|
|
|
|
|
|
|
return new_row, soup |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def add_bolded(soup, new_row, text): |
|
|
|
|
|
|
|
""" Adds bolded text to the table """ |
|
|
|
|
|
|
|
new_item = soup.new_tag('th', style="text-align:left") |
|
|
|
|
|
|
|
new_item.append(text) |
|
|
|
|
|
|
|
new_row.append(new_item) |
|
|
|
|
|
|
|
return new_row, soup |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_description(soup, language, signatures, type): |
|
|
|
|
|
|
|
""" Insert the new Python / Java table after the current html c++ table """ |
|
|
|
|
|
|
|
assert signatures |
|
|
|
|
|
|
|
tmp_table = soup.new_tag('table') |
|
|
|
|
|
|
|
new_row = soup.new_tag('tr') |
|
|
|
|
|
|
|
new_row, soup = add_bolded(soup, new_row, language) |
|
|
|
|
|
|
|
new_row, soup = new_line(soup, tmp_table, new_row) |
|
|
|
|
|
|
|
for s in signatures: |
|
|
|
|
|
|
|
new_row, soup = new_line(soup, tmp_table, new_row) |
|
|
|
|
|
|
|
new_row, soup = add_signature_to_table(soup, new_row, s, language, type) |
|
|
|
|
|
|
|
new_row, soup = new_line(soup, tmp_table, new_row) |
|
|
|
|
|
|
|
return tmp_table, soup |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_anchor_list(anchor, soup): |
|
|
|
|
|
|
|
a_list = [] |
|
|
|
|
|
|
|
# go through all the links |
|
|
|
|
|
|
|
for a in soup.find_all('a', href=True): |
|
|
|
|
|
|
|
# find links with the same anchor |
|
|
|
|
|
|
|
last_part_of_link = a['href'].rsplit('#', 1)[-1] |
|
|
|
|
|
|
|
if last_part_of_link == anchor: |
|
|
|
|
|
|
|
a_list.append(a) |
|
|
|
|
|
|
|
return a_list |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def is_static_method(element): |
|
|
|
|
|
|
|
if element.name == "table": |
|
|
|
|
|
|
|
tmp_element = element.find('td', {'class': 'memname'}) |
|
|
|
|
|
|
|
if tmp_element is not None: |
|
|
|
|
|
|
|
if 'static' in tmp_element.text: |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
if element['class'][0] == 'memItemRight': |
|
|
|
|
|
|
|
if "static" in element.previousSibling.text: |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def append_python_signatures_to_table(soup, signatures, table, type): |
|
|
|
|
|
|
|
if type == "method": |
|
|
|
|
|
|
|
if is_static_method(table): |
|
|
|
|
|
|
|
type = "static" + type |
|
|
|
|
|
|
|
description, soup = create_description(soup, "Python:", signatures, type) |
|
|
|
|
|
|
|
description['class'] = 'python_language' |
|
|
|
description['class'] = 'python_language' |
|
|
|
soup = insert_or_replace(soup, table, description, "table", "python_language") |
|
|
|
soup = insert_or_replace(table, description, 'table', 'python_language') |
|
|
|
return soup |
|
|
|
return soup |
|
|
|
|
|
|
|
|
|
|
|
def get_heading_text(a): |
|
|
|
|
|
|
|
str = "" |
|
|
|
|
|
|
|
element = a.parent |
|
|
|
|
|
|
|
if element is not None: |
|
|
|
|
|
|
|
childs = element.find_all('a') |
|
|
|
|
|
|
|
# the anchor should not be an argument of a function / method |
|
|
|
|
|
|
|
if childs.index(a) is not 0: |
|
|
|
|
|
|
|
return str |
|
|
|
|
|
|
|
element = element.parent |
|
|
|
|
|
|
|
if element is not None: |
|
|
|
|
|
|
|
if element.has_attr('class'): |
|
|
|
|
|
|
|
tmp_class = element["class"][0] |
|
|
|
|
|
|
|
if "memitem:" in tmp_class and "python" not in tmp_class: |
|
|
|
|
|
|
|
str = element.parent.find("tr").text |
|
|
|
|
|
|
|
return str |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def insert_or_replace(soup, element, description, tag_name, tag_class): |
|
|
|
|
|
|
|
old = element.next_sibling |
|
|
|
|
|
|
|
if old is not None: |
|
|
|
|
|
|
|
if old.name != tag_name: |
|
|
|
|
|
|
|
old = None |
|
|
|
|
|
|
|
elif not tag_class in old.get('class', []): |
|
|
|
|
|
|
|
old = None |
|
|
|
|
|
|
|
# if already existed replace with the new |
|
|
|
|
|
|
|
if old is None: |
|
|
|
|
|
|
|
element.insert_after(description) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
old.replace_with(description) |
|
|
|
|
|
|
|
return soup |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def new_heading_td(soup, s, href, type): |
|
|
|
def create_python_fn_description(soup, variants): |
|
|
|
if href is None: |
|
|
|
language = 'Python:' |
|
|
|
attrs = {'class': 'memItemLeft', 'valign': 'top', 'align': 'right'} |
|
|
|
table = soup.new_tag('table') |
|
|
|
new_td = soup.new_tag('td', **attrs) |
|
|
|
heading_row = soup.new_tag('th') |
|
|
|
new_td.append(str(s.get('ret', None))) |
|
|
|
table.append( |
|
|
|
else: |
|
|
|
append(soup.new_tag('tr'), |
|
|
|
attrs = {'class': 'memItemRight', 'valign': 'bottom'} |
|
|
|
append(soup.new_tag('th', colspan=999, style="text-align:left"), language))) |
|
|
|
new_td = soup.new_tag('td', **attrs) |
|
|
|
for v in variants: |
|
|
|
|
|
|
|
#logging.debug(v) |
|
|
|
# make the function name linkable |
|
|
|
add_signature_to_table(soup, table, v, language, type) |
|
|
|
attrs_a = {'class': 'el', 'href': href} |
|
|
|
#print(table) |
|
|
|
new_a = soup.new_tag('a', **attrs_a) |
|
|
|
return table |
|
|
|
tmp_name = str(s.get('name', None)) |
|
|
|
|
|
|
|
if type is not "method": |
|
|
|
|
|
|
|
tmp_name = "cv2." + tmp_name |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
tmp_name = "obj." + tmp_name |
|
|
|
|
|
|
|
new_a.append(tmp_name) |
|
|
|
|
|
|
|
new_td.append(new_a) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
new_td.append("(" + s['arg'] +")") |
|
|
|
|
|
|
|
return soup, new_td |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def append_python_signatures_to_heading(soup, signatures, element, href, type): |
|
|
|
def add_signature_to_table(soup, table, signature, language, type): |
|
|
|
if type == "method": |
|
|
|
""" Add a signature to an html table""" |
|
|
|
if is_static_method(element): |
|
|
|
row = soup.new_tag('tr') |
|
|
|
type = "static" + type |
|
|
|
row.append(soup.new_tag('td', style='width: 20px;')) |
|
|
|
for s in signatures: |
|
|
|
|
|
|
|
attrs = {'class': 'memitem:python'} |
|
|
|
|
|
|
|
new_tr = soup.new_tag('tr', **attrs) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
soup, new_td_left = new_heading_td(soup, s, None, type) |
|
|
|
if 'ret' in signature: |
|
|
|
new_tr.append(new_td_left) |
|
|
|
row.append(append(soup.new_tag('td'), signature['ret'])) |
|
|
|
|
|
|
|
row.append(append(soup.new_tag('td'), '=')) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
row.append(soup.new_tag('td')) # return values |
|
|
|
|
|
|
|
row.append(soup.new_tag('td')) # '=' |
|
|
|
|
|
|
|
|
|
|
|
soup, new_td_right = new_heading_td(soup, s, href, type) |
|
|
|
row.append(append(soup.new_tag('td'), signature['name'] + '(')) |
|
|
|
new_tr.append(new_td_right) |
|
|
|
row.append(append(soup.new_tag('td', **{'class': 'paramname'}), signature['arg'])) |
|
|
|
|
|
|
|
row.append(append(soup.new_tag('td'), ')')) |
|
|
|
|
|
|
|
table.append(row) |
|
|
|
|
|
|
|
|
|
|
|
soup = insert_or_replace(soup, element, new_tr, "tr", "memitem:python") |
|
|
|
|
|
|
|
return soup |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def append_python_signature(function_variants, anchor_list, soup): |
|
|
|
def append(target, obj): |
|
|
|
type = anchor_list[0].type |
|
|
|
target.append(obj) |
|
|
|
if type == "method" or type == "fn": |
|
|
|
return target |
|
|
|
if len(anchor_list) == 1: |
|
|
|
|
|
|
|
tmp_anchor = anchor_list[0].anchor |
|
|
|
|
|
|
|
a_list = get_anchor_list(tmp_anchor, soup) |
|
|
|
|
|
|
|
for a in a_list: |
|
|
|
|
|
|
|
if a['href'] == "#" + tmp_anchor: |
|
|
|
|
|
|
|
tmp_element = a.parent |
|
|
|
|
|
|
|
# ignore the More... link <td class = mdescRight> |
|
|
|
|
|
|
|
if tmp_element is None or tmp_element['class'][0] == 'mdescRight': |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
# Function Documentation (tables) |
|
|
|
|
|
|
|
table = a.findNext('table') |
|
|
|
|
|
|
|
if table is not None: |
|
|
|
|
|
|
|
soup = append_python_signatures_to_table(soup, function_variants, table, type) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
str = get_heading_text(a) |
|
|
|
|
|
|
|
if "Functions" in str: |
|
|
|
|
|
|
|
soup = append_python_signatures_to_heading(soup, function_variants, a.parent, a['href'], type) |
|
|
|
|
|
|
|
return soup |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_html(file, soup): |
|
|
|
|
|
|
|
tmp_str = str(soup) |
|
|
|
def insert_or_replace(element_before, new_element, tag, tag_class): |
|
|
|
if os.name == 'nt': # if Windows |
|
|
|
old = element_before.find_next_sibling(tag, class_=tag_class) |
|
|
|
with open(file, "wb") as tmp_file: |
|
|
|
if old is None: |
|
|
|
tmp_file.write(tmp_str.encode("ascii","ignore")) |
|
|
|
element_before.insert_after(new_element) |
|
|
|
else: |
|
|
|
else: |
|
|
|
with open(file, "w") as tmp_file: |
|
|
|
old.replace_with(new_element) |
|
|
|
tmp_file.write(tmp_str) |
|
|
|
|
|
|
|