Browse Source

feat(dynamic-variables): add dynamic variables to both templates

and macros.
Tienson Qin 4 years ago
parent
commit
150953fcb8

+ 1 - 0
package.json

@@ -57,6 +57,7 @@
     },
     "dependencies": {
         "chokidar": "^3.5.1",
+        "chrono-node": "^2.2.1",
         "codemirror": "^5.58.1",
         "diff": "5.0.0",
         "diff-match-patch": "^1.0.5",

+ 6 - 2
src/main/frontend/components/block.cljs

@@ -838,11 +838,15 @@
                                (get (state/get-macros) (keyword name)))
                 macro-content (if (and (seq arguments) macro-content)
                                 (block/macro-subs macro-content arguments)
-                                macro-content)]
+                                macro-content)
+                macro-content (when macro-content
+                                (editor-handler/resolve-dynamic-template! macro-content))]
             (render-macro config name arguments macro-content format))
 
           (when-let [macro-txt (macro->text name arguments)]
-            (let [format (get-in config [:block :block/format] :markdown)]
+            (let [macro-txt (when macro-txt
+                              (editor-handler/resolve-dynamic-template! macro-txt))
+                  format (get-in config [:block :block/format] :markdown)]
               (render-macro config name arguments macro-txt format))))))
 
     :else

+ 2 - 1
src/main/frontend/components/editor.cljs

@@ -218,7 +218,8 @@
                                                 (text/rejoin-properties properties')))))
                                        content (if (string/includes? (string/trim edit-content) "\n")
                                                  content
-                                                 (text/remove-level-spaces content format))]
+                                                 (text/remove-level-spaces content format))
+                                       content (editor-handler/resolve-dynamic-template! content)]
                                    (state/set-editor-show-template-search! false)
                                    (editor-handler/insert-command! id
                                                                    content

+ 7 - 1
src/main/frontend/date.cljs

@@ -7,7 +7,13 @@
             [cljs-bean.core :as bean]
             [frontend.util :as util]
             [clojure.string :as string]
-            [goog.object :as gobj]))
+            [goog.object :as gobj]
+            ["chrono-node" :as chrono]))
+
+(defn nld-parse
+  [s]
+  (when (string? s)
+    ((gobj/get chrono "parseDate") s)))
 
 (defn format
   [date]

+ 41 - 13
src/main/frontend/handler/editor.cljs

@@ -294,8 +294,8 @@
                                 (reset! last-child-end-pos old-end-pos)))
 
                             (cond->
-                             {:block/uuid uuid
-                              :block/meta new-meta}
+                                {:block/uuid uuid
+                                 :block/meta new-meta}
                               (and (some? indent-left?) (not @next-leq-level?))
                               (assoc :block/level (if indent-left? (dec level) (inc level)))
                               (and new-content (not @next-leq-level?))
@@ -448,10 +448,10 @@
                                       :page/original-name tag}) tags))
          page-alias (when-let [alias (:alias new-properties)]
                       (map
-                       (fn [alias]
-                         {:page/original-name alias
-                          :page/name (string/lower-case alias)})
-                       (remove #{(:page/name page)} alias)))
+                        (fn [alias]
+                          {:page/original-name alias
+                           :page/name (string/lower-case alias)})
+                        (remove #{(:page/name page)} alias)))
 
          permalink-changed? (when (and pre-block? (:permalink old-properties))
                               (not= (:permalink old-properties)
@@ -508,8 +508,8 @@
                  ;; create the file
                  (let [value (block-text-with-time nil format value)
                        content (str (util/default-content-with-title format
-                                      (or (:page/original-name page)
-                                          (:page/name page)))
+                                                                     (or (:page/original-name page)
+                                                                         (:page/name page)))
                                     value)]
                    (p/let [_ (fs/create-if-not-exists repo dir file-path content)
                            _ (git-handler/git-add repo path)]
@@ -1168,7 +1168,7 @@
                                                (if (string/starts-with? (string/lower-case line) key)
                                                  new-line
                                                  line))
-                                             lines)
+                                          lines)
                               new-lines (if (not= lines new-lines)
                                           new-lines
                                           (cons (first new-lines) ;; title
@@ -1561,7 +1561,7 @@
             ext (if ext (subs ext (string/last-index-of ext ".")) "")
             filename (str (gen-filename index file) ext)
             filename (str path "/" filename)]
-        ;(js/console.debug "Write asset #" dir filename file)
+                                        ;(js/console.debug "Write asset #" dir filename file)
         (if (util/electron?)
           (let [from (.-path file)]
             (p/then (js/window.apis.copyFileToAssets dir filename from)
@@ -1676,7 +1676,7 @@
    ;; "_" "_"
    ;; ":" ":"                              ; TODO: only properties editing and org mode tag
    ;; "^" "^"
-})
+   })
 
 (def reversed-autopair-map
   (zipmap (vals autopair-map)
@@ -2030,7 +2030,7 @@
                                                                 :end-pos end-pos}))]
                                  (reset! last-start-pos end-pos)
                                  block))
-                             blocks))
+                          blocks))
                 file-id (:db/id (:block/file block))
                 file (db/entity file-id)
                 page (:block/page block)
@@ -2097,7 +2097,7 @@
                                                               :end-pos end-pos}))]
                                (reset! last-start-pos end-pos)
                                block))
-                           blocks))
+                        blocks))
               file-id (:db/id (:block/file block))
               file (db/entity file-id)
               page (:block/page block)
@@ -2244,3 +2244,31 @@
         value (:block/content block)
         new-value (string/replace value full_text new-full-text)]
     (save-block-aux! block new-value (:block/format block) {})))
+
+(defn variable-rules
+  []
+  {"today" (util/format "[[%s]]" (date/today))
+   "yesterday" (util/format "[[%s]]" (date/yesterday))
+   "tomorrow" (util/format "[[%s]]" (date/tomorrow))
+   "time" (date/get-current-time)
+   "current page" (util/format "[[%s]]"
+                               (or (state/get-current-page)
+                                   (date/today)))})
+
+;; TODO: programmable
+;; context information, date, current page
+(defn resolve-dynamic-template!
+  [content]
+  (string/replace content #"<%([^%].*?)%>"
+                  (fn [[_ match]]
+                    (let [match (string/trim match)]
+                      (cond
+                       (string/blank? match)
+                       ""
+                       (get (variable-rules) (string/lower-case match))
+                       (get (variable-rules) (string/lower-case match))
+                       :else
+                       (if-let [nld (date/nld-parse match)]
+                         (let [date (tc/to-local-date-time nld)]
+                           (util/format "[[%s]]" (date/journal-name date)))
+                         match))))))

+ 12 - 0
yarn.lock

@@ -1112,6 +1112,13 @@ chokidar@^3.5.1:
   optionalDependencies:
     fsevents "~2.3.1"
 
+chrono-node@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/chrono-node/-/chrono-node-2.2.1.tgz#6591c95724011fd7cadd8ae394bacb5004357bf2"
+  integrity sha512-Cdw4LxAlVb3BbfoAIw50v8MhVmFGBzzvTpQUO3F5ezyo/MnZ3db3G73cHNE2aiNsAhK9qpg39RpUl6jxTIUGeA==
+  dependencies:
+    dayjs "^1.10.0"
+
 cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
@@ -1616,6 +1623,11 @@ d@1, d@^1.0.1:
     es5-ext "^0.10.50"
     type "^1.0.1"
 
+dayjs@^1.10.0:
+  version "1.10.4"
+  resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2"
+  integrity sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==
+
 debug@^2.2.0, debug@^2.3.3, debug@^2.6.9:
   version "2.6.9"
   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"