From ea7852256f9ae51ced72f4bab0598cc8120f189e Mon Sep 17 00:00:00 2001 From: dexta Date: Mon, 27 Jul 2026 18:40:05 +0200 Subject: [PATCH] test the graph --- 00_aMeta/toolz/CYOA/Dockerfile.echobox | 12 +++ 00_aMeta/toolz/CYOA/getItWork.txt | 4 + 00_aMeta/toolz/CYOA/main.go | 87 +++++++++---------- .../stories/cyoa_juniorMiner/node_funk.adoc | 22 +++-- .../cyoa_juniorMiner/node_sensoren.adoc | 20 +++++ .../stories/cyoa_juniorMiner/node_start.adoc | 2 +- .../cyoa_juniorMiner/node_steuerung.adoc | 23 +++-- .../cyoa_juniorMiner/node_steuerungMitte.adoc | 20 +++++ .../cyoa_juniorMiner/node_steuerungOben.adoc | 20 +++++ .../cyoa_juniorMiner/node_steuerungUnten.adoc | 20 +++++ .../stories/cyoa_juniorMiner/node_waffen.adoc | 19 ++++ 11 files changed, 185 insertions(+), 64 deletions(-) create mode 100644 00_aMeta/toolz/CYOA/Dockerfile.echobox create mode 100644 00_aMeta/toolz/CYOA/stories/cyoa_juniorMiner/node_sensoren.adoc create mode 100644 00_aMeta/toolz/CYOA/stories/cyoa_juniorMiner/node_steuerungMitte.adoc create mode 100644 00_aMeta/toolz/CYOA/stories/cyoa_juniorMiner/node_steuerungOben.adoc create mode 100644 00_aMeta/toolz/CYOA/stories/cyoa_juniorMiner/node_steuerungUnten.adoc create mode 100644 00_aMeta/toolz/CYOA/stories/cyoa_juniorMiner/node_waffen.adoc diff --git a/00_aMeta/toolz/CYOA/Dockerfile.echobox b/00_aMeta/toolz/CYOA/Dockerfile.echobox new file mode 100644 index 0000000..6115682 --- /dev/null +++ b/00_aMeta/toolz/CYOA/Dockerfile.echobox @@ -0,0 +1,12 @@ +FROM debian:trixie-slim + +# Asciidoctor installieren und apt-Cache sofort wieder leeren, um das Image klein zu halten +RUN apt-get update && \ + apt-get install -y --no-install-recommends asciidoctor && \ + rm -rf /var/lib/apt/lists/* + +# ENTRYPOINT als Echo Box: +# -s = embedded (kein html/body wraper) +# -o - = output auf stdout +# - = read von stdin +ENTRYPOINT ["asciidoctor", "-s", "-o", "-", "-"] \ No newline at end of file diff --git a/00_aMeta/toolz/CYOA/getItWork.txt b/00_aMeta/toolz/CYOA/getItWork.txt index 9dae686..e2ceddc 100644 --- a/00_aMeta/toolz/CYOA/getItWork.txt +++ b/00_aMeta/toolz/CYOA/getItWork.txt @@ -10,3 +10,7 @@ go build -o cyoa-engine main.go ./cyoa-engine -dir ./stories -serve -port 8080 # Wenn du jetzt in Neovim Dateien abspeicherst oder neue `[[node_id]]`-Knoten anlegst, musst du im # Browser nur `http://localhost:8080` aufrufen und siehst sofort deine Änderungen inkl. vollständiger Link-Prüfung! + +# baue das docker image + +docker build -t asciidoctor-echo -f Dockerfile.echobox . \ No newline at end of file diff --git a/00_aMeta/toolz/CYOA/main.go b/00_aMeta/toolz/CYOA/main.go index 320f2aa..310b817 100644 --- a/00_aMeta/toolz/CYOA/main.go +++ b/00_aMeta/toolz/CYOA/main.go @@ -7,6 +7,7 @@ import ( "html/template" "net/http" "os" + "os/exec" "path/filepath" "regexp" "strings" @@ -20,13 +21,13 @@ type Choice struct { // StoryNode repräsentiert einen einzelnen Knotenpunkt in der Geschichte type StoryNode struct { - ID string `json:"id"` - Title string `json:"title"` - Content string `json:"content"` - Choices []Choice `json:"choices"` - IsReboot bool `json:"isReboot"` - IsEnd bool `json:"isEnd"` - FileSource string `json:"fileSource"` + ID string `json:"id"` + Title string `json:"title"` + Content string `json:"content"` + Choices []Choice `json:"choices"` + IsReboot bool `json:"isReboot"` + IsEnd bool `json:"isEnd"` + FileSource string `json:"fileSource"` } // StoryGraph hält alle Knoten und Analyse-Daten @@ -78,8 +79,6 @@ func loadStoryGraph(rootDir string) *StoryGraph { } // Regex-Muster für Knoten und Links - // AsciiDoc: [[node_id]] gefolgt von === Titel - // Markdown: # node_id oder [[node_id]] adocNodeRegex := regexp.MustCompile(`\[\[([a-zA-Z0-9_\-]+)\]\]`) adocChoiceRegex := regexp.MustCompile(`<<([a-zA-Z0-9_\-]+)\s*,\s*([^>]+)>>`) mdChoiceRegex := regexp.MustCompile(`\[([^\]]+)\]\((?:#)?([a-zA-Z0-9_\-]+)\)`) @@ -112,7 +111,7 @@ func loadStoryGraph(rootDir string) *StoryGraph { // Prüfung auf neuen Knoten-Anker [[id]] if matches := adocNodeRegex.FindStringSubmatch(line); len(matches) > 1 { if currentNode != nil { - currentNode.Content = cleanBodyText(currentBody.String()) + currentNode.Content = renderWithEchoBox(currentBody.String()) graph.Nodes[currentNode.ID] = currentNode currentBody.Reset() } @@ -186,7 +185,7 @@ func loadStoryGraph(rootDir string) *StoryGraph { } if currentNode != nil { - currentNode.Content = cleanBodyText(currentBody.String()) + currentNode.Content = renderWithEchoBox(currentBody.String()) graph.Nodes[currentNode.ID] = currentNode } @@ -194,23 +193,34 @@ func loadStoryGraph(rootDir string) *StoryGraph { }) if err != nil { - fmt.Printf("\033[1;31m[WAR NUNG]\033[0m Fehler beim Durchsuchen der Dateien: %v\n", err) + fmt.Printf("\033[1;31m[WARNUNG]\033[0m Fehler beim Durchsuchen der Dateien: %v\n", err) } return graph } -// cleanBodyText entfernt Syntax-Rauschen für die HTML-Darstellung -func cleanBodyText(raw string) string { - // Links entfernen/bereinigen +// renderWithEchoBox entfernt Syntax-Rauschen und nutzt den Debian 13 Docker Container als HTML Echo Box +func renderWithEchoBox(raw string) string { + fmt.Println("render with docker") + // Links entfernen (Diese sollen als Buttons, nicht als Text-Wirrwarr auftauchen) adocChoiceRegex := regexp.MustCompile(`<<[a-zA-Z0-9_\-]+\s*,\s*([^>]+)>>`) cleaned := adocChoiceRegex.ReplaceAllString(raw, "") mdChoiceRegex := regexp.MustCompile(`\[([^\]]+)\]\((?:#)?[a-zA-Z0-9_\-]+\)`) cleaned = mdChoiceRegex.ReplaceAllString(cleaned, "") - // HTML-Maskierung - return html.EscapeString(strings.TrimSpace(cleaned)) + // Docker Echo Box aufrufen (Debian 13 Asciidoctor) + cmd := exec.Command("docker", "run", "--rm", "-i", "asciidoctor-echo") + cmd.Stdin = strings.NewReader(strings.TrimSpace(cleaned)) + + out, err := cmd.Output() + if err != nil { + // Fallback bei Docker-Fehler (z.B. wenn der Daemon nicht läuft) + fmt.Printf("\033[1;31m[DOCKER FEHLER]\033[0m Konnte Echo Box nicht nutzen. Fallback auf RAW Text.\n") + return html.EscapeString(strings.TrimSpace(cleaned)) + } + + return string(out) } // validateGraph prüft Verzweigungen auf Konsistenz @@ -246,7 +256,7 @@ func validateGraph(g *StoryGraph) { // Konsolen-Bericht if len(g.BrokenLinks) > 0 { - fmt.Println("\n\033[1;31m[!] DEFECKTE ZIEL-LINKS (Fehlende Knoten):\033[0m") + fmt.Println("\n\033[1;31m[!] DEFEKTE ZIEL-LINKS (Fehlende Knoten):\033[0m") for _, link := range g.BrokenLinks { fmt.Printf(" - %s\n", link) } @@ -300,13 +310,6 @@ func startServer(g *StoryGraph, htmlPath string, port int, watchDir string) { http.ServeFile(w, r, htmlPath) }) - http.HandleFunc("/api/graph", func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - freshGraph := loadStoryGraph(watchDir) - // Einfacher JSON Output - fmt.Fprintf(w, `{"nodes":%d, "start":"%s"}`, len(freshGraph.Nodes), freshGraph.StartNodeID) - }) - err := http.ListenAndServe(addr, nil) if err != nil { fmt.Printf("Server-Fehler: %v\n", err) @@ -360,7 +363,6 @@ const htmlTemplate = ` pointer-events: none; } - /* Window Maker Header */ header { background: #111; border-bottom: 2px solid var(--term-green); @@ -389,7 +391,6 @@ const htmlTemplate = ` background: rgba(0, 20, 10, 0.5); } - /* Hauptbereich */ main { flex: 1; display: flex; @@ -403,7 +404,6 @@ const htmlTemplate = ` z-index: 1; } - /* Story Terminal Content */ .node-card { border: 1px solid var(--term-dim); background: rgba(5, 15, 10, 0.85); @@ -424,11 +424,19 @@ const htmlTemplate = ` .node-body { line-height: 1.6; font-size: 1rem; - white-space: pre-wrap; margin-bottom: 20px; } - /* Choices List */ + /* AsciiDoc Formatierungen im Terminal Look */ + .node-body p { margin-bottom: 15px; } + .node-body ul, .node-body ol { margin-bottom: 15px; margin-left: 20px; } + .node-body li { margin-bottom: 5px; } + .node-body strong, .node-body b { color: var(--term-amber); } + .node-body em, .node-body i { color: var(--term-cyan); font-style: italic;} + .node-body code { background: rgba(0, 255, 102, 0.1); padding: 2px 5px; border-radius: 3px; font-family: var(--font-stack); } + .node-body h1, .node-body h2, .node-body h3, .node-body h4 { color: var(--term-cyan); margin: 20px 0 10px 0; border-bottom: 1px dashed var(--term-dim); padding-bottom: 5px; } + .node-body blockquote { border-left: 3px solid var(--term-dim); padding-left: 10px; margin-bottom: 15px; font-style: italic; opacity: 0.8; } + .choices-container { display: flex; flex-direction: column; @@ -471,7 +479,6 @@ const htmlTemplate = ` color: var(--term-green); } - /* Controls & Graph Modal Toggle */ footer { border-top: 1px solid var(--term-dim); padding: 10px 20px; @@ -496,7 +503,6 @@ const htmlTemplate = ` color: var(--term-cyan); } - /* Graph Canvas View */ #graph-modal { display: none; position: fixed; @@ -541,17 +547,15 @@ const htmlTemplate = ` -
-
+
=== INTERAKTIVER VORHERSAGE-GRAPH === - +