001 (ns mw-engine.render
002 "Render a world as HTML.
003
004 Adapted (simplified) from mw-ui.render-world; this is for visualisation, not
005 interaction."
006 ;; TODO: but possibly it would be better if there is to be a newer version of
007 ;; mw-ui, to base it on this.
008 (:require [hiccup2.core :refer [html]])
009 )
010
011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
012 ;;;;
013 ;;;; This program is free software; you can redistribute it and/or
014 ;;;; modify it under the terms of the GNU General Public License
015 ;;;; as published by the Free Software Foundation; either version 2
016 ;;;; of the License, or (at your option) any later version.
017 ;;;;
018 ;;;; This program is distributed in the hope that it will be useful,
019 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
020 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
021 ;;;; GNU General Public License for more details.
022 ;;;;
023 ;;;; You should have received a copy of the GNU General Public License
024 ;;;; along with this program; if not, write to the Free Software
025 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
026 ;;;; USA.
027 ;;;;
028 ;;;; Copyright (C) 2024 Simon Brooke
029 ;;;;
030 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
031
032 (def ^:dynamic *state-images-relative-path* "img/tiles/")
033
034 (defn format-css-class
035 "Format this statekey, assumed to be a keyword indicating a state in the
036 world, into a CSS class"
037 [statekey]
038 (name statekey))
039
040 (defn format-image-path
041 "Render this statekey, assumed to be a keyword indicating a state in the
042 world, into a path which should recover the corresponding image file."
043 [statekey]
044 (format "%s%s.png" *state-images-relative-path* (format-css-class statekey)))
045
046 (defn format-mouseover [cell]
047 (str cell))
048
049 (defn render-cell
050 "Render this world cell as a Hiccup table cell."
051 [cell]
052 (let [state (:state cell)]
053 [:td {:class (format-css-class state) :title (format-mouseover cell)}
054
055 [:img {:alt (:state cell) :src (format-image-path state)}]]))
056
057
058 (defn render-world-row
059 "Render this world row as a Hiccup table row."
060 [row]
061 (apply vector (cons :tr (map render-cell row))))
062
063 (defn render-world-table
064 "Render this `world` as a complete HTML table in a DIV. If
065 `state-images-relative-path` is passed, use that to override the default path."
066 ([world]
067 [:div {:class "world"}
068 (apply vector
069 (cons :table
070 (map render-world-row world)))
071 [:p
072 (str "Generation " (:generation (first (flatten world))))]])
073 ([world state-images-relative-path]
074 (binding [*state-images-relative-path* state-images-relative-path]
075 (render-world-table world))))
076
077 (defn render-world-page
078 ([world]
079 [:html
080 [:head
081 [:title "Rendered world"]
082 [:style "div.world table, div.world table tr td {
083 padding: 0;
084 margin: 0;
085 border-collapse: collapse;
086 border: none;}"]]
087 [:body
088 (render-world-table world)]])
089 ([world state-images-relative-path]
090 (binding [*state-images-relative-path* state-images-relative-path]
091 (render-world-page world))))
092
093 (defn world->html-file
094 ([world output-path]
095 (spit output-path (str (html (render-world-page world)))))
096 ([world output-path state-images-relative-path]
097 (binding [*state-images-relative-path* state-images-relative-path]
098 (world->html-file world output-path))))