pseudomuto / protoc-gen-doc

Documentation generator plugin for Google Protocol Buffers
MIT License
2.61k stars 462 forks source link

html hyperlinks to custom types in tables not working #419

Open naderafshari opened 4 years ago

naderafshari commented 4 years ago

When clicking on primitive types in the Type column we jump to the Scalar Value Types table at the end of the html page. But, when clinking on custom types in the Type column, which are defined and present in the same html page, nothing happens. This does seem unexpected. Is this a bug?

kawasakizx10rr commented 4 years ago

I have a similar issue with the produced html, i see quite a few links to things like google.protobuf.timestamp which is listed in the html document as a hyperlink but when clicked it does nothing, and no detailed entry of it exists within the document.

Any ideas how to resolve these links that does not work within the produced HTML document ?

jack-tutor commented 1 year ago

I found that the href are just missing a . - you can add this in the url to see it work.

I decided to just post-process the html file - will leave some python code in case it helps other people:

Regex matches the row - group 0 is the href - we then find all the occurences and replace. I am excluding the grpc primitive types in this regex - but it may be cleaner to do this in my replace function. Can totally believe there are lighter weight ways to perform this operation too.

    primitive_types = [
        "double",
        "float",
        *[f"{numType}{size}" for size in ["32", "64"] for numType in ["int", "uint", "sint", "fixed", "sfixed"]],
        "bool",
        "string",
        "bytes",
    ]
    regex = rf'<td><a href="#(?!(?:{"|".join(primitive_types)}))([\w.]+)">(.*?)</a></td>'

    def handle_match(match: re.Match) -> str:
        # Get the matched text and start/end positions of the second group
        group_text = match.group(1)
        group_start = match.start(1) - match.start(0)  # indexed from the start of the text of the doc
        group_end = match.end(1) - match.start(0)
        full_string = match.group(0)

        return f"{full_string[:group_start]}.{group_text}{full_string[group_end:]}"

    with open(f"{path_to_docs}/index.html", "r+") as html_file:
        html = html_file.read()
        html_file.seek(0)
        html_file.write(re.sub(regex, handle_match, html))
        html_file.truncate()