mirror of
https://github.com/journeyman-cc/smeagol.git
synced 2026-04-12 18:05:06 +00:00
#13 WOW! It works! And it's beautiful!
This commit is contained in:
parent
a1fa392699
commit
fa944f1780
11 changed files with 498 additions and 159 deletions
210
README.md
210
README.md
|
|
@ -1,91 +1,119 @@
|
||||||

|

|
||||||
|
|
||||||
# Welcome to Smeagol!
|
# Welcome to Smeagol!
|
||||||
Smeagol is a simple Wiki engine inspired by [Gollum](https://github.com/gollum/gollum/wiki). Gollum is a Wiki engine written in Ruby, which uses a number of simple text formats including [Markdown](http://daringfireball.net/projects/markdown/), and which uses [Git](http://git-scm.com/) to provide versioning and backup. I needed a new Wiki for a project and thought Gollum would be ideal - but unfortunately it doesn't provide user authentication, which I needed, and it was simpler for me to reimplement the bits I did need in Clojure than to modify Gollum.
|
Smeagol is a simple Wiki engine inspired by [Gollum](https://github.com/gollum/gollum/wiki). Gollum is a Wiki engine written in Ruby, which uses a number of simple text formats including [Markdown](http://daringfireball.net/projects/markdown/), and which uses [Git](http://git-scm.com/) to provide versioning and backup. I needed a new Wiki for a project and thought Gollum would be ideal - but unfortunately it doesn't provide user authentication, which I needed, and it was simpler for me to reimplement the bits I did need in Clojure than to modify Gollum.
|
||||||
|
|
||||||
So at this stage Smeagol is a Wiki engine written in Clojure which uses Markdown as its text format, which does have user authentication, and which uses Git as its versioning and backup system.
|
So at this stage Smeagol is a Wiki engine written in Clojure which uses Markdown as its text format, which does have user authentication, and which uses Git as its versioning and backup system.
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
Smeagol is now a fully working small Wiki engine, and meets my own immediate needs.
|
Smeagol is now a fully working small Wiki engine, and meets my own immediate needs.
|
||||||
|
|
||||||
## Markup syntax
|
## Markup syntax
|
||||||
Smeagol uses the Markdown format as provided by [markdown-clj](https://github.com/yogthos/markdown-clj), with the addition that anything enclosed in double square brackets, \[\[like this\]\], will be treated as a link into the wiki itself.
|
Smeagol uses the Markdown format as provided by [markdown-clj](https://github.com/yogthos/markdown-clj), with the addition that anything enclosed in double square brackets, \[\[like this\]\], will be treated as a link into the wiki itself.
|
||||||
|
|
||||||
## Security and authentication
|
## Security and authentication
|
||||||
Security is now greatly improved. There is a file called *passwd* in the *resources* directory, which contains a clojure map which maps usernames to maps with plain-text passwords and emails thus:
|
Security is now greatly improved. There is a file called *passwd* in the *resources* directory, which contains a clojure map which maps usernames to maps with plain-text passwords and emails thus:
|
||||||
|
|
||||||
{:admin {:password "admin" :email "admin@localhost" :admin true}
|
{:admin {:password "admin" :email "admin@localhost" :admin true}
|
||||||
:adam {:password "secret" :email "adam@localhost"}}
|
:adam {:password "secret" :email "adam@localhost"}}
|
||||||
|
|
||||||
that is to say, the username is a keyword and the corresponding password is a string. However, since version 0.5.0, users can now change their own passwords, and when the user changes their password their new password is encrypted using the [scrypt](http://www.tarsnap.com/scrypt.html) one-way encryption scheme. The password file is now no longer either in the *resources/public* directory so cannot be downloaded through the browser, nor in the git archive to which the Wiki content is stored, so that even if that git archive is remotely clonable an attacker cannot get the password file that way.
|
that is to say, the username is a keyword and the corresponding password is a string. However, since version 0.5.0, users can now change their own passwords, and when the user changes their password their new password is encrypted using the [scrypt](http://www.tarsnap.com/scrypt.html) one-way encryption scheme. The password file is now no longer either in the *resources/public* directory so cannot be downloaded through the browser, nor in the git archive to which the Wiki content is stored, so that even if that git archive is remotely clonable an attacker cannot get the password file that way.
|
||||||
|
|
||||||
## Images
|
## Images
|
||||||
Smeagol does not currently have any mechanism to upload images. You can, however, link to images already available on the web, like this:
|
Smeagol does not currently have any mechanism to upload images. You can, however, link to images already available on the web, like this:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Todo
|
## Now with data visualisation
|
||||||
* Mechanism to add users through the user interface;
|
|
||||||
|
Inspired by [visdown](http://visdown.amitkaps.com/) and [vega-lite](https://vega.github.io/vega-lite/docs/), you can now embed visualisations into Smeagol pages, like this:
|
||||||
## Advertisement
|
|
||||||
If you like what you see here, I am available for work on open source Clojure projects. Contact me via [WEFT](http://www.weft.scot/).
|
### Flight punctuality at London airports
|
||||||
|
|
||||||
### Phoning home
|
Example cribbed in its entirety from [here](http://visdown.amitkaps.com/london):
|
||||||
Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file
|
```vis
|
||||||
|
data:
|
||||||
resources/templates/base.html
|
url: "data/london.csv"
|
||||||
|
transform:
|
||||||
and replace the line
|
-
|
||||||
|
filter: datum.year == 2016
|
||||||
<img height="16" width="16" alt="The Web Engineering Factory & Toolworks" src="http://www.weft.scot/images/weft.logo.64.png"> Developed by <a href="http://www.weft.scot/">WEFT</a>
|
mark: rect
|
||||||
|
encoding:
|
||||||
with the line
|
x:
|
||||||
|
type: nominal
|
||||||
<img height="16" width="16" alt="The Web Engineering Factory & Toolworks" src="img/weft.logo.64.png"> Developed by <a href="http://www.weft.scot/">WEFT</a>
|
field: source
|
||||||
|
y:
|
||||||
## License
|
type: nominal
|
||||||
Copyright © 2014-2015 Simon Brooke. Licensed under the GNU General Public License,
|
field: dest
|
||||||
version 2.0 or (at your option) any later version. If you wish to incorporate
|
color:
|
||||||
parts of Smeagol into another open source project which uses a less restrictive
|
type: quantitative
|
||||||
license, please contact me; I'm open to dual licensing it.
|
field: flights
|
||||||
|
aggregate: sum
|
||||||
## Prerequisites
|
```
|
||||||
You will need [Leiningen](https://github.com/technomancy/leiningen) 2.0 or above installed.
|
|
||||||
|
Note that this visualisation will not be rendered in the GitHub wiki, as it doesn't have Smeagol's data visualisation magic. This is what it should look like:
|
||||||
You will need [node](https://nodejs.org/en/) and [bower](https://bower.io/) installed.
|
|
||||||
|

|
||||||
## Running
|
|
||||||
To start a web server for the application, run:
|
## Advertisement
|
||||||
|
If you like what you see here, I am available for work on open source Clojure projects.
|
||||||
lein bower install
|
|
||||||
lein ring server
|
### Phoning home
|
||||||
|
Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file
|
||||||
Alternatively, if you want to deploy to a servlet container (which I would strongly recommend), the simplest thing is to run:
|
|
||||||
|
resources/templates/base.html
|
||||||
lein bower install
|
|
||||||
lein ring uberwar
|
and replace the line
|
||||||
|
|
||||||
(a command which I'm sure Smeagol would entirely appreciate) and deploy the resulting war file.
|
<img height="16" width="16" alt="The Web Engineering Factory & Toolworks" src="http://www.weft.scot/images/weft.logo.64.png"> Developed by <a href="http://www.weft.scot/">WEFT</a>
|
||||||
|
|
||||||
## Experimental Docker image
|
with the line
|
||||||
|
|
||||||
You can now run Smeagol as a [Docker](http://www.docker.com) image. To run my Docker image, use
|
<img height="16" width="16" alt="The Web Engineering Factory & Toolworks" src="img/weft.logo.64.png"> Developed by <a href="http://www.weft.scot/">WEFT</a>
|
||||||
|
|
||||||
docker run simonbrooke/smeagol
|
## License
|
||||||
|
Copyright © 2014-2015 Simon Brooke. Licensed under the GNU General Public License,
|
||||||
Smeagol will run, obviously, on the IP address of your Docker image, on port 8080. To find the IP address, start the image using the command above and then use
|
version 2.0 or (at your option) any later version. If you wish to incorporate
|
||||||
|
parts of Smeagol into another open source project which uses a less restrictive
|
||||||
docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(docker ps -q)
|
license, please contact me; I'm open to dual licensing it.
|
||||||
|
|
||||||
Suppose this prints '10.10.10.10', then the URL to browse to will be http://10.10.10.10:8080/smeagol/
|
## Prerequisites
|
||||||
|
You will need [Leiningen](https://github.com/technomancy/leiningen) 2.0 or above installed.
|
||||||
This image is _experimental_, but it does seem to work fairly well. What it does **not** yet do, however, is push the git repository to a remote location, so when you tear the Docker image down your edits will be lost. My next objective for this image is for it to have a cammand line parameter being the git address of a repository from which it can initialise the Wiki content, and to which it will periodically push local changes to the Wiki content.
|
|
||||||
|
You will need [node](https://nodejs.org/en/) and [bower](https://bower.io/) installed.
|
||||||
To build your own Docker image, run:
|
|
||||||
|
## Running
|
||||||
lein clean
|
To start a web server for the application, run:
|
||||||
lein bower install
|
|
||||||
lein ring uberwar
|
lein bower install
|
||||||
lein docker build
|
lein ring server
|
||||||
|
|
||||||
This will build a new Docker image locally; you can, obviously, push it to your own Docker repository if you wish.
|
Alternatively, if you want to deploy to a servlet container (which I would strongly recommend), the simplest thing is to run:
|
||||||
|
|
||||||
|
lein bower install
|
||||||
|
lein ring uberwar
|
||||||
|
|
||||||
|
(a command which I'm sure Smeagol would entirely appreciate) and deploy the resulting war file.
|
||||||
|
|
||||||
|
## Experimental Docker image
|
||||||
|
|
||||||
|
You can now run Smeagol as a [Docker](http://www.docker.com) image. To run my Docker image, use
|
||||||
|
|
||||||
|
docker run simonbrooke/smeagol
|
||||||
|
|
||||||
|
Smeagol will run, obviously, on the IP address of your Docker image, on port 8080. To find the IP address, start the image using the command above and then use
|
||||||
|
|
||||||
|
docker inspect --format '{{ .NetworkSettings.IPAddress }}' $(docker ps -q)
|
||||||
|
|
||||||
|
Suppose this prints '10.10.10.10', then the URL to browse to will be http://10.10.10.10:8080/smeagol/
|
||||||
|
|
||||||
|
This image is _experimental_, but it does seem to work fairly well. What it does **not** yet do, however, is push the git repository to a remote location, so when you tear the Docker image down your edits will be lost. My next objective for this image is for it to have a cammand line parameter being the git address of a repository from which it can initialise the Wiki content, and to which it will periodically push local changes to the Wiki content.
|
||||||
|
|
||||||
|
To build your own Docker image, run:
|
||||||
|
|
||||||
|
lein clean
|
||||||
|
lein bower install
|
||||||
|
lein ring uberwar
|
||||||
|
lein docker build
|
||||||
|
|
||||||
|
This will build a new Docker image locally; you can, obviously, push it to your own Docker repository if you wish.
|
||||||
|
|
|
||||||
36
project.clj
36
project.clj
|
|
@ -1,30 +1,30 @@
|
||||||
(defproject smeagol "0.5.0-rc3"
|
(defproject smeagol "0.5.1-SNAPSHOT"
|
||||||
:description "A simple Git-backed Wiki inspired by Gollum"
|
:description "A simple Git-backed Wiki inspired by Gollum"
|
||||||
:url "https://github.com/simon-brooke/smeagol"
|
:url "https://github.com/simon-brooke/smeagol"
|
||||||
:dependencies [[org.clojure/clojure "1.7.0"]
|
:dependencies [[org.clojure/clojure "1.8.0"]
|
||||||
[org.clojure/core.memoize "0.5.9"]
|
[org.clojure/core.memoize "0.5.9"]
|
||||||
[com.taoensso/encore "2.91.1"]
|
[org.clojure/data.json "0.2.6"]
|
||||||
[lib-noir "0.9.9" :exclusions [org.clojure/tools.reader]]
|
|
||||||
[com.cemerick/url "0.1.1"]
|
|
||||||
[ring-server "0.4.0"]
|
|
||||||
[selmer "1.10.9"]
|
|
||||||
|
|
||||||
[org.clojure/tools.logging "0.4.0"]
|
[org.clojure/tools.logging "0.4.0"]
|
||||||
[com.taoensso/timbre "4.10.0"]
|
[clj-jgit "0.8.9"]
|
||||||
|
[clj-yaml "0.4.0"]
|
||||||
|
[com.cemerick/url "0.1.1"]
|
||||||
[com.fzakaria/slf4j-timbre "0.3.7"]
|
[com.fzakaria/slf4j-timbre "0.3.7"]
|
||||||
|
[com.taoensso/encore "2.91.1"]
|
||||||
|
[com.taoensso/timbre "4.10.0"]
|
||||||
|
[com.taoensso/tower "3.0.2" :exclusions [com.taoensso/encore]]
|
||||||
|
[crypto-password "0.2.0"]
|
||||||
|
[environ "1.1.0"]
|
||||||
|
[im.chit/cronj "1.4.4"]
|
||||||
|
[lib-noir "0.9.9" :exclusions [org.clojure/tools.reader]]
|
||||||
|
[markdown-clj "0.9.99" :exclusions [com.keminglabs/cljx]]
|
||||||
|
[noir-exception "0.2.5"]
|
||||||
[org.slf4j/slf4j-api "1.7.25"]
|
[org.slf4j/slf4j-api "1.7.25"]
|
||||||
[org.slf4j/log4j-over-slf4j "1.7.25"]
|
[org.slf4j/log4j-over-slf4j "1.7.25"]
|
||||||
[org.slf4j/jul-to-slf4j "1.7.25"]
|
[org.slf4j/jul-to-slf4j "1.7.25"]
|
||||||
[org.slf4j/jcl-over-slf4j "1.7.25"]
|
[org.slf4j/jcl-over-slf4j "1.7.25"]
|
||||||
|
[prone "1.1.4"]
|
||||||
[com.taoensso/tower "3.0.2" :exclusions [com.taoensso/encore]]
|
[ring-server "0.4.0"]
|
||||||
[markdown-clj "0.9.99" :exclusions [com.keminglabs/cljx]]
|
[selmer "1.10.9"]]
|
||||||
[crypto-password "0.2.0"]
|
|
||||||
[clj-jgit "0.8.9"]
|
|
||||||
[environ "1.1.0"]
|
|
||||||
[im.chit/cronj "1.4.4"]
|
|
||||||
[noir-exception "0.2.5"]
|
|
||||||
[prone "1.1.4"]]
|
|
||||||
|
|
||||||
:repl-options {:init-ns smeagol.repl}
|
:repl-options {:init-ns smeagol.repl}
|
||||||
:jvm-opts ["-server"]
|
:jvm-opts ["-server"]
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,39 @@ Smeagol does not currently have any mechanism to upload images. You can, however
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## Now with data visualisation
|
||||||
|
|
||||||
|
Inspired by [visdown](http://visdown.amitkaps.com/) and [vega-lite](https://vega.github.io/vega-lite/docs/), you can now embed visualisations into Smeagol pages, like this:
|
||||||
|
|
||||||
|
### Flight punctuality at London airports
|
||||||
|
|
||||||
|
Example cribbed in its entirety from [here](http://visdown.amitkaps.com/london):
|
||||||
|
```vis
|
||||||
|
data:
|
||||||
|
url: "data/london.csv"
|
||||||
|
transform:
|
||||||
|
-
|
||||||
|
filter: datum.year == 2016
|
||||||
|
mark: rect
|
||||||
|
encoding:
|
||||||
|
x:
|
||||||
|
type: nominal
|
||||||
|
field: source
|
||||||
|
y:
|
||||||
|
type: nominal
|
||||||
|
field: dest
|
||||||
|
color:
|
||||||
|
type: quantitative
|
||||||
|
field: flights
|
||||||
|
aggregate: sum
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that this visualisation will not be rendered in the GitHub wiki, as it doesn't have Smeagol's data visualisation magic. This is what it should look like:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Advertisement
|
## Advertisement
|
||||||
If you like what you see here, I am available for work on open source Clojure projects. Contact me via [WEFT](http://www.weft.scot/).
|
If you like what you see here, I am available for work on open source Clojure projects.
|
||||||
|
|
||||||
### Phoning home
|
### Phoning home
|
||||||
Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file
|
Smeagol currently requests the WEFT logo in the page footer from my home site. This is mainly so I can get a feel for how many people are using the product. If you object to this, edit the file
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,11 @@ th {
|
||||||
border: thin solid silver;
|
border: thin solid silver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.data-visualisation {
|
||||||
|
padding: 0.25em 5%;
|
||||||
|
}
|
||||||
|
|
||||||
.error {
|
.error {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: red;
|
background-color: red;
|
||||||
|
|
@ -231,6 +236,10 @@ th {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.vega-bindings, .vega-actions {
|
||||||
|
font-size: 66%;
|
||||||
|
}
|
||||||
|
|
||||||
.warn {
|
.warn {
|
||||||
color: maroon;
|
color: maroon;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
158
resources/public/data/london.csv
Normal file
158
resources/public/data/london.csv
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
"source","dest","airline","flights","onTimePerf","delayAverage","year"
|
||||||
|
"LHR","ORD","AA",2490,66.33,21.11,2010
|
||||||
|
"LHR","ORD","BA",1413,57.63,23.3,2010
|
||||||
|
"LHR","ORD","UA",2105,73.24,14.57,2010
|
||||||
|
"LHR","ORD","VS",218,77.06,11.1,2010
|
||||||
|
"LHR","LAX","AA",706,66.38,17.66,2010
|
||||||
|
"LHR","LAX","BA",1914,50.18,31.01,2010
|
||||||
|
"LHR","LAX","UA",698,81.81,13.62,2010
|
||||||
|
"LHR","LAX","VS",1285,56.86,21.92,2010
|
||||||
|
"LHR","JFK","AA",3205,67.36,20.31,2010
|
||||||
|
"LHR","JFK","BA",4181,66.59,20.84,2010
|
||||||
|
"LHR","JFK","DL",1611,62.12,23.74,2010
|
||||||
|
"LHR","JFK","KU",305,46.56,38.75,2010
|
||||||
|
"LHR","JFK","VS",2067,59.62,23.69,2010
|
||||||
|
"LHR","EWR","BA",1828,70.25,17.67,2010
|
||||||
|
"LHR","EWR","CO",2697,69.28,18.87,2010
|
||||||
|
"LHR","EWR","VS",1399,65.62,23.15,2010
|
||||||
|
"LHR","IAD","BA",2011,62.11,21.71,2010
|
||||||
|
"LHR","IAD","UA",2094,74.67,14.11,2010
|
||||||
|
"LHR","IAD","VS",700,66.24,19.75,2010
|
||||||
|
"LCY","JFK","BA",1012,89.12,5.67,2010
|
||||||
|
"LHR","ORD","AA",2532,76.87,13.34,2011
|
||||||
|
"LHR","ORD","BA",1440,76.32,14.42,2011
|
||||||
|
"LHR","ORD","UA",2106,79.36,15.2,2011
|
||||||
|
"LHR","ORD","VS",302,82.72,8.66,2011
|
||||||
|
"LHR","LAX","AA",730,75.48,13.66,2011
|
||||||
|
"LHR","LAX","BA",1984,63.46,18.47,2011
|
||||||
|
"LHR","LAX","UA",698,83.52,11.7,2011
|
||||||
|
"LHR","LAX","VS",1397,79,11.2,2011
|
||||||
|
"LHR","JFK","AA",2917,75.8,14.77,2011
|
||||||
|
"LHR","JFK","BA",4944,73.56,14.65,2011
|
||||||
|
"LHR","JFK","DL",2144,80.91,13.05,2011
|
||||||
|
"LHR","JFK","KU",302,52.65,30.02,2011
|
||||||
|
"LHR","JFK","VS",2104,76.32,15.09,2011
|
||||||
|
"LHR","EWR","BA",2129,80.7,11.24,2011
|
||||||
|
"LHR","EWR","CO",3503,78.42,14.19,2011
|
||||||
|
"LHR","EWR","VS",1410,77.52,13.39,2011
|
||||||
|
"LHR","IAD","BA",2157,74.08,14.11,2011
|
||||||
|
"LHR","IAD","UA",2516,80.79,14,2011
|
||||||
|
"LHR","IAD","VS",711,82.42,9.73,2011
|
||||||
|
"LCY","JFK","BA",1031,92.05,4.12,2011
|
||||||
|
"LHR","ORD","AA",2523,72.07,20.03,2012
|
||||||
|
"LHR","ORD","BA",1445,70.03,17.73,2012
|
||||||
|
"LHR","ORD","UA",2102,76.08,15.35,2012
|
||||||
|
"LHR","ORD","VS",308,83.77,8.31,2012
|
||||||
|
"LHR","LAX","AA",714,75.35,12.03,2012
|
||||||
|
"LHR","LAX","BA",1874,63.48,18.34,2012
|
||||||
|
"LHR","LAX","UA",693,76.16,14.88,2012
|
||||||
|
"LHR","LAX","VS",1324,76.13,14.08,2012
|
||||||
|
"LHR","JFK","AA",3367,75.72,12.75,2012
|
||||||
|
"LHR","JFK","BA",5129,69.28,17.68,2012
|
||||||
|
"LHR","JFK","DL",2151,77.63,13.59,2012
|
||||||
|
"LHR","JFK","KU",307,52.12,32.02,2012
|
||||||
|
"LHR","JFK","VS",2227,81.9,11.32,2012
|
||||||
|
"LHR","EWR","BA",1920,73.02,15.88,2012
|
||||||
|
"LHR","EWR","CO",612,84.48,9.24,2012
|
||||||
|
"LHR","EWR","UA",2872,69.76,17.91,2012
|
||||||
|
"LHR","EWR","VS",1421,76.14,16.68,2012
|
||||||
|
"LHR","IAD","BA",2014,71.45,16.23,2012
|
||||||
|
"LHR","IAD","UA",2444,69.04,18.98,2012
|
||||||
|
"LHR","IAD","VS",703,87.06,7.71,2012
|
||||||
|
"LCY","JFK","BA",474,91.33,3.74,2012
|
||||||
|
"LCY","JFK","BA",537,89.37,4.71,2012
|
||||||
|
"LHR","ORD","AA",2513,74.69,15.29,2013
|
||||||
|
"LHR","ORD","BA",1440,65.35,20.84,2013
|
||||||
|
"LHR","ORD","UA",2110,78.39,14.13,2013
|
||||||
|
"LHR","ORD","VS",324,83.02,9.05,2013
|
||||||
|
"LHR","LAX","AA",728,76.48,12.56,2013
|
||||||
|
"LHR","LAX","BA",1864,59.5,27.43,2013
|
||||||
|
"LHR","LAX","UA",702,85.47,9.86,2013
|
||||||
|
"LHR","LAX","VS",1288,79,13.76,2013
|
||||||
|
"LHR","JFK","AA",2991,76.4,13.73,2013
|
||||||
|
"LHR","JFK","BA",5350,66.97,18.95,2013
|
||||||
|
"LHR","JFK","DL",2166,82.09,10.81,2013
|
||||||
|
"LHR","JFK","KU",306,62.42,21.53,2013
|
||||||
|
"LHR","JFK","VS",2825,81.91,10.53,2013
|
||||||
|
"LHR","EWR","BA",1838,71.44,16.72,2013
|
||||||
|
"LHR","EWR","UA",3494,80.59,12.36,2013
|
||||||
|
"LHR","EWR","VS",1419,81.66,11.7,2013
|
||||||
|
"LHR","IAD","BA",2012,71.02,18.67,2013
|
||||||
|
"LHR","IAD","UA",2496,80.39,12.82,2013
|
||||||
|
"LHR","IAD","VS",702,86.89,7.1,2013
|
||||||
|
"LCY","JFK","BA",945,90.64,4.58,2013
|
||||||
|
"LGW","LAX","DY",105,72.38,36.83,2014
|
||||||
|
"LGW","JFK","DY",156,51.92,27.79,2014
|
||||||
|
"LHR","ORD","AA",2476,73.5,22.09,2014
|
||||||
|
"LHR","ORD","BA",1444,65.28,18.7,2014
|
||||||
|
"LHR","ORD","UA",2110,77.56,13.68,2014
|
||||||
|
"LHR","ORD","VS",348,81.32,8.86,2014
|
||||||
|
"LHR","LAX","AA",728,76.79,18.56,2014
|
||||||
|
"LHR","LAX","BA",1450,56.84,23.1,2014
|
||||||
|
"LHR","LAX","DL",127,92.13,6.92,2014
|
||||||
|
"LHR","LAX","UA",698,85.1,8.53,2014
|
||||||
|
"LHR","LAX","VS",1217,80.99,12.58,2014
|
||||||
|
"LHR","JFK","AA",2287,78.18,14.74,2014
|
||||||
|
"LHR","JFK","BA",6018,71.29,16.59,2014
|
||||||
|
"LHR","JFK","DL",2123,82.13,11.19,2014
|
||||||
|
"LHR","JFK","KU",310,48.22,33.17,2014
|
||||||
|
"LHR","JFK","VS",2820,79.77,12.45,2014
|
||||||
|
"LHR","EWR","BA",1943,71.46,19.7,2014
|
||||||
|
"LHR","EWR","UA",3485,78.3,15.19,2014
|
||||||
|
"LHR","EWR","VS",1420,86.6,8.37,2014
|
||||||
|
"LHR","IAD","BA",1807,74.58,15.31,2014
|
||||||
|
"LHR","IAD","UA",2130,81.13,13.61,2014
|
||||||
|
"LHR","IAD","VS",695,89.06,6.9,2014
|
||||||
|
"LCY","JFK","BA",1003,91.23,4.43,2014
|
||||||
|
"LGW","LAX","DY",328,66.46,21.41,2015
|
||||||
|
"LGW","JFK","DY",543,64.09,31.78,2015
|
||||||
|
"LHR","ORD","AA",2062,72.09,27.59,2015
|
||||||
|
"LHR","ORD","BA",1442,71.4,16.24,2015
|
||||||
|
"LHR","ORD","UA",2099,83.94,10.37,2015
|
||||||
|
"LHR","ORD","VS",330,78.79,11.61,2015
|
||||||
|
"LHR","LAX","AA",1265,75.42,14.5,2015
|
||||||
|
"LHR","LAX","BA",1450,66.9,17.67,2015
|
||||||
|
"LHR","LAX","DL",540,79.44,10.97,2015
|
||||||
|
"LHR","LAX","UA",704,89.2,7.5,2015
|
||||||
|
"LHR","LAX","VS",1230,80.81,12.74,2015
|
||||||
|
"LHR","JFK","AA",2130,77.45,15.21,2015
|
||||||
|
"LHR","JFK","BA",5994,77.84,13.61,2015
|
||||||
|
"LHR","JFK","DL",2069,80.75,13.51,2015
|
||||||
|
"LHR","JFK","KU",310,59.22,32.67,2015
|
||||||
|
"LHR","JFK","VS",3363,76.35,13.82,2015
|
||||||
|
"LHR","EWR","BA",1459,76.47,14.03,2015
|
||||||
|
"LHR","EWR","DL",381,95.54,2.88,2015
|
||||||
|
"LHR","EWR","UA",3493,79.23,16.31,2015
|
||||||
|
"LHR","EWR","VS",871,81.75,10.7,2015
|
||||||
|
"LHR","IAD","BA",1421,76.89,12.03,2015
|
||||||
|
"LHR","IAD","UA",2126,81.74,14.02,2015
|
||||||
|
"LHR","IAD","VS",703,85.49,12.59,2015
|
||||||
|
"LCY","JFK","BA",937,92.74,4.52,2015
|
||||||
|
"LTN","EWR","DJT",316,81.53,18.18,2015
|
||||||
|
"LGW","LAX","DY",421,59.86,23.64,2016
|
||||||
|
"LGW","LAX","DI",38,65.79,14.39,2016
|
||||||
|
"LGW","JFK","BA",486,69.75,18.02,2016
|
||||||
|
"LGW","JFK","DY",689,65.31,28.18,2016
|
||||||
|
"LGW","JFK","DI",39,69.23,15.49,2016
|
||||||
|
"LHR","ORD","AA",2453,71.82,26.15,2016
|
||||||
|
"LHR","ORD","BA",1443,68.88,17.58,2016
|
||||||
|
"LHR","ORD","UA",2085,82.25,14.2,2016
|
||||||
|
"LHR","ORD","VS",333,89.79,5.07,2016
|
||||||
|
"LHR","LAX","AA",1411,68.25,19.46,2016
|
||||||
|
"LHR","LAX","BA",1452,54.34,24.89,2016
|
||||||
|
"LHR","LAX","UA",700,87,8.48,2016
|
||||||
|
"LHR","LAX","VS",1376,79.58,10.13,2016
|
||||||
|
"LHR","JFK","AA",2623,76.82,21.41,2016
|
||||||
|
"LHR","JFK","BA",5625,69.97,17.15,2016
|
||||||
|
"LHR","JFK","DL",2081,80.37,13.42,2016
|
||||||
|
"LHR","JFK","KU",253,19.76,71.96,2016
|
||||||
|
"LHR","JFK","VS",3489,79.67,11.44,2016
|
||||||
|
"LHR","EWR","AI",118,65.25,21.14,2016
|
||||||
|
"LHR","EWR","BA",1444,76.11,13.49,2016
|
||||||
|
"LHR","EWR","UA",3472,79.03,15.71,2016
|
||||||
|
"LHR","EWR","VS",722,82.27,9.48,2016
|
||||||
|
"LHR","IAD","BA",1415,71.59,17.44,2016
|
||||||
|
"LHR","IAD","UA",2134,82.05,13.24,2016
|
||||||
|
"LHR","IAD","VS",699,84.69,8.02,2016
|
||||||
|
"LCY","JFK","BA",921,90.01,5.26,2016
|
||||||
|
"LTN","EWR","DJT",333,87.05,8.44,2016
|
||||||
|
BIN
resources/public/data/london.png
Normal file
BIN
resources/public/data/london.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
|
|
@ -6,7 +6,6 @@
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="{{servlet-context}}/content/stylesheet.css" media="screen" rel="stylesheet" type="text/css" />
|
<link href="{{servlet-context}}/content/stylesheet.css" media="screen" rel="stylesheet" type="text/css" />
|
||||||
<link href="{{servlet-context}}/css/print.css" media="print" rel="stylesheet" type="text/css" />
|
|
||||||
{% block extra-headers %}
|
{% block extra-headers %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,18 @@
|
||||||
{% extends "templates/base.html" %}
|
{% extends "templates/base.html" %}
|
||||||
|
|
||||||
|
{% block extra-headers %}
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/vega/3.0.0-rc2/vega.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/vega-lite/2.0.0-beta.10/vega-lite.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/vega-embed/3.0.0-beta.19/vega-embed.js"></script>
|
||||||
|
|
||||||
|
<style media="screen">
|
||||||
|
/* Add space between Vega-Embed links */
|
||||||
|
.vega-actions a {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="content" class="wiki">
|
<div id="content" class="wiki">
|
||||||
{% if editable %}
|
{% if editable %}
|
||||||
|
|
|
||||||
133
src/smeagol/formatting.clj
Normal file
133
src/smeagol/formatting.clj
Normal file
|
|
@ -0,0 +1,133 @@
|
||||||
|
(ns ^{:doc "Format Semagol's enhanced markdown format."
|
||||||
|
:author "Simon Brooke"}
|
||||||
|
smeagol.formatting
|
||||||
|
(:require [clojure.string :as cs]
|
||||||
|
[cemerick.url :refer (url url-encode url-decode)]
|
||||||
|
[noir.io :as io]
|
||||||
|
[noir.session :as session]
|
||||||
|
[markdown.core :as md]
|
||||||
|
[smeagol.authenticate :as auth]
|
||||||
|
[clj-yaml.core :as yaml]
|
||||||
|
[clojure.data.json :as json]))
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;
|
||||||
|
;;;; Smeagol: a very simple Wiki engine.
|
||||||
|
;;;;
|
||||||
|
;;;; This program is free software; you can redistribute it and/or
|
||||||
|
;;;; modify it under the terms of the GNU General Public License
|
||||||
|
;;;; as published by the Free Software Foundation; either version 2
|
||||||
|
;;;; of the License, or (at your option) any later version.
|
||||||
|
;;;;
|
||||||
|
;;;; This program is distributed in the hope that it will be useful,
|
||||||
|
;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;;;; GNU General Public License for more details.
|
||||||
|
;;;;
|
||||||
|
;;;; You should have received a copy of the GNU General Public License
|
||||||
|
;;;; along with this program; if not, write to the Free Software
|
||||||
|
;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||||
|
;;;; USA.
|
||||||
|
;;;;
|
||||||
|
;;;; Copyright (C) 2017 Simon Brooke
|
||||||
|
;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;
|
||||||
|
;;;; Right, doing the data visualisation thing is tricky. Doing it in the
|
||||||
|
;;;; pipeline doesn't work, because the md-to-html-string filter messes up
|
||||||
|
;;;; both YAML and JSON notation. So we need to extract the visualisation YAML
|
||||||
|
;;;; fragments from the Markdown text and replace them with tokens we will
|
||||||
|
;;;; recognise afterwards, perform md-to-html-string, and then replace our
|
||||||
|
;;;; tokens with the transformed visualisation specification.
|
||||||
|
;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
;; Error to show if text to be rendered is nil.
|
||||||
|
(def no-text-error "No text: does the file exist?")
|
||||||
|
|
||||||
|
|
||||||
|
(defn local-links
|
||||||
|
"Rewrite text in `html-src` surrounded by double square brackets as a local link into this wiki."
|
||||||
|
[^String html-src]
|
||||||
|
(if html-src
|
||||||
|
(cs/replace html-src #"\[\[[^\[\]]*\]\]"
|
||||||
|
#(let [text (clojure.string/replace %1 #"[\[\]]" "")
|
||||||
|
encoded (url-encode text)
|
||||||
|
;; I use '\_' to represent '_' in wiki markup, because
|
||||||
|
;; '_' is meaningful in Markdown. However, this needs to
|
||||||
|
;; be stripped out when interpreting local links.
|
||||||
|
munged (cs/replace encoded #"%26%2395%3B" "_")]
|
||||||
|
(format "<a href='wiki?page=%s'>%s</a>" munged text)))
|
||||||
|
no-text-error))
|
||||||
|
|
||||||
|
|
||||||
|
(defn yaml->vis
|
||||||
|
"Transcode this YAML fragment into the source for a Vega visualisation with this index."
|
||||||
|
[^String yaml-src ^Integer index]
|
||||||
|
(str
|
||||||
|
"<div class='data-visualisation' id='vis" index "'></div>\n"
|
||||||
|
"<script>\n//<![CDATA[\nvar vl"
|
||||||
|
index
|
||||||
|
" = "
|
||||||
|
(json/write-str
|
||||||
|
(assoc (yaml/parse-string yaml-src) (keyword "$schema") "https://vega.github.io/schema/vega-lite/v2.json"))
|
||||||
|
";\nvega.embed('#vis" index "', vl" index ");\n//]]\n</script>"))
|
||||||
|
|
||||||
|
|
||||||
|
(defn process-text
|
||||||
|
"Process this `text`, assumed to be markdown potentially containing both local links
|
||||||
|
and YAML visualisation specifications, and return a map comprising JSON visualisation
|
||||||
|
specification, and HTML text with markers for where those should be reinserted.
|
||||||
|
|
||||||
|
The map has two top-level keys: `:visualisations`, a map of constructed keywords to
|
||||||
|
visualisation specifications, and `:text`, an HTML text string with the keywords
|
||||||
|
present where the corresponding visualisation should be inserted."
|
||||||
|
([text]
|
||||||
|
(process-text 0 {:visualisations {}} (cs/split text #"```") '()))
|
||||||
|
([index result fragments processed]
|
||||||
|
(cond
|
||||||
|
(empty? fragments)
|
||||||
|
(assoc result :text (local-links (md/md-to-html-string (cs/join "\n\n" (reverse processed)))))
|
||||||
|
(clojure.string/starts-with? (first fragments) "vis")
|
||||||
|
(let [kw (keyword (str "visualisation-" index))]
|
||||||
|
(process-text
|
||||||
|
(+ index 1)
|
||||||
|
(assoc
|
||||||
|
result
|
||||||
|
:visualisations
|
||||||
|
(assoc
|
||||||
|
(:visualisations result)
|
||||||
|
kw
|
||||||
|
(yaml->vis
|
||||||
|
(subs (first fragments) 3)
|
||||||
|
index)))
|
||||||
|
(rest fragments)
|
||||||
|
(cons kw processed)))
|
||||||
|
true
|
||||||
|
(process-text (+ index 1) result (rest fragments) (cons (first fragments) processed)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn reintegrate-visualisations
|
||||||
|
"Given a map of the form produced by `process-text`, return a string of HTML text
|
||||||
|
with the visualisations (if any) reintegrated."
|
||||||
|
([processed-text]
|
||||||
|
(reintegrate-visualisations (:visualisations processed-text) (:text processed-text)))
|
||||||
|
([visualisations text]
|
||||||
|
(let [ks (keys visualisations)]
|
||||||
|
(if (empty? (keys visualisations))
|
||||||
|
text
|
||||||
|
(let [kw (first ks)]
|
||||||
|
(reintegrate-visualisations
|
||||||
|
(dissoc visualisations kw)
|
||||||
|
(cs/replace
|
||||||
|
text
|
||||||
|
(str kw)
|
||||||
|
(cs/replace (kw visualisations) "\\/" "/"))))))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn md->html
|
||||||
|
"Take this markdown source, and return HTML."
|
||||||
|
[md-src]
|
||||||
|
(reintegrate-visualisations (process-text md-src)))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
[taoensso.timbre :as timbre]
|
[taoensso.timbre :as timbre]
|
||||||
[smeagol.authenticate :as auth]
|
[smeagol.authenticate :as auth]
|
||||||
[smeagol.diff2html :as d2h]
|
[smeagol.diff2html :as d2h]
|
||||||
|
[smeagol.formatting :refer [md->html]]
|
||||||
[smeagol.layout :as layout]
|
[smeagol.layout :as layout]
|
||||||
[smeagol.util :as util]
|
[smeagol.util :as util]
|
||||||
[smeagol.history :as hist]
|
[smeagol.history :as hist]
|
||||||
|
|
@ -98,7 +99,7 @@
|
||||||
(merge (util/standard-params request)
|
(merge (util/standard-params request)
|
||||||
{:title (str (:edit-title-prefix layout/config) " " page)
|
{:title (str (:edit-title-prefix layout/config) " " page)
|
||||||
:page page
|
:page page
|
||||||
:side-bar (util/local-links (util/md->html side-bar))
|
:side-bar (md->html (io/slurp-resource side-bar))
|
||||||
:content (if exists? (io/slurp-resource (str "/content/" page suffix)) "")
|
:content (if exists? (io/slurp-resource (str "/content/" page suffix)) "")
|
||||||
:exists exists?}))))))
|
:exists exists?}))))))
|
||||||
|
|
||||||
|
|
@ -124,8 +125,7 @@
|
||||||
(merge (util/standard-params request)
|
(merge (util/standard-params request)
|
||||||
{:title page
|
{:title page
|
||||||
:page page
|
:page page
|
||||||
:side-bar (util/local-links (util/md->html "/content/_side-bar.md"))
|
:content (md->html (io/slurp-resource file-name))
|
||||||
:content (util/local-links (util/md->html file-name))
|
|
||||||
:editable true})))
|
:editable true})))
|
||||||
true (response/redirect (str "/edit?page=" page)))))
|
true (response/redirect (str "/edit?page=" page)))))
|
||||||
|
|
||||||
|
|
@ -138,11 +138,12 @@
|
||||||
page (url-decode (or (:page params) (:default-page-title layout/config)))
|
page (url-decode (or (:page params) (:default-page-title layout/config)))
|
||||||
file-name (str page ".md")
|
file-name (str page ".md")
|
||||||
repo-path (str (io/resource-path) "/content/")]
|
repo-path (str (io/resource-path) "/content/")]
|
||||||
|
(timbre/info (format "Showing history of page '%s'" page))
|
||||||
(layout/render "history.html"
|
(layout/render "history.html"
|
||||||
(merge (util/standard-params request)
|
(merge (util/standard-params request)
|
||||||
{:title (str "History of " page)
|
{:title (str "History of " page)
|
||||||
:page page
|
:page page
|
||||||
:history (hist/find-history repo-path file-name)}))))
|
:history (md->html (hist/find-history repo-path file-name))}))))
|
||||||
|
|
||||||
|
|
||||||
(defn version-page
|
(defn version-page
|
||||||
|
|
@ -152,15 +153,14 @@
|
||||||
page (url-decode (or (:page params) (:default-page-title layout/config)))
|
page (url-decode (or (:page params) (:default-page-title layout/config)))
|
||||||
version (:version params)
|
version (:version params)
|
||||||
file-name (str page ".md")
|
file-name (str page ".md")
|
||||||
repo-path (str (io/resource-path) "/content/")]
|
repo-path (str (io/resource-path) "/content/")
|
||||||
|
content (hist/fetch-version repo-path file-name version)]
|
||||||
|
(timbre/info (format "Showing version '%s' of page '%s'" version page))
|
||||||
(layout/render "wiki.html"
|
(layout/render "wiki.html"
|
||||||
(merge (util/standard-params request)
|
(merge (util/standard-params request)
|
||||||
{:title (str (:vers-col-hdr layout/config) " " version " of " page)
|
{:title (str (:vers-col-hdr layout/config) " " version " of " page)
|
||||||
:page page
|
:page page
|
||||||
:content (util/local-links
|
:content (md->html content)}))))
|
||||||
(md/md-to-html-string
|
|
||||||
(hist/fetch-version
|
|
||||||
repo-path file-name version)))}))))
|
|
||||||
|
|
||||||
|
|
||||||
(defn diff-page
|
(defn diff-page
|
||||||
|
|
@ -171,6 +171,7 @@
|
||||||
version (:version params)
|
version (:version params)
|
||||||
file-name (str page ".md")
|
file-name (str page ".md")
|
||||||
repo-path (str (io/resource-path) "/content/")]
|
repo-path (str (io/resource-path) "/content/")]
|
||||||
|
(timbre/info (format "Showing diff between version '%s' of page '%s' and current" version page))
|
||||||
(layout/render "wiki.html"
|
(layout/render "wiki.html"
|
||||||
(merge (util/standard-params request)
|
(merge (util/standard-params request)
|
||||||
{:title (str (:diff-title-prefix layout/config)" " version " of " page)
|
{:title (str (:diff-title-prefix layout/config)" " version " of " page)
|
||||||
|
|
@ -201,10 +202,7 @@
|
||||||
(layout/render "auth.html"
|
(layout/render "auth.html"
|
||||||
(merge (util/standard-params request)
|
(merge (util/standard-params request)
|
||||||
{:title (if user (str (:logout-link layout/config) " " user) (:login-link layout/config))
|
{:title (if user (str (:logout-link layout/config) " " user) (:login-link layout/config))
|
||||||
:redirect-to ((:headers request) "referer")
|
:redirect-to ((:headers request) "referer")})))))
|
||||||
:side-bar (util/local-links (util/md->html "/content/_side-bar.md"))
|
|
||||||
:header (util/local-links (util/md->html "/content/_header.md"))
|
|
||||||
:user user})))))
|
|
||||||
|
|
||||||
|
|
||||||
(defn passwd-page
|
(defn passwd-page
|
||||||
|
|
@ -221,8 +219,6 @@
|
||||||
(layout/render "passwd.html"
|
(layout/render "passwd.html"
|
||||||
(merge (util/standard-params request)
|
(merge (util/standard-params request)
|
||||||
{:title (str (:chpass-title-prefix layout/config) " " user)
|
{:title (str (:chpass-title-prefix layout/config) " " user)
|
||||||
:side-bar (util/local-links (util/md->html "/content/_side-bar.md"))
|
|
||||||
:header (util/local-links (util/md->html "/content/_header.md"))
|
|
||||||
:message (if changed? (:chpass-success layout/config))
|
:message (if changed? (:chpass-success layout/config))
|
||||||
:error (cond
|
:error (cond
|
||||||
(nil? oldpass) nil
|
(nil? oldpass) nil
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,9 @@
|
||||||
(ns ^{:doc "Miscellaneous utility functions supporting Smeagol."
|
(ns ^{:doc "Miscellaneous utility functions supporting Smeagol."
|
||||||
:author "Simon Brooke"}
|
:author "Simon Brooke"}
|
||||||
smeagol.util
|
smeagol.util
|
||||||
(:require [clojure.string :as cs]
|
(:require [noir.session :as session]
|
||||||
[cemerick.url :refer (url url-encode url-decode)]
|
[smeagol.authenticate :as auth]
|
||||||
[noir.io :as io]
|
[smeagol.formatting :refer [md->html]]))
|
||||||
[noir.session :as session]
|
|
||||||
[markdown.core :as md]
|
|
||||||
[smeagol.authenticate :as auth]))
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;
|
;;;;
|
||||||
|
|
@ -31,38 +28,13 @@
|
||||||
;;;;
|
;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn md->html
|
|
||||||
"reads a markdown file from public/md and returns an HTML string"
|
|
||||||
[filename]
|
|
||||||
(md/md-to-html-string (io/slurp-resource filename)))
|
|
||||||
|
|
||||||
|
|
||||||
;; Error to show if text to be rendered is nil.
|
|
||||||
(def no-text-error "No text: does the file exist?")
|
|
||||||
|
|
||||||
|
|
||||||
(defn local-links
|
|
||||||
"Rewrite text in `html-src` surrounded by double square brackets as a local link into this wiki."
|
|
||||||
[^String html-src]
|
|
||||||
(if html-src
|
|
||||||
(cs/replace html-src #"\[\[[^\[\]]*\]\]"
|
|
||||||
#(let [text (clojure.string/replace %1 #"[\[\]]" "")
|
|
||||||
encoded (url-encode text)
|
|
||||||
;; I use '\_' to represent '_' in wiki markup, because
|
|
||||||
;; '_' is meaningful in Markdown. However, this needs to
|
|
||||||
;; be stripped out when interpreting local links.
|
|
||||||
munged (cs/replace encoded #"%26%2395%3B" "_")]
|
|
||||||
(format "<a href='wiki?page=%s'>%s</a>" munged text)))
|
|
||||||
no-text-error))
|
|
||||||
|
|
||||||
|
|
||||||
(defn standard-params
|
(defn standard-params
|
||||||
"Return a map of standard parameters to pass to the template renderer."
|
"Return a map of standard parameters to pass to the template renderer."
|
||||||
[request]
|
[request]
|
||||||
(let [user (session/get :user)]
|
(let [user (session/get :user)]
|
||||||
{:user user
|
{:user user
|
||||||
:admin (auth/get-admin user)
|
:admin (auth/get-admin user)
|
||||||
:side-bar (local-links (md->html "/content/_side-bar.md"))
|
:side-bar (md->html (io/slurp-resource "/content/_side-bar.md"))
|
||||||
:header (local-links (md->html "/content/_header.md"))
|
:header (md->html (io/slurp-resource "/content/_header.md"))
|
||||||
:version (System/getProperty "smeagol.version")}))
|
:version (System/getProperty "smeagol.version")}))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue