summaryrefslogtreecommitdiff
path: root/src/weepinbell/metadata/jf2.clj
blob: 758c381d67f643b8fffbabe4e4cf5bd6cdbfaa31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
(ns weepinbell.metadata.jf2
  "JF2 parser from various data formats (eg. microformats) to JF2 format."
  (:require [hickory.core :as hickory]
            [mf2clj.core :as mf]
            [weepinbell.metadata.microformats :refer [parse-microformats]]
            [weepinbell.metadata.html-head :refer [parse-meta]]
            [weepinbell.metadata.json-ld :refer [parse-json-ld]]))

(defn supplement-merge
  "Deep merge maps A and B where B never overrides A.
   Supplements A with values A does not have but B has."
  [a b]
  (let [supplement (fn [acc k v]
                     (assoc acc k (supplement-merge (get acc k) v)))]
    (cond
      (nil? a)           b
      (not (and (map? a) (map? b))) a
      :else              (reduce-kv supplement a b))))

(defn parse
  "Takes HTML string, return a JF2 data object compiled from
   mircorformats and more sources."
  [^String html-string]
  {:pre [(string? html-string)]}
  (let [mf (mf/parse html-string)
        mf->jf2 (parse-microformats mf)
        hick (-> html-string hickory/parse hickory/as-hickory)
        more [mf->jf2
              (parse-meta hick)
              (parse-json-ld hick)]]
    (reduce supplement-merge more)))