mirror of
https://github.com/opencv/opencv.git
synced 2025-06-12 20:42:53 +08:00
doc: update Python signatures generation
- drop dependency on 'import cv2', use pyopencv_signatures.json instead - try to make generator idempotent
This commit is contained in:
parent
912de363f4
commit
d715badbde
@ -205,10 +205,14 @@ if(BUILD_DOCS AND DOXYGEN_FOUND)
|
|||||||
list(APPEND js_tutorials_assets_deps "${f}" "${opencv_tutorial_html_dir}/${fname}")
|
list(APPEND js_tutorials_assets_deps "${f}" "${opencv_tutorial_html_dir}/${fname}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
set(doxygen_result "${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/index.html")
|
||||||
|
|
||||||
add_custom_target(doxygen_cpp
|
add_custom_target(doxygen_cpp
|
||||||
COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
|
COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
|
||||||
DEPENDS ${doxyfile} ${rootfile} ${bibfile} ${deps} ${js_tutorials_assets_deps}
|
DEPENDS ${doxyfile} ${rootfile} ${bibfile} ${deps} ${js_tutorials_assets_deps}
|
||||||
|
COMMENT "Generate Doxygen documentation"
|
||||||
)
|
)
|
||||||
|
|
||||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html
|
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doxygen/html
|
||||||
DESTINATION "${OPENCV_DOC_INSTALL_PATH}"
|
DESTINATION "${OPENCV_DOC_INSTALL_PATH}"
|
||||||
COMPONENT "docs" OPTIONAL
|
COMPONENT "docs" OPTIONAL
|
||||||
@ -216,16 +220,16 @@ if(BUILD_DOCS AND DOXYGEN_FOUND)
|
|||||||
|
|
||||||
if(BUILD_opencv_python2)
|
if(BUILD_opencv_python2)
|
||||||
add_custom_target(doxygen_python
|
add_custom_target(doxygen_python
|
||||||
COMMAND ${PYTHON2_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tools/python_signatures.py" "${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/"
|
COMMAND ${PYTHON2_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tools/python_signatures.py" "${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/" "${OPENCV_PYTHON2_SIGNATURES_FILE}"
|
||||||
DEPENDS doxygen_cpp opencv_python2
|
DEPENDS "${doxygen_result}" gen_opencv_python2
|
||||||
)
|
)
|
||||||
add_custom_target(doxygen
|
add_custom_target(doxygen
|
||||||
DEPENDS doxygen_cpp doxygen_python
|
DEPENDS doxygen_cpp doxygen_python
|
||||||
)
|
)
|
||||||
elseif(BUILD_opencv_python3)
|
elseif(BUILD_opencv_python3)
|
||||||
add_custom_target(doxygen_python
|
add_custom_target(doxygen_python
|
||||||
COMMAND ${PYTHON3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tools/python_signatures.py" "${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/"
|
COMMAND ${PYTHON3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/tools/python_signatures.py" "${CMAKE_CURRENT_BINARY_DIR}/doxygen/html/" "${OPENCV_PYTHON3_SIGNATURES_FILE}"
|
||||||
DEPENDS doxygen_cpp opencv_python3
|
DEPENDS "${doxygen_result}" gen_opencv_python3
|
||||||
)
|
)
|
||||||
add_custom_target(doxygen
|
add_custom_target(doxygen
|
||||||
DEPENDS doxygen_cpp doxygen_python
|
DEPENDS doxygen_cpp doxygen_python
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
from __future__ import print_function
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import codecs
|
import codecs
|
||||||
import cv2
|
from pprint import pprint
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
import bs4
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise ImportError('Error: '
|
raise ImportError('Error: '
|
||||||
@ -63,14 +64,12 @@ def add_signature_to_table(tmp_soup, new_row, signature, function_name, language
|
|||||||
else:
|
else:
|
||||||
new_item = tmp_soup.new_tag('td')
|
new_item = tmp_soup.new_tag('td')
|
||||||
|
|
||||||
if "-> None" in signature:
|
if str(signature.get('ret', None)) != "None":
|
||||||
pass
|
new_item.append(signature.get('ret') + ' =')
|
||||||
elif "->" in signature:
|
|
||||||
new_item.append(signature.split("->", 1)[1] + ' =')
|
|
||||||
new_row.append(new_item)
|
new_row.append(new_item)
|
||||||
|
|
||||||
if "Python" in language:
|
if "Python" in language:
|
||||||
function_name = "cv2." + function_name
|
pass # function_name = "cv2." + function_name
|
||||||
elif "Java" in language:
|
elif "Java" in language:
|
||||||
# get word before function_name (= output)
|
# get word before function_name (= output)
|
||||||
str_before_bracket = signature.split('(', 1)[0]
|
str_before_bracket = signature.split('(', 1)[0]
|
||||||
@ -79,8 +78,8 @@ def add_signature_to_table(tmp_soup, new_row, signature, function_name, language
|
|||||||
new_item.append(output + " ")
|
new_item.append(output + " ")
|
||||||
new_row.append(new_item)
|
new_row.append(new_item)
|
||||||
|
|
||||||
new_row = add_item(tmp_soup, new_row, False, function_name + '(')
|
new_row = add_item(tmp_soup, new_row, False, signature.get('name', function_name) + '(')
|
||||||
new_row = add_item(tmp_soup, new_row, True, get_text_between_substrings(signature, "(", ")"))
|
new_row = add_item(tmp_soup, new_row, True, signature['arg'])
|
||||||
new_row = add_item(tmp_soup, new_row, False, ')')
|
new_row = add_item(tmp_soup, new_row, False, ')')
|
||||||
return new_row
|
return new_row
|
||||||
|
|
||||||
@ -100,98 +99,81 @@ def add_bolded(tmp_soup, new_row, text):
|
|||||||
return new_row
|
return new_row
|
||||||
|
|
||||||
|
|
||||||
def append_table_to(cpp_table, tmp_soup, language, signature, function_name):
|
def create_description(tmp_soup, language, signatures, function_name):
|
||||||
""" Insert the new Python / Java table after the current html c++ table """
|
""" Insert the new Python / Java table after the current html c++ table """
|
||||||
if signature != "":
|
assert signatures
|
||||||
tmp_table = tmp_soup.new_tag('table')
|
tmp_table = tmp_soup.new_tag('table')
|
||||||
new_row = tmp_soup.new_tag('tr')
|
new_row = tmp_soup.new_tag('tr')
|
||||||
new_row = add_bolded(tmp_soup, new_row, language)
|
new_row = add_bolded(tmp_soup, new_row, language)
|
||||||
ident = False
|
ident = False
|
||||||
|
|
||||||
if len(signature) > 120:
|
new_row = new_line(tmp_soup, tmp_table, new_row)
|
||||||
new_row = new_line(tmp_soup, tmp_table, new_row)
|
ident = True
|
||||||
ident = True
|
|
||||||
|
|
||||||
if " or " in signature:
|
for s in signatures:
|
||||||
ident = True
|
new_row = new_line(tmp_soup, tmp_table, new_row)
|
||||||
for tmp_sig in signature.split(" or "):
|
new_row = add_signature_to_table(tmp_soup, new_row, s, function_name, language, ident)
|
||||||
new_row = new_line(tmp_soup, tmp_table, new_row)
|
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 tmp_table
|
||||||
return cpp_table
|
|
||||||
|
|
||||||
|
|
||||||
def add_signatures(tmp_soup, tmp_dir, ADD_JAVA, ADD_PYTHON, module_name):
|
def add_signatures(tmp_soup, tmp_dir, module_name, config):
|
||||||
""" Add signatures to the current soup and rewrite the html file"""
|
""" Add signatures to the current soup and rewrite the html file"""
|
||||||
|
|
||||||
logging.debug(tmp_dir)
|
logging.debug(tmp_dir)
|
||||||
sign_counter = 0
|
sign_counter = 0
|
||||||
python_sign_counter = 0
|
python_sign_counter = 0
|
||||||
java_sign_counter = 0
|
java_sign_counter = 0
|
||||||
|
|
||||||
if ADD_JAVA:
|
if config.ADD_JAVA:
|
||||||
functions_file = "java_doc_txts/" + module_name + "/functions.txt"
|
functions_file = "java_doc_txts/" + module_name + "/functions.txt"
|
||||||
if os.path.exists(functions_file):
|
if os.path.exists(functions_file):
|
||||||
with open(functions_file, 'r') as f:
|
with open(functions_file, 'r') as f:
|
||||||
java_signatures = f.read().split("\n")
|
java_signatures = f.read().split("\n")
|
||||||
else:
|
else:
|
||||||
ADD_JAVA = False # This C++ module (module_name) may not exist in Java
|
config.ADD_JAVA = False # This C++ module (module_name) may not exist in Java
|
||||||
|
|
||||||
# the HTML tag & class being used to find functions
|
# the HTML tag & class being used to find functions
|
||||||
for function in tmp_soup.findAll("h2", {"class": "memtitle"}):
|
for function in tmp_soup.findAll("h2", {"class": "memtitle"}):
|
||||||
function_name = function.getText()
|
function_name = None
|
||||||
if os.name == 'nt': # if Windows
|
for c in function.contents:
|
||||||
function_name = function_name.encode("ascii","ignore").decode()
|
if isinstance(c, bs4.element.NavigableString):
|
||||||
|
fn = str(c).encode("ascii","ignore").decode().strip()
|
||||||
|
if not fn.endswith('()'): # all functions have () in it's name
|
||||||
|
# enums, structures, etc
|
||||||
|
continue
|
||||||
|
function_name = fn[:-2]
|
||||||
|
|
||||||
# all functions have () in it's name
|
if not function_name:
|
||||||
if "()" not in function_name:
|
|
||||||
continue
|
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
|
sign_counter += 1
|
||||||
|
|
||||||
# if not Windows computer
|
|
||||||
if os.name != 'nt':
|
|
||||||
function_name = function_name.replace(' ', '')[2:]
|
|
||||||
|
|
||||||
cpp_table = function.findNext('table')
|
cpp_table = function.findNext('table')
|
||||||
|
|
||||||
if ADD_PYTHON:
|
if config.ADD_PYTHON:
|
||||||
try:
|
signatures = config.python_signatures.get("cv::" + str(function_name), None)
|
||||||
|
if signatures:
|
||||||
print(function_name)
|
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)
|
description = create_description(tmp_soup, "Python:", signatures, function_name)
|
||||||
|
description['class'] = 'python_language'
|
||||||
|
old = cpp_table.next_sibling
|
||||||
|
if old.name != 'table':
|
||||||
|
old = None
|
||||||
|
elif not 'python_language' in old.get('class', []):
|
||||||
|
old = None
|
||||||
|
if old is None:
|
||||||
|
cpp_table.insert_after(description)
|
||||||
|
else:
|
||||||
|
old.replace_with(description)
|
||||||
python_sign_counter += 1
|
python_sign_counter += 1
|
||||||
except AttributeError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if ADD_JAVA:
|
if config.ADD_JAVA:
|
||||||
for signature in java_signatures:
|
for signature in java_signatures:
|
||||||
if function_name in signature:
|
if function_name in signature:
|
||||||
append_table_to(cpp_table, tmp_soup, "Java:", signature, function_name)
|
create_description(cpp_table, tmp_soup, "Java:", signature, function_name)
|
||||||
java_sign_counter += 1
|
java_sign_counter += 1
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -8,13 +8,37 @@ TODO:
|
|||||||
* clarify special case:
|
* clarify special case:
|
||||||
http://docs.opencv.org/3.2.0/db/de0/group__core__utils.html#ga4910d7f86336cd4eff9dd05575667e41
|
http://docs.opencv.org/3.2.0/db/de0/group__core__utils.html#ga4910d7f86336cd4eff9dd05575667e41
|
||||||
"""
|
"""
|
||||||
|
from __future__ import print_function
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import html_functions
|
import logging
|
||||||
|
|
||||||
|
loglevel=os.environ.get("LOGLEVEL", None)
|
||||||
|
if loglevel:
|
||||||
|
logging.basicConfig(level=loglevel)
|
||||||
|
|
||||||
ADD_JAVA = False
|
ADD_JAVA = False
|
||||||
ADD_PYTHON = True
|
ADD_PYTHON = True
|
||||||
ROOT_DIR = sys.argv[1]
|
ROOT_DIR = sys.argv[1]
|
||||||
|
PYTHON_SIGNATURES_FILE = sys.argv[2]
|
||||||
|
|
||||||
|
import json
|
||||||
|
python_signatures = dict()
|
||||||
|
with open(PYTHON_SIGNATURES_FILE, "rt") as f:
|
||||||
|
python_signatures = json.load(f)
|
||||||
|
print("Loaded Python signatures: %d" % len(python_signatures))
|
||||||
|
|
||||||
|
class Configuration():
|
||||||
|
def __init__(self):
|
||||||
|
self.ADD_PYTHON = ADD_PYTHON
|
||||||
|
self.python_signatures = python_signatures
|
||||||
|
self.ADD_JAVA = ADD_JAVA
|
||||||
|
|
||||||
|
config = Configuration()
|
||||||
|
|
||||||
|
|
||||||
|
import html_functions
|
||||||
|
|
||||||
soup = html_functions.load_html_file(ROOT_DIR + "index.html")
|
soup = html_functions.load_html_file(ROOT_DIR + "index.html")
|
||||||
href_list = html_functions.get_links_list(soup, True)
|
href_list = html_functions.get_links_list(soup, True)
|
||||||
@ -24,11 +48,11 @@ for link in href_list:
|
|||||||
soup = html_functions.load_html_file(ROOT_DIR + link)
|
soup = html_functions.load_html_file(ROOT_DIR + link)
|
||||||
sub_href_list = html_functions.get_links_list(soup, True)
|
sub_href_list = html_functions.get_links_list(soup, True)
|
||||||
module_name = html_functions.get_text_between_substrings(link, "group__", ".html")
|
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)
|
html_functions.add_signatures(soup, ROOT_DIR + link, module_name, config)
|
||||||
|
|
||||||
# add python signatures to the sub-modules
|
# add python signatures to the sub-modules
|
||||||
link = re.sub(r"group__.+html", "", link)
|
link = re.sub(r"group__.+html", "", link)
|
||||||
for sub_link in sub_href_list:
|
for sub_link in sub_href_list:
|
||||||
tmp_dir = ROOT_DIR + link + sub_link
|
tmp_dir = ROOT_DIR + link + sub_link
|
||||||
soup = html_functions.load_html_file(tmp_dir)
|
soup = html_functions.load_html_file(tmp_dir)
|
||||||
html_functions.add_signatures(soup, tmp_dir, ADD_JAVA, ADD_PYTHON, module_name)
|
html_functions.add_signatures(soup, tmp_dir, module_name, config)
|
||||||
|
Loading…
Reference in New Issue
Block a user