diff --git a/api/address.proto b/api/address.proto index 04ea6db5..8879f11a 100644 --- a/api/address.proto +++ b/api/address.proto @@ -4,6 +4,7 @@ package envoy.api.v2; import "google/protobuf/wrappers.proto"; +// protodoc-title: Network related configuration elements // [V2-API-DIFF] Addresses now have .proto structure. message Pipe { diff --git a/api/base.proto b/api/base.proto index acb37046..40c6329b 100644 --- a/api/base.proto +++ b/api/base.proto @@ -9,6 +9,8 @@ import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; +// protodoc-title: Common configuration elements + // Identifies location of where either Envoy runs or where upstream hosts run. message Locality { // Region this zone belongs to. diff --git a/tools/protodoc/protodoc.py b/tools/protodoc/protodoc.py index af11df71..81f33f86 100755 --- a/tools/protodoc/protodoc.py +++ b/tools/protodoc/protodoc.py @@ -7,6 +7,7 @@ from collections import defaultdict import copy import functools import sys +import re from google.protobuf.compiler import plugin_pb2 @@ -19,6 +20,8 @@ WKT_NAMESPACE_PREFIX = '.google.protobuf.' # http://www.fileformat.info/info/unicode/char/2063/index.htm UNICODE_INVISIBLE_SEPARATOR = u'\u2063' +# Page/section titles with special prefixes in the proto comments +DOC_TITLE_REGEX = 'protodoc-title:\s([^\n]+)\n\n?' class ProtodocError(Exception): """Base error class for the protodoc module.""" @@ -134,6 +137,23 @@ def FormatHeader(style, text): return '%s\n%s\n\n' % (text, style * len(text)) +def FormatHeaderFromFile(style, file_level_comment, alt): + """Format RST header based on special file level title + + Args: + style: underline style, e.g. '=', '-'. + file_level_comment: detached comment at top of file. + alt: If the file_level_comment does not contain a user + specified title, use the alt text as page title. + Returns: + RST formatted header, and file level comment without page title strings. + """ + m = re.search(DOC_TITLE_REGEX, file_level_comment) + if m: + # remove title hint and any new lines that follow + return FormatHeader(style, m.group(1)), re.sub(DOC_TITLE_REGEX, '', file_level_comment) + return FormatHeader(style, alt), file_level_comment + def FormatFieldTypeAsJson(type_context, field): """Format FieldDescriptorProto.Type as a pseudo-JSON string. @@ -402,10 +422,11 @@ def FormatProtoAsBlockComment(proto): def GenerateRst(proto_file): """Generate a RST representation from a FileDescriptor proto.""" - header = FormatHeader('=', proto_file.name) source_code_info = SourceCodeInfo(proto_file.source_code_info) # Find the earliest detached comment, attribute it to file level. - comment = source_code_info.file_level_comment + # Also extract file level titles if any. + header, comment = FormatHeaderFromFile('=', source_code_info.file_level_comment, + proto_file.name) msgs = '\n'.join( FormatMessage(TypeContext(source_code_info, [4, index], msg.name), msg) for index, msg in enumerate(proto_file.message_type))