NodeJS 上的 Clojurescript Hickory(解析 HTML 打嗝)

Clojurescript Hickory on NodeJS (parse HTML to hiccup)

我需要一种方法来解析 HTML 标记,以便在用 Clojurescript 编写的 node.js 应用程序上打嗝。在客户端,我使用了山核桃木来完成这项工作,不幸的是,它在 Node.js 上表现不佳。如果任何命名空间需要 hickory.core 节点拒绝 运行 应用程序说

ReferenceError: Node is not defined
    at hickory$core$node_type (/media/lapdaten/ARBEITSSD/dev/violinas_macchiato/target/out/hickory/core.cljs:35:1)
    at Object.<anonymous> (/media/lapdaten/ARBEITSSD/dev/violinas_macchiato/target/out/hickory/core.cljs:39:16)

如果我用 figwheel 热加载库,而节点已经 运行ning CIDER 给我各种山核桃函数的代码完成,但 hickory.core/parse-fragment 在 运行 时未定义(hickory.core/as-hiccup 由于某种原因可用)。

这实际上是一个 known problem with hickory because it depends on a browser DOM API, which is unavailable in Node.js. I tried (set! js/DOMParser (.-DOMParser (js/require "xmldom"))) as suggested on GitHub,但我实际上不知道该将表达式放在哪里。一般来说 GitHub 上的讨论让我毫无头绪......

有没有人让山核桃木在 Node.js 上工作?关于如何让我的应用程序将 HTML 转换为打嗝还有其他建议吗?

非常感谢!

奥利弗

由于山核桃树不以我能理解的方式支持 Node.js 我最近一直在研究本机 Node.js 解决方案。看posthtml-parser。它的好处是,它产生的 JSON 与几乎完全 hickory-format 仅差 js->clj,即以下内容:

(ns utils.phtmltohiccup
  (:require
   ["posthtml-parser" :as phr] ; requiring the shadow-cljs way
   ))
   
(def testhtml
  "<ul class=\"list\" important=\"false\"><li>Hello World</li><li>Hello Again</li></ul>")

(js->clj
 (phr
  testhtml) :keywordize-keys true)

产生:

[{:tag "ul"
  :attrs
  {:class "list"
   :important "false"}
  :content
  [{:tag "li"
    :content
    ["Hello World"]}
   {:tag "li"
    :content
    ["Hello Again"]}]}]

关于正确的山核桃木的唯一区别似乎是缺少 :type 键并且假定类型为 :element。这种结构在 Clojurescript 中是高度可行的形式。当我确实需要打嗝时,我现在使用两个非常简单的函数之一将上面的山核桃转换为打嗝。 Stack-consuming:

(defn parsed-to-hiccup-sc
  ""
  [hickory]
  (map
   (fn [element]
     (if (:tag element)
       (do
         (print (:tag element))
         (let [{:keys [tag attrs content]} element]
           (into [(keyword tag) attrs] (parsed-to-hiccup-sc content))
           ))
       (str element)))
   hickory))

或者我使用 clojure.walk(我假设这不是 stack-consuming):

(defn parsed-to-hiccup-ns
  ""
  [hickory]
  (walk/postwalk
   (fn [element]
     (if (:tag element)
       (let [{:keys [tag attrs content]} element]
         (into [(keyword tag) attrs] content))
       (str element)))
   hickory))

暂时这个解决方案足以满足我的意图和目的。但是,我会把这个库提请山核桃维护者注意。也许有一种简单的方法可以将 posthtml-parser 集成到山核桃中以获得正确的 Node.js-support.