diff --git a/README.md b/README.md index 9bc7a1a5..7414f3ab 100644 --- a/README.md +++ b/README.md @@ -45,9 +45,9 @@ The project has a simple [service implementation](https://github.com/erdos/stenc ## Version -**Latest stable** version is `0.5.6` +**Latest stable** version is `0.5.7` -**Latest snapshot** version is `0.5.7-SNAPSHOT` +**Latest snapshot** version is `0.5.8-SNAPSHOT` If you are using Maven, add the followings to your `pom.xml`: @@ -57,7 +57,7 @@ The dependency: io.github.erdos stencil-core - 0.5.6 + 0.5.7 ``` @@ -72,7 +72,7 @@ And the [Clojars](https://clojars.org) repository: Alternatively, if you are using Leiningen, add the following to the `:dependencies` section of your `project.clj` -file: `[io.github.erdos/stencil-core "0.5.6"]` +file: `[io.github.erdos/stencil-core "0.5.7"]` Previous versions are available on the [Stencil Clojars](https://clojars.org/io.github.erdos/stencil-core) page. diff --git a/java-src/io/github/erdos/stencil/impl/Logging.java b/java-src/io/github/erdos/stencil/impl/Logging.java deleted file mode 100644 index 9bbf0966..00000000 --- a/java-src/io/github/erdos/stencil/impl/Logging.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.github.erdos.stencil.impl; - -import org.slf4j.Logger; - -import java.util.concurrent.atomic.AtomicLong; -import java.util.function.Consumer; -import java.util.function.Supplier; - -/** - * Logging support - */ -@SuppressWarnings("WeakerAccess") -public final class Logging { - - private Logging() {} - - /** - * Returns a consumer that can be used to print elapsed time. - */ - public static Consumer> debugStopWatch(Logger logger) { - AtomicLong lastMeasure = new AtomicLong(0); - return msg -> { - long now = System.currentTimeMillis(); - long previous = lastMeasure.getAndSet(now); - - if (previous == 0) { - logger.debug(msg.get()); - } else - logger.debug(msg.get(), now - previous); - }; - } -} diff --git a/project.clj b/project.clj index ede879f7..d6707a20 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject io.github.erdos/stencil-core "0.5.7-SNAPSHOT" +(defproject io.github.erdos/stencil-core "0.5.8-SNAPSHOT" :url "https://github.com/erdos/stencil" :description "Templating engine for office documents." :license {:name "Eclipse Public License - v 2.0" diff --git a/service/project.clj b/service/project.clj index 6eb31683..cd325fb2 100644 --- a/service/project.clj +++ b/service/project.clj @@ -1,10 +1,10 @@ -(defproject io.github.erdos/stencil-service "0.5.7-SNAPSHOT" +(defproject io.github.erdos/stencil-service "0.5.8-SNAPSHOT" :description "Web service for the Stencil templating engine" :url "https://github.com/erdos/stencil" :license {:name "Eclipse Public License - v 2.0" :url "https://www.eclipse.org/legal/epl-2.0/"} :dependencies [[org.clojure/clojure "1.11.1"] - [io.github.erdos/stencil-core "0.5.7-SNAPSHOT"] + [io.github.erdos/stencil-core "0.5.8-SNAPSHOT"] [org.slf4j/slf4j-api "2.0.0-alpha7"] [org.mozilla/rhino-engine "1.7.14"] [http-kit "2.5.0"] diff --git a/src/stencil/cleanup.clj b/src/stencil/cleanup.clj index 59a1172c..b5cce0db 100644 --- a/src/stencil/cleanup.clj +++ b/src/stencil/cleanup.clj @@ -110,11 +110,7 @@ ;; Itt nincsen blokk, amit normalizálni kellene (defmethod control-ast-normalize :cmd/echo [echo-command] echo-command) -(defmethod control-ast-normalize :cmd/include [include-command] - (if-not (string? (:name include-command)) - (throw (parsing-exception (pr-str (:name include-command)) - "Parameter of include call must be a single string literal!")) - include-command)) +(defmethod control-ast-normalize :cmd/include [include-command] include-command) ;; A feltételes elágazásoknál mindig generálunk egy javított THEN ágat (defmethod control-ast-normalize :if [control-ast] @@ -188,6 +184,7 @@ (collect-1 [mapping x] (case (:cmd x) :cmd/echo (expr mapping (:expression x)) + :cmd/include (expr mapping (:name x)) :if (concat (expr mapping (:condition x)) (collect mapping (apply concat (::blocks x)))) @@ -205,7 +202,8 @@ ;; returns a set of fragment names use in this document (set (for [item (tree-seq map? (comp flatten ::blocks) {::blocks [control-ast]}) :when (map? item) - :when (= :cmd/include (:cmd item))] + :when (= :cmd/include (:cmd item)) + :when (string? (:name item))] (:name item)))) (defn process [raw-token-seq] diff --git a/src/stencil/model.clj b/src/stencil/model.clj index df8f4e49..53a88088 100644 --- a/src/stencil/model.clj +++ b/src/stencil/model.clj @@ -6,6 +6,7 @@ (:require [clojure.data.xml :as xml] [clojure.java.io :as io :refer [file]] [stencil.eval :as eval] + [stencil.infix :refer [eval-rpn]] [stencil.merger :as merger] [stencil.types :refer [->FragmentInvoke]] [stencil.util :refer [unlazy-tree eval-exception]] @@ -193,32 +194,31 @@ ; (xml-map-attrs {ooxml/r-embed id-rename ooxml/r-id id-rename} item)) -(defmethod eval/eval-step :cmd/include [function local-data-map {frag-name :name}] +(defmethod eval/eval-step :cmd/include [function local-data-map step] (assert (map? local-data-map)) - (assert (string? frag-name)) - (do - (if-let [fragment-model (get *all-fragments* frag-name)] - (let [;; merge style definitions from fragment - style-ids-rename (-> fragment-model :main :style :parsed (doto assert) (style/insert-styles!)) + (let [frag-name (eval-rpn local-data-map function (:name step))] + (if-let [fragment-model (get *all-fragments* frag-name)] + (let [;; merge style definitions from fragment + style-ids-rename (-> fragment-model :main :style :parsed (doto assert) (style/insert-styles!)) - relation-ids-rename (relations/ids-rename fragment-model frag-name) - relation-rename-map (into {} (map (juxt :old-id :new-id)) relation-ids-rename) + relation-ids-rename (relations/ids-rename fragment-model frag-name) + relation-rename-map (into {} (map (juxt :old-id :new-id)) relation-ids-rename) ;; evaluate - evaled (eval-template-model fragment-model local-data-map function {}) + evaled (eval-template-model fragment-model local-data-map function {}) ;; write back - get-xml (fn [x] (or (:xml x) @(:xml-delay x))) - evaled-parts (->> evaled :main :result - (get-xml) - (extract-body-parts) - (map (partial relations/xml-rename-relation-ids relation-rename-map)) - (map (partial xml-map-attrs - {ooxml/attr-numId - (partial numbering/copy-numbering fragment-model (atom {}))})) - (map (partial style/xml-rename-style-ids style-ids-rename)) - (doall))] - (swap! *inserted-fragments* conj frag-name) - (run! relations/add-extra-file! relation-ids-rename) - [{:text (->FragmentInvoke {:frag-evaled-parts evaled-parts})}]) - (throw (eval-exception (str "No fragment for name: " frag-name) nil))))) + get-xml (fn [x] (or (:xml x) @(:xml-delay x))) + evaled-parts (->> evaled :main :result + (get-xml) + (extract-body-parts) + (map (partial relations/xml-rename-relation-ids relation-rename-map)) + (map (partial xml-map-attrs + {ooxml/attr-numId + (partial numbering/copy-numbering fragment-model (atom {}))})) + (map (partial style/xml-rename-style-ids style-ids-rename)) + (doall))] + (swap! *inserted-fragments* conj frag-name) + (run! relations/add-extra-file! relation-ids-rename) + [{:text (->FragmentInvoke {:frag-evaled-parts evaled-parts})}]) + (throw (eval-exception (str "No fragment for name: " frag-name) nil))))) diff --git a/src/stencil/process.clj b/src/stencil/process.clj index 2c766ea4..2de7553b 100644 --- a/src/stencil/process.clj +++ b/src/stencil/process.clj @@ -6,7 +6,8 @@ [io.github.erdos.stencil.impl FileHelper ZipHelper]) (:require [clojure.java.io :as io] [stencil.log :as log] - [stencil.model :as model])) + [stencil.model :as model] + [stencil.model.common :refer [unix-path]])) (set! *warn-on-reflection* true) @@ -65,7 +66,7 @@ (io! (with-open [zipstream (new ZipOutputStream outstream)] (doseq [[k writer] writers-map - :let [rel-path (FileHelper/toUnixSeparatedString (.toPath (io/file k))) + :let [rel-path (unix-path (io/file k)) ze (new ZipEntry rel-path)]] (assert (not (.contains rel-path "../"))) (log/trace "ZIP: writing {}" rel-path) diff --git a/test/stencil/errors.clj b/test/stencil/errors.clj index d8d05207..042536ae 100644 --- a/test/stencil/errors.clj +++ b/test/stencil/errors.clj @@ -43,12 +43,6 @@ (throw-ex-parsing? "{%for x in xs%}a"))) -(deftest test-wrong-include - (testing "Unexpected value in inlude tag" - (throw-ex-parsing? "{% include header %}") - (throw-ex-parsing? "{% include a+1 %}"))) - - (deftest test-not-closed (testing "Expressions are not closed properly" (throw-ex-parsing? "{%=") diff --git a/test/stencil/process_test.clj b/test/stencil/process_test.clj index 1c738414..d495ffc1 100644 --- a/test/stencil/process_test.clj +++ b/test/stencil/process_test.clj @@ -33,4 +33,12 @@ {:close :a}], :fragments #{"elefant"} :variables ()} - (test-prepare "{%include \"elefant\"%}"))))) + (test-prepare "{%include \"elefant\"%}")))) + (testing "Fragment invocation is a dynamic expression" + (is (= {:dynamic? true, + :executable [{:open :a} + {:stencil.cleanup/blocks [], :cmd :cmd/include, :name 'valtozo :raw "{%include valtozo%}"} + {:close :a}], + :fragments #{} + :variables '("valtozo")} + (test-prepare "{%include valtozo%}")))))