Skip to content

Commit

Permalink
Merge pull request #7 from kiranshila/templates
Browse files Browse the repository at this point in the history
  • Loading branch information
kiranshila authored Jun 13, 2021
2 parents 51cc5f4 + a00149c commit a12cab5
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 96 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ more sense to wrap the excellent Flexmark (java) and Remark (js) markdown parser
most basic level, `cybermonday` provides a top level function `parse-md`
that gives you a nice, reagent-renderable representation of your source. This
includes all of the CommonMark spec as well as the best features of popular extensions such as tables,
strikethroughs, footnotes, generic attributes, definitions, math, and more! This
strikethroughs, footnotes, math, and more! This
even supports inline html and html around markdown-formated text.

However, `cybermonday` also provides access to a hiccup representation of the
Expand Down
2 changes: 0 additions & 2 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@
clj-commons/clj-yaml {:mvn/version "0.7.106"}
com.vladsch.flexmark/flexmark {:mvn/version "0.62.2"}
com.vladsch.flexmark/flexmark-ext-tables {:mvn/version "0.62.2"}
com.vladsch.flexmark/flexmark-ext-definition {:mvn/version "0.62.2"}
com.vladsch.flexmark/flexmark-ext-footnotes {:mvn/version "0.62.2"}
com.vladsch.flexmark/flexmark-ext-gfm-strikethrough {:mvn/version "0.62.2"}
com.vladsch.flexmark/flexmark-ext-gfm-tasklist {:mvn/version "0.62.2"}
com.vladsch.flexmark/flexmark-ext-attributes {:mvn/version "0.62.2"}
com.vladsch.flexmark/flexmark-test-util {:mvn/version "0.62.2"}
com.vladsch.flexmark/flexmark-ext-gitlab {:mvn/version "0.62.2"}
hickory/hickory {:mvn/version "0.7.1"}
Expand Down
File renamed without changes.
35 changes: 0 additions & 35 deletions doc/01-AST.md → doc/02-AST.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,41 +210,6 @@ code block with an appropriate language.

### Generic Markdown Extensions

#### Attributes

Currently Java-only

Following the details from the [flexmark
spec](https://github.com/vsch/flexmark-java/wiki/Attributes-Extension). Cybermonday differs from the default
configuration as `ASSIGN_TEXT_ATTRIBUTES` is set to false. This implies that
inline attributes will always configure the parent element. This is due to the
fact that the way the Flexmark AST is built for the extended behavior, merging
attributes into leaves at the same level makes the transformation much more
difficult. If a need for this feature comes up, it might be worth looking into,
but the primary use case of heading `:id`s is unaffected.

```clojure
[:markdown/attributes {:key "value"}]
```

#### Definitions

Currently Java-only

From the [PHP Markdown Extra Definition
List](https://michelf.ca/projects/php-markdown/extra/#def-list).

#### Definition List, Term, and Items

The definition list contains the term and item children nodes. The term and
item bodies can of course contain additional hiccup.

```clojure
[:dl {}
[:dt {} "Foo"]
[:dd {} [:p {} "Bar"]]]
```

#### Footnotes

Enables footnotes in the common format. Details [here](https://github.com/vsch/flexmark-java/wiki/Footnotes-Extension)
Expand Down
22 changes: 22 additions & 0 deletions doc/03-Templates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Templates

Cybermonday has very basic support for templates with
[mustache](https://mustache.github.io/) syntax. This is basic in the sense that
it only works for mustache tags, such as `{{foo}}` transforms to a
`:markdown/mustache` IR node as `[:markdown/mustache {} "foo"]`. This feature is
disabled by default but can be enabled by setting `:parse-templates?` to `true`
in the `parse-md` opts map.

You could then easily implement templating with a lowering fn such as

```clojure
(def replacements {:foo "bar"})

(defn lower-mustache [[_ _ body]]
((keyword body) replacements))
```

However the default behavior, even when enabled is to leave the text as is.

This feature should be considered very alpha and prone to change as we perhaps
might want to pull in an actual implementation of mustache templating.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<packaging>jar</packaging>
<groupId>com.kiranshila</groupId>
<artifactId>cybermonday</artifactId>
<version>0.1.0</version>
<version>0.2.0</version>
<name>cybermonday</name>
<dependencies>
<dependency>
Expand Down
17 changes: 11 additions & 6 deletions src/cybermonday/core.cljc
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
(ns cybermonday.core
(:require
[cybermonday.lowering :refer [to-html-hiccup]]
[cybermonday.ir :refer [md-to-ir]]
[cybermonday.utils :as utils]
[cybermonday.templates :as templates]
[cybermonday.lowering :as lowering]
[cybermonday.ir :as ir]
#?(:clj [clj-yaml.core :as yaml]
:cljs ["yaml" :as yaml])))

Expand All @@ -12,11 +14,14 @@

(defn parse-md
"Generates HTML hiccup from markdown and associated frontmatter
See `cybermonday.lowering/to-html-hiccup` for opts map values"
See `cybermonday.lowering/to-html-hiccup` for opts map values.
Set `:process-templates?` to true to process mustache templates"
([md opts]
(let [[_ fm body] (re-matches frontmatter-re md)]
{:frontmatter (when fm (parse-yaml fm))
:body (-> body
md-to-ir
(to-html-hiccup opts))}))
:body (cond-> body
true ir/md-to-ir
(:process-templates? opts) templates/parse-templates
true (lowering/to-html-hiccup opts)
true utils/cleanup-whitespace)}))
([md] (parse-md md nil)))
15 changes: 1 addition & 14 deletions src/cybermonday/ir.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,6 @@
item))
almost-hiccup))

