~subsetpark/bagatto

f5c14aa448995f5cc934507b1264eda68305fc47 — Zach Smith 10 months ago 26e05cd
Add root to paths in demo
M demo/index.janet => demo/index.janet +2 -2
@@ 117,7 117,7 @@
# function. It returns a function that will take the site data and a
# post and call `bagatto/render` on the specified template, with the
# site and the post as arguments.
(def render-post (bagatto/renderer "templates/post"))
(def render-post (bagatto/renderer "templates/post" {:root "../.."}))
                
# The Posts index is generated from the site data and lists out all
# the posts. Therefore, it isn't rendered out of a specific source


@@ 129,7 129,7 @@
# accept only one argument---just the site data---without any specific
# item being rendered. The only difference will be that the `:_item`
# attribute won't be available in the template.
(def render-post-index (bagatto/renderer "templates/posts"))
(def render-post-index (bagatto/renderer "templates/posts" {:root ".."}))

# Likewise, our `site` struct has three entries---there doesn't have
# to be any clean mapping between entries in `data` and entries in

M demo/templates/base_bottom.temple => demo/templates/base_bottom.temple +1 -1
@@ 1,6 1,6 @@
        </div>
{$ (import hypertext) $}
{$ (def dest index-path) $}
{% (def dest (path/join (args :root) index-path)) %}
{% (print (hypertext/markup (li (a :href dest "All posts")))) %}
  </body>
</html>

M demo/templates/posts.temple => demo/templates/posts.temple +1 -1
@@ 35,7 35,7 @@

<ul>
{% (loop [post :in (args :posts)]
     (def dest (-> (make-post-path args post)))
     (def dest (path/join (args :root) (make-post-path args post)))
     (print (hypertext/markup
            (li (a :href dest
                   [(post :title)]))))) %}

M main.janet => main.janet +23 -21
@@ 2,6 2,7 @@
(import argparse :prefix "")

(import src/core)
(import src/error)

(def bagatto
  ```


@@ 13,7 14,7 @@
# Monkey-patch the temple environment with our additional functions.
(merge-into temple/base-env bagatto)

(defn load-file [index]
(defn- load-file 
  ```
  Given the filename of our index module, evaluate it in the execution
  environment with our "stdlib" in it. This will give index module


@@ 22,17 23,24 @@
  those libraries having to be present when the index module is
  written).
  ```
  [index]
  (temple/add-loader)
  (dofile index :env bagatto))


(defn- index-value
  [env sym index]
  (try ((env sym) :value)
       ([err fib] (error/eval-error sym index))))

(def argparse-params ["A transparent, extensible static site generator."
                      "repl" {:kind :flag :help "Compile your index module and enter the REPL."}
                      :default {:kind :option :help "The index module to evaluate." :required true} ])
                      "repl" {:kind :flag
                              :help "Compile your index module and enter the REPL."}
                      :default {:kind
                                :option
                                :help "The index module to evaluate."
                                :required true}])

(defn main [& args]
  
  (match (os/getenv "JANET_PATH")
    nil :ok
    janet-path (put root-env :syspath janet-path))


@@ 40,6 48,8 @@
  (let [args (argparse ;argparse-params)
        index (args :default)
        env (load-file index)]
    # Monkey-patch the temple environment with the functions defined
    # in the index module.
    (merge-into temple/base-env env)

    (if (args "repl")


@@ 48,21 58,13 @@
      (repl nil nil env)
      # Normal mode: evaluate index module and write site.
      (do
        (defn value
          [sym]
          (try ((env sym) :value)
               ([err fib]
                (error
                 (string "Expected symbol "
                         sym
                         "; couldn't be found after evaluating "
                         index)))))
    
        (setdyn :bagatto-defaults (env :bagatto-defaults))

        (let [data-spec (value 'data)
              data (core/load-data data-spec)
              site (value 'site)
              writer-specs (core/produce-writer-specs site data)
              writers (core/produce-writers writer-specs)]
          (core/resume-writers writers))))))
        (def data (let [data-spec (index-value env 'data index)]
                    (core/load-data data-spec)))
        (def writer-specs (let [site-spec (index-value env 'site index)]
                            (core/produce-writer-specs site-spec data)))

        (-> writer-specs
           (core/produce-writers)
           (core/resume-writers))))))

M src/core.janet => src/core.janet +13 -15
@@ 6,8 6,6 @@
(defn- struct->table [s]
  (->> (or s @{}) (kvs) (splice) (table)))



(defn- maybe-apply [f args args-type ret-type]
  (if (function? f)
    (try


@@ 19,7 17,7 @@
  (table/setproto (struct->table spec)
                  (struct->table (dyn :bagatto-defaults))))

(defn load-data [data-spec]
(defn load-data
  ```
  First phase of main business logic. `data-spec` contains a
  specification of all the sources necessary to generate our `attrs`


@@ 40,6 38,7 @@
  finite number of [filename file-contents] tuples, and an :attrs
  function that will be called on each file-contents.
  ```
  [data-spec]
  (def res @{})
  
  (defn make-attrs [filename &opt file-contents parser]


@@ 49,19 48,19 @@
           (parser file-contents))
      ([err fib] (error/attrs-error err parser))))
  
  (loop [[entry spec] :pairs data-spec]
  (loop [[spec-name spec] :pairs data-spec]
    (let [with-defaults (set-defaults spec)
          transform-f (or (spec :transform) identity)
          data (match with-defaults
                 
                 ({:src loader :attrs parser} (fiber? loader))
                 (-> (seq [loader-out :generate loader]
                          (match loader-out
                            [filename file-contents]
                            (make-attrs filename file-contents parser)
                            filename
                            (make-attrs filename)))
                     (transform-f))
                         (match loader-out
                           [filename file-contents]
                           (make-attrs filename file-contents parser)
                           filename
                           (make-attrs filename)))
                    (transform-f))
                 
                 ({:src loader :attrs parser} (function? loader))
                 (let [[filename file-contents] (loader)]


@@ 75,26 74,26 @@
                 attrs
                 
                 _ (error/data-error with-defaults))]
      (put res entry data)))
      (put res spec-name data)))
  res)

(defn produce-writer-specs [site data]
(defn produce-writer-specs 
  ```
  Second phase of main business logic. `site` contains a specification
  for generating a website and `data` is all the source data we have to
  do it with. Here we generate a new writer fiber for each file in the
  website.
  ```
  [site data]
  (def writers @[])
  
  (defn push-writer [type path contents]
    (array/push writers [type path contents]))
  
  (loop [[_entry spec] :pairs site]
  (loop [[_spec-name spec] :pairs site]
    (let [with-defaults (set-defaults spec)
          filter (spec :filter)]
      (default filter (fn [_site _item] true))
      
      (match with-defaults
        
        {:each site-selector


@@ 144,7 143,6 @@
                      (print to)
                      (util/mkpath ppath)
                      (util/copy-file from to))))]
  
    (fiber/new (fn [] (f x y))))) 

(defn produce-writers [specs] (seq [spec :in specs] (new-writer ;spec)))

M src/error.janet => src/error.janet +5 -0
@@ 1,5 1,10 @@
(defn- f-name [f] (or (disasm f :name) "f"))

(defn eval-error
  [sym filename]
  (error
   (string "Expected symbol " sym "; couldn't be found after evaluating " filename)))

(defn path-content-error
  [err f args-type ret-type]
  (error (string/format