<filename>tools/hdoc.py<gh_stars>10-100
#!/usr/bin/env python3

import sys
import re
from subprocess import Popen, PIPE
from argparse import ArgumentParser

__version__ = "0.1"

RE_FN = re.compile("[^\s]+\s+([^\(]+)\(")
RE_STRUCT = re.compile("(struct\s+[^{]+)\s*{")
RE_DEFINE = re.compile("#define\s+([^(]+)\(")
RE_DOC = re.compile("\s+\*\s?(.*\n)")
RE_SEC = re.compile("//\s+@(.*)\n")
RE_SECDOC = re.compile("//\s?(.*\n)")


def main():

    parser = ArgumentParser(description="Include docs to markdown",
                            epilog="Copyright (C) 2020 <NAME> <<EMAIL>>",
                            )

    parser.add_argument("--version", action="version",
                        version="%(prog)s " + __version__)
    parser.add_argument("--doc-version", dest="docver", default=None,
                        help="Use this as version instead of git tag/commit")
    parser.add_argument("--header", dest="header", default=None,
                        help="Add this file at the begining of the document")
    parser.add_argument("--footer", dest="footer", default=None,
                        help="Add this file at the end of the document")
    parser.add_argument("title", help="Title of the resulting document")

    args = parser.parse_args()

    if args.docver is None:
        proc = Popen(["git", "describe", "--abbrev=0", "--tags"],
                     stdout=PIPE, stderr=PIPE)
        out, err = proc.communicate()
        if proc.returncode != 0:
            proc = Popen(["git", "rev-parse", "--short", "HEAD"],
                         stdout=PIPE, stderr=PIPE)
            out, err = proc.communicate()
            out = b"git-" + out

        docver = out.decode("utf-8").strip()
    else:
        docver = args.docver

    data = sys.stdin.readlines()
    ref = {}
    section = None
    sections = {}
    while data:
        line = data.pop(0)

        # section comment
        if line.strip().startswith("//"):
            g = RE_SEC.search(line)
            if g:
                section = g.group(1)
                doclines = []
                while True:
                    line = data.pop(0)
                    if not line.strip():
                        break
                    doclines.append(line)

                doc = ""
                for l in doclines:
                    g = RE_SECDOC.match(l)
                    if g:
                        doc += g.group(1)

                sections[section] = doc

        # begin fn/struct comment
        if line.strip() == "/**":
            doclines = []
            while True:
                line = data.pop(0)
                if line.strip() == "*/":
                    break
                doclines.append(line)

            line = data.pop(0)
            g = RE_DEFINE.search(line)
            if g is None:
                g = RE_STRUCT.search(line)
                if g is None:
                    g = RE_FN.search(line)
                    if g is None:
                        continue
                    else:
                        fn = line.strip()
                else:
                    fn = line
                    while True:
                        line = data.pop(0)
                        fn += line
                        if line.strip() == "};":
                            break
            else:
                fn = line
                while True:
                    line = data.pop(0)
                    fn += line
                    if not line.strip().endswith("\\"):
                        fn = fn.rstrip()
                        break

            name = g.group(1).strip()
            anchor = name.replace(" ", "-")

            doc = ""
            for l in doclines:
                g = RE_DOC.match(l)
                if g:
                    doc += g.group(1)
            ref[name] = {"name": name, "anchor": anchor,
                         "fn": fn, "doc": doc, "section": section}

    print("""\
---
title: '{title}'
subtitle: 'Version {version}'
...""".format(title=args.title, version=docver))

    if args.header:
        with open(args.header, "rt") as fd:
            print(fd.read())

    csec = None
    for k in sorted(ref.keys(), key=lambda k: (ref[k]["section"], k)):
        v = ref[k]
        if csec != v["section"]:
            csec = v["section"]
            print("## %s\n" % csec)
            if csec in sections:
                print(sections[csec])

        print("""\
### {name}
```c
{fn}
```

{doc}
""".format(**v))

    if args.footer:
        with open(args.footer, "rt") as fd:
            print(fd.read())


if __name__ == "__main__":
    main()

<filename>tools/hdoc.py<gh_stars>10-100
#!/usr/bin/env python3