;; Final IR postprocessing

(defn cleanup-whitespace
"Removes excess whitespace from the resulting AST."
[hiccup]
(walk/postwalk
(fn [item]
(cond
(string? item) (when (not (str/blank? item)) item)
:else item))
hiccup))

;; IR Generation

(defn md-to-ir
Expand All @@ -90,5 +78,4 @@
[md]
(let [document (.parse parser/parser md)]
(->> (parser/to-hiccup document md)
process-inline-html
cleanup-whitespace)))
process-inline-html)))
24 changes: 6 additions & 18 deletions src/cybermonday/lowering.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
:markdown/inline-math :code
:markdown/html-comment nil
:markdown/soft-line-break nil
:markdown/attributes nil
:markdown/reference nil
:markdown/table-separator nil})

Expand Down Expand Up @@ -77,6 +76,9 @@
:li
(conj body [:input {:checked checked? :disabled true :type "checkbox"}])))

(defn lower-mustache [[_ _ body]]
(str "{{" body "}}"))

(defn lower-fallback [[tag attrs & body]]
(if (contains? default-tags tag)
(when-let [new-tag (default-tags tag)]
Expand All @@ -95,22 +97,8 @@
:markdown/footnote-block lower-footnote-block
:markdown/task-list-item lower-task-list-item
:markdown/link-ref lower-link-ref
:markdown/image-ref lower-image-ref})

(defn attributes
"Returns the attributes map of a given node, merging children attributes IR nodes"
[[_ attrs & body]]
(apply merge attrs (map second (filter #(= :markdown/attributes (first %)) body))))

(defn merge-attributes
"Walks the IR tree and merges in attributes"
[ir]
(walk/postwalk
(fn [item]
(if (hiccup? item)
(assoc item 1 (attributes item))
item))
ir))
:markdown/image-ref lower-image-ref
:markdown/mustache lower-mustache})

(defn lower-ir
"Transforms the IR tree by lowering nodes to their HTML representation"
Expand Down Expand Up @@ -153,6 +141,6 @@
`:lower-fns` supplies a mapping from IR keyword to lowering fn
`default-attrs` supplies a mapping from HTML keyword to default node attributes"
[ir & [{:keys [lower-fns default-attrs]}]]
(-> (merge-attributes ir)
(-> ir
(lower-ir (or lower-fns default-lowering))
(apply-post-attrs (or default-attrs {}))))
19 changes: 1 addition & 18 deletions src/cybermonday/parser.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
HtmlCommentBlock HtmlEntity)
(com.vladsch.flexmark.ext.tables
TablesExtension TableBlock TableHead TableRow TableCell TableBody TableBody TableSeparator)
(com.vladsch.flexmark.ext.attributes AttributesExtension AttributesNode)
(com.vladsch.flexmark.ext.definition DefinitionExtension DefinitionList DefinitionTerm DefinitionItem)
(com.vladsch.flexmark.ext.footnotes FootnoteExtension Footnote FootnoteBlock)
(com.vladsch.flexmark.ext.gfm.strikethrough StrikethroughExtension Strikethrough)
(com.vladsch.flexmark.ext.gfm.tasklist TaskListExtension TaskListItem)
Expand All @@ -27,12 +25,9 @@
"The default options for the Flexmark parser
There shouldn't be a reason to change this"
(.. (MutableDataSet.)
(set AttributesExtension/ASSIGN_TEXT_ATTRIBUTES false)
(set Parser/EXTENSIONS
[(TablesExtension/create)
(FootnoteExtension/create)
(DefinitionExtension/create)
(AttributesExtension/create)
(StrikethroughExtension/create)
(TaskListExtension/create)
(GitLabExtension/create)])
Expand Down Expand Up @@ -69,10 +64,7 @@
TableHead :thead
TableBody :tbody
TableRow :tr
BlockQuote :blockquote
DefinitionList :dl
DefinitionTerm :dt
DefinitionItem :dd})
BlockQuote :blockquote})

