NubeIO / rubix-ce-docs

ce docs
https://nubeio.github.io/rubix-ce-docs/
0 stars 1 forks source link

go code to md #32

Open NubeDev opened 1 year ago

NubeDev commented 1 year ago

using godocdown

https://github.com/robertkrimen/godocdown

install

go install github.com/robertkrimen/godocdown/godocdown

coded example

example of a simple generator for // or ///

go run main.go -path=/home/aidan/code/go/go2md
func main() {
    pathParse := flag.String("path", "", "")
    flag.Parse()
    path := *pathParse
    fmt.Println("word:", path)
    doc, err := Get(path, true, true)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error creating of documentation from folder `%s`: %v", path, err)
        os.Exit(1)
    }

    fmt.Println(doc)
}
package main

import (
    "bytes"
    "errors"
    "fmt"
    "io/ioutil"
    "os"
    "path/filepath"
    "sort"
    "strings"
)

var separator string = string(filepath.Separator)

func Get(path string, deep, asTriple bool) (doc string, err error) {
    defer func() {
        if err != nil {
            et := errors.New(fmt.Sprintf("error with input data: err: %v %v, %v", path, deep, err))
            err = et
        }
    }()
    //  Function Get
    //  search all Go files in `path` and go deeper by folders.
    var aPath string
    aPath, err = filepath.Abs(path)
    if err != nil {
        return "", fmt.Errorf("cannot get absolute path: %v", err)
    }
    var st os.FileInfo
    st, err = os.Stat(aPath)
    if os.IsNotExist(err) {
        return "", fmt.Errorf("cannot find: `%s`", path)
    }
    if !st.IsDir() {
        return "", fmt.Errorf("is not a folder: `%s`", path)
    }

    var files []string

    // List of ignore folders: vendor, .git
    ignore := []string{"vendor", ".git"}
    folderList := []string{path}
    // For avoid infinite loop added limits of search iterations(cycles).
    for iter := 0; iter < 1000000; iter++ {
        var findFolders []string
        for _, folder := range folderList {
            fileInfo, err := ioutil.ReadDir(folder)
            if err != nil {
                return "", fmt.Errorf("cannot read dir `%s`: %v", folder, err)
            }
            for _, f := range fileInfo {
                if f.IsDir() {
                    isIgnore := false
                    for _, ig := range ignore {
                        if f.Name() == ig {
                            isIgnore = true
                            break
                        }
                    }
                    if isIgnore {
                        continue
                    }
                    findFolders = append(findFolders, f.Name())
                    continue
                }
                if name := f.Name(); strings.HasSuffix(name, ".go") {
                    files = append(files, folder+separator+name)
                }
            }
        }
        folderList = findFolders
        if !deep || len(folderList) == 0 {
            break
        }
    }

    if len(files) == 0 {
        return "", fmt.Errorf("cannot find any files")
    }

    sort.Strings(files)
    // Reading files one by one.
    for _, filename := range files {
        var content []byte
        content, err = ioutil.ReadFile(filename)
        if err != nil {
            // If cannot read a file content, then return the error.
            return "", fmt.Errorf("cannot read file content: %v", filename)
        }
        // Read file line by line.
        lines := bytes.Split(content, []byte("\n"))
        for i := range lines {
            line := lines[i]
            var ts string = "//"
            if asTriple {
                ts = "///"
            }

            index := bytes.Index(line, []byte(ts))

            if index < 0 {
                // that line haven`t triplet-slash
                continue
            }
            if index > 0 {
                // Before triplet-slash is not acceptable any characters,
                // except `\t` or space.
                isAcceptableLine := true
                for pos := 0; pos < index; pos++ {
                    if !(line[pos] == ' ' || line[pos] == '\t') {
                        isAcceptableLine = false
                        break
                    }
                }
                if !isAcceptableLine {
                    continue
                }
            }
            newLine := string(line[index+len(ts):]) + "\n"

            if strings.Contains(newLine, "Function") {
                doc += "## " + newLine
            } else if strings.Contains(newLine, "Type") {
                doc += "## " + newLine
            } else if strings.Contains(newLine, "Example") {
                doc += "### " + newLine
            } else {
                doc += newLine
            }
        }
    }
    return
}