import sys
import re
from subprocess import Popen, PIPE
from argparse import ArgumentParser

__version__ = "0.1"

RE_FN = re.compile("[^\s]+\s+([^\(]+)\(")
RE_STRUCT = re.compile("(struct\s+[^{]+)\s*{")
RE_DEFINE = re.compile("#define\s+([^(]+)\(")
RE_DOC = re.compile("\s+\*\s?(.*\n)")
RE_SEC = re.compile("//\s+@(.*)\n")
RE_SECDOC = re.compile("//\s?(.*\n)")


def main():

    parser = ArgumentParser(description="Include docs to markdown",
                            epilog="Copyright (C) 2020 <NAME> <<EMAIL>>",
                            )

    parser.add_argument("--version", action="version",
                        version="%(prog)s " + __version__)
    parser.add_argument("--doc-version", dest="docver", default=None,
                        help="Use this as version instead of git tag/commit")
    parser.add_argument("--header", dest="header", default=None,
                        help="Add this file at the begining of the document")
    parser.add_argument("--footer", dest="footer", default=None,
                        help="Add this file at the end of the document")
    parser.add_argument("title", help="Title of the resulting document")

    args = parser.parse_args()

    if args.docver is None:
        proc = Popen(["git", "describe", "--abbrev=0", "--tags"],
                     stdout=PIPE, stderr=PIPE)
        out, err = proc.communicate()
        if proc.returncode != 0:
            proc = Popen(["git", "rev-parse", "--short", "HEAD"],
                         stdout=PIPE, stderr=PIPE)
            out, err = proc.communicate()
            out = b"git-" + out

        docver = out.decode("utf-8").strip()
    else:
        docver = args.docver

    data = sys.stdin.readlines()
    ref = {}
    section = None
    sections = {}
    while data:
        line = data.pop(0)

        # section comment
        if line.strip().startswith("//"):
            g = RE_SEC.search(line)
            if g:
                section = g.group(1)
                doclines = []
                while True:
                    line = data.pop(0)
                    if not line.strip():
                        break
                    doclines.append(line)

                doc = ""
                for l in doclines:
                    g = RE_SECDOC.match(l)
                    if g:
                        doc += g.group(1)

                sections[section] = doc

        # begin fn/struct comment
        if line.strip() == "/**":
            doclines = []
            while True:
                line = data.pop(0)
                if line.strip() == "*/":
                    break
                doclines.append(line)

            line = data.pop(0)
            g = RE_DEFINE.search(line)
            if g is None:
                g = RE_STRUCT.search(line)
                if g is None:
                    g = RE_FN.search(line)
                    if g is None:
                        continue
                    else:
                        fn = line.strip()
                else:
                    fn = line
                    while True:
                        line = data.pop(0)
                        fn += line
                        if line.strip() == "};":
                            break
            else:
                fn = line
                while True:
                    line = data.pop(0)
                    fn += line
                    if not line.strip().endswith("\\"):
                        fn = fn.rstrip()
                        break

            name = g.group(1).strip()
            anchor = name.replace(" ", "-")

            doc = ""
            for l in doclines:
                g = RE_DOC.match(l)
                if g:
                    doc += g.group(1)
            ref[name] = {"name": name, "anchor": anchor,
                         "fn": fn, "doc": doc, "section": section}

    print("""\
---
title: '{title}'
subtitle: 'Version {version}'
...""".format(title=args.title, version=docver))

    if args.header:
        with open(args.header, "rt") as fd:
            print(fd.read())

    csec = None
    for k in sorted(ref.keys(), key=lambda k: (ref[k]["section"], k)):
        v = ref[k]
        if csec != v["section"]:
            csec = v["section"]
            print("## %s\n" % csec)
            if csec in sections:
                print(sections[csec])

        print("""\
### {name}
```c
{fn}
```

{doc}
""".format(**v))

    if args.footer:
        with open(args.footer, "rt") as fd:
            print(fd.read())


if __name__ == "__main__":
    main()

#!/usr/bin/env python3 # section comment # begin fn/struct comment \ --- title: '{title}' subtitle: 'Version {version}' ... # %s\n" % csec) \ ### {name} ```c {fn} ```  {doc}