(defn node-to-tag
"Gets the default tag for this `node` or throws an error if we encounter a node we aren't handling."
Expand Down Expand Up @@ -174,15 +166,6 @@
HtmlInline
(to-hiccup [this _]
[:markdown/html {} (str (.getChars this))])
AttributesNode
(to-hiccup [this _]
[:markdown/attributes (into {} (for [attribute (.getChildren this)
:let [name (str (.getName attribute))
value (str (.getValue attribute))]]
(cond
(.isId attribute) [:id value]
(.isClass attribute) [:class value]
:else [(keyword name) (if (not-empty value) value true)])))])
Footnote
(to-hiccup [this _]
[:markdown/footnote {:id (str (.getText this))}])
Expand Down
35 changes: 35 additions & 0 deletions src/cybermonday/templates.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(ns cybermonday.templates
(:require
[cybermonday.utils :refer [hiccup? make-hiccup-node]]
[clojure.walk :as walk]
[clojure.string :as str]))

(def blacklisted-tags #{:pre
:code
:markdown/indented-code-block
:markdown/fenced-code-block})

(defn parse-templates [ast]
(walk/postwalk
(fn [item]
(if (hiccup? item)
(let [[key attr & body] item]
(if (not (contains? blacklisted-tags key))
(make-hiccup-node
key
attr
(apply
concat
(for [child body]
(if (string? child)
(let [split (str/split child #"\{\{|\}\}")
items (partition-all 2 split)]
(letfn [(process [[not-template template]]
(if template
[not-template [:markdown/mustache {} template]]
[not-template]))]
(mapcat process items)))
[child]))))
item))
item))
ast))
10 changes: 10 additions & 0 deletions src/cybermonday/utils.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,13 @@
str/lower-case))

(def html-comment-re #"<!--([\s\S]*?)-->")

(defn cleanup-whitespace
"Removes excess whitespace from the resulting AST."
[hiccup]
(walk/postwalk
(fn [item]
(cond
(string? item) (when (not (str/blank? item)) item)
:else item))
hiccup))
1 change: 0 additions & 1 deletion src/deps.cljs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{:npm-deps {"remark" "13.0.0"
"remark-deflist" "0.3.0"
"remark-gfm" "1.0.0"
"remark-math" "4.0.0"
"remark-parse" "9.0.0"
Expand Down

0 comments on commit a12cab5

Please sign in to comment.