mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 14:36:36 +08:00
Using __doc__ to add Python signatures to the docs.
This commit is contained in:
parent
66e09bc9a4
commit
912de363f4
@ -205,7 +205,7 @@ if(BUILD_DOCS AND DOXYGEN_FOUND)
|
||||
list(APPEND js_tutorials_assets_deps "${f}" "${opencv_tutorial_html_dir}/${fname}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(doxygen
|
||||
add_custom_target(doxygen_cpp
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
|
||||
DEPENDS ${doxyfile} ${rootfile} ${bibfile} ${deps} ${js_tutorials_assets_deps}
|
||||
)
|
||||
@ -214,6 +214,28 @@ if(BUILD_DOCS AND DOXYGEN_FOUND)
|
||||
COMPONENT "docs" OPTIONAL
|
||||
)
|
||||
|
||||
if(BUILD_opencv_python2)
|
||||
add_custom_target(doxygen_python
|
||||
COMMAND ${PYTHON2_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tools/python_signatures.py" "${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/"
|
||||
DEPENDS doxygen_cpp opencv_python2
|
||||
)
|
||||
add_custom_target(doxygen
|
||||
DEPENDS doxygen_cpp doxygen_python
|
||||
)
|
||||
elseif(BUILD_opencv_python3)
|
||||
add_custom_target(doxygen_python
|
||||
COMMAND ${PYTHON3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tools/python_signatures.py" "${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/"
|
||||
DEPENDS doxygen_cpp opencv_python3
|
||||
)
|
||||
add_custom_target(doxygen
|
||||
DEPENDS doxygen_cpp doxygen_python
|
||||
)
|
||||
else()
|
||||
add_custom_target(doxygen
|
||||
DEPENDS doxygen_cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# Alias to build/install docs only
|
||||
add_custom_target(install_docs
|
||||
DEPENDS doxygen
|
||||
|
209
doc/tools/html_functions.py
Normal file
209
doc/tools/html_functions.py
Normal file
@ -0,0 +1,209 @@
|
||||
import logging
|
||||
import os
|
||||
import codecs
|
||||
import cv2
|
||||
|
||||
|
||||
try:
|
||||
from bs4 import BeautifulSoup
|
||||
except ImportError:
|
||||
raise ImportError('Error: '
|
||||
'Install BeautifulSoup (bs4) for adding'
|
||||
' Python & Java signatures documentation')
|
||||
|
||||
|
||||
def is_not_module_link(tmp_link):
|
||||
""" Checks if a link belongs to a c++ method """
|
||||
if tmp_link is None:
|
||||
return True
|
||||
if "group" not in tmp_link:
|
||||
return True
|
||||
if "#" in tmp_link:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_links_list(tmp_soup, filter_links):
|
||||
""" Get a list of links from a soup """
|
||||
tmp_href_list = []
|
||||
for tmp_link in tmp_soup.findAll('a'):
|
||||
tmp_href = tmp_link.get('href')
|
||||
if filter_links:
|
||||
if is_not_module_link(tmp_href):
|
||||
continue
|
||||
tmp_href_list.append(tmp_href)
|
||||
return tmp_href_list
|
||||
|
||||
|
||||
def load_html_file(file_dir):
|
||||
""" Uses BeautifulSoup to load an html """
|
||||
with open(file_dir) as fp:
|
||||
tmp_soup = BeautifulSoup(fp, 'html.parser')
|
||||
return tmp_soup
|
||||
|
||||
|
||||
def add_item(tmp_soup, new_row, is_parameter, text):
|
||||
""" Adds a new html tag for the table with the signature """
|
||||
new_item = tmp_soup.new_tag('td')
|
||||
if is_parameter:
|
||||
new_item = tmp_soup.new_tag('td', **{'class': 'paramname'})
|
||||
new_item.append(text)
|
||||
new_row.append(new_item)
|
||||
return new_row
|
||||
|
||||
|
||||
def get_text_between_substrings(sig, begin_char, end_char):
|
||||
return sig.partition(begin_char)[-1].rpartition(end_char)[0]
|
||||
|
||||
|
||||
def add_signature_to_table(tmp_soup, new_row, signature, function_name, language, ident):
|
||||
""" Add a signature to an html table"""
|
||||
if ident:
|
||||
new_item = tmp_soup.new_tag('td', style="padding-left: 0.5cm;")
|
||||
else:
|
||||
new_item = tmp_soup.new_tag('td')
|
||||
|
||||
if "-> None" in signature:
|
||||
pass
|
||||
elif "->" in signature:
|
||||
new_item.append(signature.split("->", 1)[1] + ' =')
|
||||
new_row.append(new_item)
|
||||
|
||||
if "Python" in language:
|
||||
function_name = "cv2." + function_name
|
||||
elif "Java" in language:
|
||||
# get word before function_name (= output)
|
||||
str_before_bracket = signature.split('(', 1)[0]
|
||||
list_of_words = str_before_bracket.split()
|
||||
output = list_of_words[len(list_of_words) - 2]
|
||||
new_item.append(output + " ")
|
||||
new_row.append(new_item)
|
||||
|
||||
new_row = add_item(tmp_soup, new_row, False, function_name + '(')
|
||||
new_row = add_item(tmp_soup, new_row, True, get_text_between_substrings(signature, "(", ")"))
|
||||
new_row = add_item(tmp_soup, new_row, False, ')')
|
||||
return new_row
|
||||
|
||||
|
||||
def new_line(tmp_soup, tmp_table, new_row):
|
||||
""" Adds a new line to the html table """
|
||||
tmp_table.append(new_row)
|
||||
new_row = tmp_soup.new_tag('tr')
|
||||
return new_row
|
||||
|
||||
|
||||
def add_bolded(tmp_soup, new_row, text):
|
||||
""" Adds bolded text to the table """
|
||||
new_item = tmp_soup.new_tag('th', style="text-align:left")
|
||||
new_item.append(text)
|
||||
new_row.append(new_item)
|
||||
return new_row
|
||||
|
||||
|
||||
def append_table_to(cpp_table, tmp_soup, language, signature, function_name):
|
||||
""" Insert the new Python / Java table after the current html c++ table """
|
||||
if signature != "":
|
||||
tmp_table = tmp_soup.new_tag('table')
|
||||
new_row = tmp_soup.new_tag('tr')
|
||||
new_row = add_bolded(tmp_soup, new_row, language)
|
||||
ident = False
|
||||
|
||||
if len(signature) > 120:
|
||||
new_row = new_line(tmp_soup, tmp_table, new_row)
|
||||
ident = True
|
||||
|
||||
if " or " in signature:
|
||||
ident = True
|
||||
for tmp_sig in signature.split(" or "):
|
||||
new_row = new_line(tmp_soup, tmp_table, new_row)
|
||||
new_row = add_signature_to_table(tmp_soup, new_row, tmp_sig, function_name, language, ident)
|
||||
new_row = new_line(tmp_soup, tmp_table, new_row)
|
||||
else:
|
||||
new_row = add_signature_to_table(tmp_soup, new_row, signature, function_name, language, ident)
|
||||
tmp_table.append(new_row)
|
||||
|
||||
cpp_table.insert_after(tmp_table)
|
||||
return cpp_table
|
||||
|
||||
|
||||
def add_signatures(tmp_soup, tmp_dir, ADD_JAVA, ADD_PYTHON, module_name):
|
||||
""" Add signatures to the current soup and rewrite the html file"""
|
||||
logging.debug(tmp_dir)
|
||||
sign_counter = 0
|
||||
python_sign_counter = 0
|
||||
java_sign_counter = 0
|
||||
|
||||
if ADD_JAVA:
|
||||
functions_file = "java_doc_txts/" + module_name + "/functions.txt"
|
||||
if os.path.exists(functions_file):
|
||||
with open(functions_file, 'r') as f:
|
||||
java_signatures = f.read().split("\n")
|
||||
else:
|
||||
ADD_JAVA = False # This C++ module (module_name) may not exist in Java
|
||||
|
||||
# the HTML tag & class being used to find functions
|
||||
for function in tmp_soup.findAll("h2", {"class": "memtitle"}):
|
||||
function_name = function.getText()
|
||||
if os.name == 'nt': # if Windows
|
||||
function_name = function_name.encode("ascii","ignore").decode()
|
||||
|
||||
# all functions have () in it's name
|
||||
if "()" not in function_name:
|
||||
continue
|
||||
|
||||
if "[" in function_name:
|
||||
if "[1/" in function_name:
|
||||
function_name = function_name.replace(' ', '')[:-7]
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
function_name = function_name.replace(' ', '')[:-2]
|
||||
sign_counter += 1
|
||||
|
||||
# if not Windows computer
|
||||
if os.name != 'nt':
|
||||
function_name = function_name.replace(' ', '')[2:]
|
||||
|
||||
cpp_table = function.findNext('table')
|
||||
|
||||
if ADD_PYTHON:
|
||||
try:
|
||||
print(function_name)
|
||||
method = getattr(cv2, str(function_name))
|
||||
description = str(method.__doc__).split("\n")
|
||||
signature = ""
|
||||
is_first_sig = True
|
||||
for line in description:
|
||||
if line.startswith(".") or line == "":
|
||||
continue
|
||||
else:
|
||||
if is_first_sig:
|
||||
signature += line
|
||||
is_first_sig = False
|
||||
else:
|
||||
signature += " or " + line
|
||||
|
||||
cpp_table = append_table_to(cpp_table, tmp_soup, "Python:", signature, function_name)
|
||||
python_sign_counter += 1
|
||||
except AttributeError:
|
||||
continue
|
||||
|
||||
if ADD_JAVA:
|
||||
for signature in java_signatures:
|
||||
if function_name in signature:
|
||||
append_table_to(cpp_table, tmp_soup, "Java:", signature, function_name)
|
||||
java_sign_counter += 1
|
||||
break
|
||||
|
||||
tmp_str = str(tmp_soup)
|
||||
if os.name == 'nt': # if Windows
|
||||
with open(tmp_dir, "wb") as tmp_file:
|
||||
tmp_file.write(tmp_str.encode("ascii","ignore"))
|
||||
else:
|
||||
with open(tmp_dir, "w") as tmp_file:
|
||||
tmp_file.write(tmp_str)
|
||||
|
||||
logging.debug("Added [" + str(python_sign_counter) + \
|
||||
"/" + str(sign_counter) + "] Python signatures")
|
||||
logging.debug("Added [" + str(java_sign_counter) + \
|
||||
"/" + str(sign_counter) + "] Java signatures")
|
34
doc/tools/python_signatures.py
Normal file
34
doc/tools/python_signatures.py
Normal file
@ -0,0 +1,34 @@
|
||||
"""
|
||||
This code adds Python signatures to the docs.
|
||||
|
||||
TODO:
|
||||
* clarify when there are several C++ signatures corresponding to a single Python function.
|
||||
i.e: calcHist():
|
||||
http://docs.opencv.org/3.2.0/d6/dc7/group__imgproc__hist.html#ga4b2b5fd75503ff9e6844cc4dcdaed35d
|
||||
* clarify special case:
|
||||
http://docs.opencv.org/3.2.0/db/de0/group__core__utils.html#ga4910d7f86336cd4eff9dd05575667e41
|
||||
"""
|
||||
import re
|
||||
import sys
|
||||
import html_functions
|
||||
|
||||
ADD_JAVA = False
|
||||
ADD_PYTHON = True
|
||||
ROOT_DIR = sys.argv[1]
|
||||
|
||||
soup = html_functions.load_html_file(ROOT_DIR + "index.html")
|
||||
href_list = html_functions.get_links_list(soup, True)
|
||||
|
||||
for link in href_list:
|
||||
# add python signatures to the module
|
||||
soup = html_functions.load_html_file(ROOT_DIR + link)
|
||||
sub_href_list = html_functions.get_links_list(soup, True)
|
||||
module_name = html_functions.get_text_between_substrings(link, "group__", ".html")
|
||||
html_functions.add_signatures(soup, ROOT_DIR + link, ADD_JAVA, ADD_PYTHON, module_name)
|
||||
|
||||
# add python signatures to the sub-modules
|
||||
link = re.sub(r"group__.+html", "", link)
|
||||
for sub_link in sub_href_list:
|
||||
tmp_dir = ROOT_DIR + link + sub_link
|
||||
soup = html_functions.load_html_file(tmp_dir)
|
||||
html_functions.add_signatures(soup, tmp_dir, ADD_JAVA, ADD_PYTHON, module_name)
|
Loading…
Reference in New Issue
Block a user