adrianvlupu / C4-Builder

This is a documentation builder. You feed it .md and .puml and it exports a site, pdf, or a markdown with navigation.
https://adrianvlupu.github.io/C4-Builder/
MIT License
562 stars 93 forks source link

Support add some hooks before/after/in when build src to docs #86

Open zzxzz12345 opened 10 months ago

zzxzz12345 commented 10 months ago

Is it possible to add some hooks before and after the build function, as well as before and after converting PUML to PNG, to achieve some effects using additional script processing? For example, my current project scans all generated markdown files after build is complete, and then

```python @execute
import Demo
text=Demo.SOME_KEY
```
```python @execute
def outout(s:io.StringIO()):
    io.append("test")
```

The content in the API description is output according to the Python script I wrote. If this is used to automatically generate and export some APIs and descriptive text.

In addition, before converting PUML, we can write a script to replace placeholders like '$ABC' to automatically generate some PUML content to prevent a certain degree of document corruption.

At present, my approach is to simply rewrite build.js to achieve my goal, but I think it can be more modular

const {build} = require('c4builder/build')
const {execSync} = require('child_process')
const {existsSync} = require('fs')
const extraBuild = async (options, conf) => {
    await build(options, conf)
    const venv = '../../venv/bin/python'
    const python = existsSync(venv) ? venv : 'python'
    console.log('process markdown python start');
    execSync(`${python} ./scripts/process_md_python.py`, (error, stdout, stderr) => {
        if (error) {
            console.error('execute python error', error)
        }
        if (stdout) {
            console.log(stdout)
        }
        if (stderr) {
            console.error(stderr)
        }
    })
    console.log('process markdown python finish');

}
module.exports = {build: extraBuild}
import glob
import io

import sys

sys.path.append("../../src")
sys.path.append("../")

for file in glob.glob('./docs/**/*.md', recursive=True):
    f = open(file)
    content = f.read()
    find_exec = True
    while find_exec:
        namespace = {}
        word = "```python @execute"
        start = content.find(word)
        if start > 0:
            end = content.find("```", start + len(word))
            script = content[(start + len(word)):end]

            try:
                exec(script, namespace)
                if namespace.get('output') is not None:
                    s = io.StringIO()
                    namespace['output'](s)
                    content = content[:start] + s.getvalue() + content[(end + len("```")):]
                elif namespace.get('pre_text') is not None:
                    pre_text = namespace['pre_text']
                    content = (content[:start] + "```\n" + str(pre_text).replace('```', "").strip() + "\n```" +
                               content[(end + len("```")):])
                elif namespace.get('text') is not None:
                    text = namespace['text']
                    content = content[:start] + text + content[(end + len("```")):]
            except Exception as e:
                print("execute script failed:")
                print(script)
                print(e.with_traceback(None))
        else:
            find_exec = False
    f.close()
    f = open(file, 'w')
    f.write(content)
    f.close()