Make doc generation work with sphinx v3.3
This commit is contained in:
parent
79a4f789a1
commit
a7ecff657c
|
@ -18,7 +18,7 @@ from docutils.parsers.rst import Directive
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
from sphinx import version_info
|
from sphinx import version_info
|
||||||
from sphinx.roles import XRefRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.locale import l_, _
|
from sphinx.locale import _
|
||||||
from sphinx.domains import Domain, ObjType, Index
|
from sphinx.domains import Domain, ObjType, Index
|
||||||
from sphinx.directives import ObjectDescription
|
from sphinx.directives import ObjectDescription
|
||||||
from sphinx.util.nodes import make_refnode
|
from sphinx.util.nodes import make_refnode
|
||||||
|
|
148
doc/mkapiref.py
148
doc/mkapiref.py
|
@ -1,9 +1,11 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# nghttp2 - HTTP/2 C Library
|
# nghttp2 - HTTP/2 C Library
|
||||||
|
#
|
||||||
|
# Copyright (c) 2020 nghttp2 contributors
|
||||||
|
# Copyright (c) 2020 ngtcp2 contributors
|
||||||
# Copyright (c) 2012 Tatsuhiro Tsujikawa
|
# Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||||
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
# "Software"), to deal in the Software without restriction, including
|
# "Software"), to deal in the Software without restriction, including
|
||||||
|
@ -25,17 +27,16 @@
|
||||||
|
|
||||||
# Generates API reference from C source code.
|
# Generates API reference from C source code.
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
from __future__ import print_function # At least python 2.6 is required
|
|
||||||
import re, sys, argparse, os.path
|
import re, sys, argparse, os.path
|
||||||
|
|
||||||
class FunctionDoc:
|
class FunctionDoc:
|
||||||
def __init__(self, name, content, domain):
|
def __init__(self, name, content, domain, filename):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.content = content
|
self.content = content
|
||||||
self.domain = domain
|
self.domain = domain
|
||||||
if self.domain == 'function':
|
if self.domain == 'function':
|
||||||
self.funcname = re.search(r'(nghttp2_[^ )]+)\(', self.name).group(1)
|
self.funcname = re.search(r'(nghttp2_[^ )]+)\(', self.name).group(1)
|
||||||
|
self.filename = filename
|
||||||
|
|
||||||
def write(self, out):
|
def write(self, out):
|
||||||
out.write('.. {}:: {}\n'.format(self.domain, self.name))
|
out.write('.. {}:: {}\n'.format(self.domain, self.name))
|
||||||
|
@ -64,6 +65,26 @@ class StructDoc:
|
||||||
out.write(' {}\n'.format(line))
|
out.write(' {}\n'.format(line))
|
||||||
out.write('\n')
|
out.write('\n')
|
||||||
|
|
||||||
|
class EnumDoc:
|
||||||
|
def __init__(self, name, content, members):
|
||||||
|
self.name = name
|
||||||
|
self.content = content
|
||||||
|
self.members = members
|
||||||
|
|
||||||
|
def write(self, out):
|
||||||
|
if self.name:
|
||||||
|
out.write('.. type:: {}\n'.format(self.name))
|
||||||
|
out.write('\n')
|
||||||
|
for line in self.content:
|
||||||
|
out.write(' {}\n'.format(line))
|
||||||
|
out.write('\n')
|
||||||
|
for name, content in self.members:
|
||||||
|
out.write(' .. enum:: {}\n'.format(name))
|
||||||
|
out.write('\n')
|
||||||
|
for line in content:
|
||||||
|
out.write(' {}\n'.format(line))
|
||||||
|
out.write('\n')
|
||||||
|
|
||||||
class MacroDoc:
|
class MacroDoc:
|
||||||
def __init__(self, name, content):
|
def __init__(self, name, content):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -75,50 +96,76 @@ class MacroDoc:
|
||||||
for line in self.content:
|
for line in self.content:
|
||||||
out.write(' {}\n'.format(line))
|
out.write(' {}\n'.format(line))
|
||||||
|
|
||||||
def make_api_ref(infiles):
|
class MacroSectionDoc:
|
||||||
|
def __init__(self, content):
|
||||||
|
self.content = content
|
||||||
|
|
||||||
|
def write(self, out):
|
||||||
|
out.write('\n')
|
||||||
|
c = ' '.join(self.content).strip()
|
||||||
|
out.write(c)
|
||||||
|
out.write('\n')
|
||||||
|
out.write('-' * len(c))
|
||||||
|
out.write('\n\n')
|
||||||
|
|
||||||
|
class TypedefDoc:
|
||||||
|
def __init__(self, name, content):
|
||||||
|
self.name = name
|
||||||
|
self.content = content
|
||||||
|
|
||||||
|
def write(self, out):
|
||||||
|
out.write('''.. type:: {}\n'''.format(self.name))
|
||||||
|
out.write('\n')
|
||||||
|
for line in self.content:
|
||||||
|
out.write(' {}\n'.format(line))
|
||||||
|
|
||||||
|
def make_api_ref(infile):
|
||||||
macros = []
|
macros = []
|
||||||
enums = []
|
enums = []
|
||||||
types = []
|
types = []
|
||||||
functions = []
|
functions = []
|
||||||
for infile in infiles:
|
while True:
|
||||||
while True:
|
line = infile.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
elif line == '/**\n':
|
||||||
line = infile.readline()
|
line = infile.readline()
|
||||||
if not line:
|
doctype = line.split()[1]
|
||||||
break
|
if doctype == '@function':
|
||||||
elif line == '/**\n':
|
functions.append(process_function('function', infile))
|
||||||
line = infile.readline()
|
elif doctype == '@functypedef':
|
||||||
doctype = line.split()[1]
|
types.append(process_function('type', infile))
|
||||||
if doctype == '@function':
|
elif doctype == '@struct' or doctype == '@union':
|
||||||
functions.append(process_function('function', infile))
|
types.append(process_struct(infile))
|
||||||
elif doctype == '@functypedef':
|
elif doctype == '@enum':
|
||||||
types.append(process_function('type', infile))
|
enums.append(process_enum(infile))
|
||||||
elif doctype == '@struct' or doctype == '@union':
|
elif doctype == '@macro':
|
||||||
types.append(process_struct(infile))
|
macros.append(process_macro(infile))
|
||||||
elif doctype == '@enum':
|
elif doctype == '@macrosection':
|
||||||
enums.append(process_enum(infile))
|
macros.append(process_macrosection(infile))
|
||||||
elif doctype == '@macro':
|
elif doctype == '@typedef':
|
||||||
macros.append(process_macro(infile))
|
types.append(process_typedef(infile))
|
||||||
return macros, enums, types, functions
|
return macros, enums, types, functions
|
||||||
|
|
||||||
alldocs = [('Macros', macros),
|
|
||||||
('Enums', enums),
|
|
||||||
('Types (structs, unions and typedefs)', types),
|
|
||||||
('Functions', functions)]
|
|
||||||
|
|
||||||
def output(
|
def output(
|
||||||
indexfile, macrosfile, enumsfile, typesfile, funcsdir,
|
title, indexfile, macrosfile, enumsfile, typesfile, funcsdir,
|
||||||
macros, enums, types, functions):
|
macros, enums, types, functions):
|
||||||
indexfile.write('''
|
indexfile.write('''
|
||||||
API Reference
|
{title}
|
||||||
=============
|
{titledecoration}
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
macros
|
{macros}
|
||||||
enums
|
{enums}
|
||||||
types
|
{types}
|
||||||
''')
|
'''.format(
|
||||||
|
title=title, titledecoration='='*len(title),
|
||||||
|
macros=os.path.splitext(os.path.basename(macrosfile.name))[0],
|
||||||
|
enums=os.path.splitext(os.path.basename(enumsfile.name))[0],
|
||||||
|
types=os.path.splitext(os.path.basename(typesfile.name))[0],
|
||||||
|
))
|
||||||
|
|
||||||
for doc in functions:
|
for doc in functions:
|
||||||
indexfile.write(' {}\n'.format(doc.funcname))
|
indexfile.write(' {}\n'.format(doc.funcname))
|
||||||
|
@ -153,9 +200,10 @@ Types (structs, unions and typedefs)
|
||||||
Synopsis
|
Synopsis
|
||||||
--------
|
--------
|
||||||
|
|
||||||
*#include <nghttp2/nghttp2.h>*
|
*#include <nghttp2/{filename}>*
|
||||||
|
|
||||||
'''.format(funcname=doc.funcname, secul='='*len(doc.funcname)))
|
'''.format(funcname=doc.funcname, secul='='*len(doc.funcname),
|
||||||
|
filename=doc.filename))
|
||||||
doc.write(f)
|
doc.write(f)
|
||||||
|
|
||||||
def process_macro(infile):
|
def process_macro(infile):
|
||||||
|
@ -164,6 +212,17 @@ def process_macro(infile):
|
||||||
macro_name = line.split()[1]
|
macro_name = line.split()[1]
|
||||||
return MacroDoc(macro_name, content)
|
return MacroDoc(macro_name, content)
|
||||||
|
|
||||||
|
def process_macrosection(infile):
|
||||||
|
content = read_content(infile)
|
||||||
|
return MacroSectionDoc(content)
|
||||||
|
|
||||||
|
def process_typedef(infile):
|
||||||
|
content = read_content(infile)
|
||||||
|
typedef = infile.readline()
|
||||||
|
typedef = re.sub(r';\n$', '', typedef)
|
||||||
|
typedef = re.sub(r'typedef ', '', typedef)
|
||||||
|
return TypedefDoc(typedef, content)
|
||||||
|
|
||||||
def process_enum(infile):
|
def process_enum(infile):
|
||||||
members = []
|
members = []
|
||||||
enum_name = None
|
enum_name = None
|
||||||
|
@ -176,7 +235,7 @@ def process_enum(infile):
|
||||||
member_content = read_content(infile)
|
member_content = read_content(infile)
|
||||||
line = infile.readline()
|
line = infile.readline()
|
||||||
items = line.split()
|
items = line.split()
|
||||||
member_name = items[0]
|
member_name = items[0].rstrip(',')
|
||||||
if len(items) >= 3:
|
if len(items) >= 3:
|
||||||
member_content.insert(0, '(``{}``) '\
|
member_content.insert(0, '(``{}``) '\
|
||||||
.format(' '.join(items[2:]).rstrip(',')))
|
.format(' '.join(items[2:]).rstrip(',')))
|
||||||
|
@ -185,7 +244,7 @@ def process_enum(infile):
|
||||||
enum_name = line.rstrip().split()[1]
|
enum_name = line.rstrip().split()[1]
|
||||||
enum_name = re.sub(r';$', '', enum_name)
|
enum_name = re.sub(r';$', '', enum_name)
|
||||||
break
|
break
|
||||||
return StructDoc(enum_name, content, members, 'macro')
|
return EnumDoc(enum_name, content, members)
|
||||||
|
|
||||||
def process_struct(infile):
|
def process_struct(infile):
|
||||||
members = []
|
members = []
|
||||||
|
@ -226,7 +285,9 @@ def process_function(domain, infile):
|
||||||
func_proto = re.sub(r';\n$', '', func_proto)
|
func_proto = re.sub(r';\n$', '', func_proto)
|
||||||
func_proto = re.sub(r'\s+', ' ', func_proto)
|
func_proto = re.sub(r'\s+', ' ', func_proto)
|
||||||
func_proto = re.sub(r'NGHTTP2_EXTERN ', '', func_proto)
|
func_proto = re.sub(r'NGHTTP2_EXTERN ', '', func_proto)
|
||||||
return FunctionDoc(func_proto, content, domain)
|
func_proto = re.sub(r'typedef ', '', func_proto)
|
||||||
|
filename = os.path.basename(infile.name)
|
||||||
|
return FunctionDoc(func_proto, content, domain, filename)
|
||||||
|
|
||||||
def read_content(infile):
|
def read_content(infile):
|
||||||
content = []
|
content = []
|
||||||
|
@ -251,6 +312,8 @@ def transform_content(content):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser(description="Generate API reference")
|
parser = argparse.ArgumentParser(description="Generate API reference")
|
||||||
|
parser.add_argument('--title', default='API Reference',
|
||||||
|
help='title of index page')
|
||||||
parser.add_argument('index', type=argparse.FileType('w'),
|
parser.add_argument('index', type=argparse.FileType('w'),
|
||||||
help='index output file')
|
help='index output file')
|
||||||
parser.add_argument('macros', type=argparse.FileType('w'),
|
parser.add_argument('macros', type=argparse.FileType('w'),
|
||||||
|
@ -269,12 +332,13 @@ if __name__ == '__main__':
|
||||||
types = []
|
types = []
|
||||||
funcs = []
|
funcs = []
|
||||||
for infile in args.files:
|
for infile in args.files:
|
||||||
m, e, t, f = make_api_ref(args.files)
|
m, e, t, f = make_api_ref(infile)
|
||||||
macros.extend(m)
|
macros.extend(m)
|
||||||
enums.extend(e)
|
enums.extend(e)
|
||||||
types.extend(t)
|
types.extend(t)
|
||||||
funcs.extend(f)
|
funcs.extend(f)
|
||||||
funcs.sort(key=lambda x: x.funcname)
|
funcs.sort(key=lambda x: x.funcname)
|
||||||
output(
|
output(
|
||||||
|
args.title,
|
||||||
args.index, args.macros, args.enums, args.types, args.funcsdir,
|
args.index, args.macros, args.enums, args.types, args.funcsdir,
|
||||||
macros, enums, types, funcs)
|
macros, enums, types, funcs)
|
||||||
|
|
Loading…
Reference in New Issue