Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix loop numbering #145

Draft
wants to merge 10 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
wip
  • Loading branch information
erdos committed Dec 25, 2022
commit 6e4e915b62b0c593b7da8e6d1e583875c0991578
31 changes: 31 additions & 0 deletions src/stencil/cleanup.clj
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,39 @@
(into {} (for [[k v] @cache]
[k (count (take-while true? (apply map = (map reverse v))))]))))

;; add ::depth to ooxml/numId elements
(defn- ast-numbering-depths [ast]
(let [numid->paths (volatile! {})
numid->depth (memoize (fn [id]
(->> (get @numid->paths id)
(map reverse)
(apply map =)
(take-while true?)
(count))))]
(letfn [(visit-all [path xs] (doseq [x xs] (visit path x)))
(visit [path x]
(if (= ooxml/attr-numId (:open+close x))
(vswap! numid->paths update (-> x :attrs ooxml/val)
(fnil conj #{}) path)
(when-let [blocks (::blocks x)]
(let [path (if (= :for (:cmd x))
(cons (gensym) path) path)]
(doseq [block blocks]
(visit-all path (::children block)))))))]
(visit-all () ast))
(mapv
(partial nested-tokens-fmap-postwalk
identity identity
(fn [e]
(if (= ooxml/attr-numId (:open+close e))
(assoc e ::depth (numid->depth (-> e :attrs ooxml/val)))
e)))
ast)))


(defn process [raw-token-seq]
(let [ast (tokens->ast raw-token-seq)
ast (ast-numbering-depths ast)
executable (mapv control-ast-normalize (annotate-environments ast))]
{:variables (find-variables ast)
:fragments (find-fragments ast)
Expand Down
30 changes: 18 additions & 12 deletions src/stencil/eval.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,38 @@
[stencil.types :refer [control?]]
[stencil.tokenizer :as tokenizer]
[stencil.util :refer [eval-exception]]
[stencil.tree-postprocess :as tree-postprocess]))
[stencil.tree-postprocess :as tree-postprocess]
[stencil.ooxml :as ooxml]))

(set! *warn-on-reflection* true)

(defmulti eval-step (fn [function data item] (:cmd item)))
(defmulti eval-step (fn [function data trace item] (or (:cmd item) (:open+close item))))

(defmethod eval-step :default [_ _ item] [item])
(defmethod eval-step :default [_ _ _ item] [item])

(defn normal-control-ast->evaled-seq [data function items]
(defn normal-control-ast->evaled-seq [data function trace items]
(assert (map? data))
(assert (ifn? function))
(assert (or (nil? items) (sequential? items)))
(eduction (mapcat (partial eval-step function data)) items))
(eduction (mapcat (partial eval-step function data trace)) items))

(defn- eval-rpn* [data function expr raw-expr]
(try (eval-rpn data function expr)
(catch Exception e
(throw (eval-exception (str "Error evaluating expression: " raw-expr) e)))))

(defmethod eval-step :if [function data item]
(defmethod eval-step :if [function data trace item]
(let [condition (eval-rpn* data function (:condition item) (:raw item))]
(log/trace "Condition {} evaluated to {}" (:condition item) condition)
(->> (if condition (:branch/then item) (:branch/else item))
(normal-control-ast->evaled-seq data function))))
(normal-control-ast->evaled-seq data function trace))))

(defmethod eval-step :cmd/echo [function data item]
(defmethod eval-step :cmd/echo [function data _ item]
(let [value (eval-rpn* data function (:expression item) (:raw item))]
(log/trace "Echoing {} as {}" (:expression item) value)
[{:text (if (control? value) value (str value))}]))

(defmethod eval-step :for [function data item]
(defmethod eval-step :for [function data trace item]
(let [items (eval-rpn* data function (:expression item) (:raw item))]
(log/trace "Loop on {} will repeat {} times" (:expression item) (count items))
(if (not-empty items)
Expand All @@ -45,13 +46,18 @@
datas (if (or (instance? java.util.Map items) (map? items))
(map datamapper (keys items) (vals items))
(map-indexed datamapper items))
bodies (cons (:branch/body-run-once item) (repeat (:branch/body-run-next item)))]
(mapcat (fn [data body] (normal-control-ast->evaled-seq data function body)) datas bodies))
bodies (cons (:branch/body-run-once item) (repeat (:branch/body-run-next item)))
traces (for [i (range)] (cons i trace))]
(mapcat (fn [data body trace] (normal-control-ast->evaled-seq data function trace body)) datas bodies traces))
(:branch/body-run-none item))))

(defmethod eval-step ooxml/attr-numId [_ _ trace item]
(println :!!! item)
[item])

(defn eval-executable [part data functions]
(->> (:executable part)
(#(doto % assert))
(normal-control-ast->evaled-seq data functions)
(normal-control-ast->evaled-seq data functions ())
(tokenizer/tokens-seq->document)
(tree-postprocess/postprocess)))
3 changes: 2 additions & 1 deletion src/stencil/model.clj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
{:source-file cts
::path (.getName cts)})

#_
(defn- add-unique-index
"Annotates some elements with an unique id.
These elements need special care when rendering duplicates them.
Expand All @@ -64,7 +65,7 @@
(defn ->exec [xml-streamable]
(with-open [stream (io/input-stream xml-streamable)]
(-> (merger/parse-to-tokens-seq stream)
(->> (map (some-fn add-unique-index identity)))
;(->> (map (some-fn add-unique-index identity)))
(cleanup/process)
(select-keys [:variables :dynamic? :executable :fragments]))))

Expand Down