finished, also added cobra cli
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
package renderer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"dirmd/internal/tree"
|
||||
"dirmd/internal/walker"
|
||||
)
|
||||
|
||||
const fenceChars = "~~~"
|
||||
|
||||
func Write(result *walker.Result, outputPath string, appendMode bool, singleFile bool) error {
|
||||
flags := os.O_CREATE | os.O_WRONLY
|
||||
if appendMode {
|
||||
flags |= os.O_APPEND
|
||||
} else {
|
||||
flags |= os.O_TRUNC
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(outputPath, flags, 0644)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot open output file: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var sb strings.Builder
|
||||
|
||||
// Determine the correct H1 path
|
||||
h1Path := result.AbsRoot
|
||||
if singleFile && len(result.Entries) > 0 {
|
||||
h1Path = filepath.Join(result.AbsRoot, result.Entries[0].RelPath)
|
||||
}
|
||||
|
||||
fmt.Fprintf(&sb, "# %s\n\n", h1Path)
|
||||
|
||||
if !singleFile {
|
||||
root := tree.Build(result.Entries)
|
||||
rootName := filepath.Base(result.AbsRoot)
|
||||
sb.WriteString("## Directory Tree\n\n")
|
||||
sb.WriteString(fenceChars + "\n")
|
||||
sb.WriteString(tree.Render(root, rootName))
|
||||
sb.WriteString(fenceChars + "\n\n")
|
||||
}
|
||||
|
||||
if len(result.Entries) > 0 {
|
||||
if !singleFile {
|
||||
sb.WriteString("## Contents\n\n")
|
||||
}
|
||||
|
||||
for _, entry := range result.Entries {
|
||||
fullPath := filepath.Join(result.AbsRoot, entry.RelPath)
|
||||
|
||||
content, err := readFile(fullPath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "warning: cannot read %s: %v\n", entry.RelPath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
language := extToLang(filepath.Ext(entry.RelPath))
|
||||
|
||||
fmt.Fprintf(&sb, "### ./%s\n\n", entry.RelPath)
|
||||
fmt.Fprintf(&sb, "%s", fenceChars)
|
||||
if language != "" {
|
||||
fmt.Fprintf(&sb, "%s", language)
|
||||
}
|
||||
fmt.Fprintf(&sb, "\n")
|
||||
fmt.Fprintf(&sb, "%s", content)
|
||||
if !strings.HasSuffix(content, "\n") {
|
||||
fmt.Fprintf(&sb, "\n")
|
||||
}
|
||||
fmt.Fprintf(&sb, "%s\n\n", fenceChars)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = f.WriteString(sb.String())
|
||||
return err
|
||||
}
|
||||
|
||||
func readFile(path string) (string, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i, b := range data {
|
||||
if b == 0 {
|
||||
return "", fmt.Errorf("contains null byte at position %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
if !utf8.Valid(data) {
|
||||
return "", fmt.Errorf("invalid UTF-8 encoding")
|
||||
}
|
||||
|
||||
content := string(data)
|
||||
content = strings.ReplaceAll(content, "\r\n", "\n")
|
||||
content = strings.ReplaceAll(content, "\r", "\n")
|
||||
|
||||
return content, nil
|
||||
}
|
||||
|
||||
func extToLang(ext string) string {
|
||||
mapping := map[string]string{
|
||||
".go": "go",
|
||||
".md": "markdown",
|
||||
".yml": "yaml",
|
||||
".yaml": "yaml",
|
||||
".js": "javascript",
|
||||
".ts": "typescript",
|
||||
".css": "css",
|
||||
".html": "html",
|
||||
".json": "json",
|
||||
".xml": "xml",
|
||||
".sql": "sql",
|
||||
".sh": "bash",
|
||||
".py": "python",
|
||||
".rs": "rust",
|
||||
".c": "c",
|
||||
".h": "c",
|
||||
".cpp": "cpp",
|
||||
".hpp": "cpp",
|
||||
".txt": "text",
|
||||
}
|
||||
|
||||
if lang, ok := mapping[strings.ToLower(ext)]; ok {
|
||||
return lang
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user