gpt4 book ai didi

html - 从一种 HTML 表示形式转换为另一种 HTML 表示形式的算法

转载 作者:行者123 更新时间:2023-11-27 23:59:45 25 4
gpt4 key购买 nike

我有一个以奇怪形式表示的 HTML(它比常规的嵌套形式更容易使用):

         [{:text "5d" :em true :strong true}
{:text "xx" :em true}
{:text "damn" :em true :strong true}
{:text "c6"}
{:text "qwe" :em true}
{:text "asd"}
{:text "qqq" :em true :strong true}]

我需要将它转换成类似 Hiccup 的:

           [[:em
[:strong "5d"]
"xx"
[:strong "damn"]]
"c6"
[:em "qwe"]
"asd"
[:strong [:em "qqq"]]]

我想出的最佳实现是:

(defn wrap-tags [states nodes]
(if (seq states)
(reduce
(fn [nodes state]
[(into [state] nodes)])
nodes states)
nodes))

(defn p->tags
([data]
(p->tags data #{} [] []))
([[node & rest] state waiting result]
(let [new-state (set (keys (dissoc node :text)))
closed (clojure.set/difference state new-state)
waiting (conj (wrap-tags closed waiting) (:text node))
result (if-not (seq new-state)
(into result waiting)
result)
waiting (if-not (seq new-state) [] waiting)]
(if (seq rest)
(p->tags rest new-state waiting result)
(if (seq waiting)
(into result (wrap-tags new-state waiting))
result)))))

虽然它不能正常工作,但它不能处理 :strong 出现的情况(它不知道应该包装多少“等待”节点,并包装所有这些节点 - 但我不知道如何跟踪这)。它对我来说也有点难看,但这不那么烦人。 :) 它现在为我的案例返回的是:

[[:em
[:strong
[:strong "5d"]
"xx"
"damn"]]
"c6"
[:em "qwe"]
"asd"
[:em [:strong "qqq"]]]

我很想听听任何关于如何改进我的代码的想法。

最佳答案

如果我正确理解了你的数据布局,看起来你想根据元素是否包含 :em 来划分序列,如果包含,则将那些包裹在 a 边单个 [:em...] 节点。 Clojure 的 partition-by 可用于执行此操作:

(def elements [{:text "5d" :em true :strong true}                                                                              
{:text "xx" :em true}
{:text "damn" :em true :strong true}
{:text "c6"}
{:text "qwe" :em true}
{:text "asd"}
{:text "qqq" :em true :strong true}])

(vec (partition-by #(:em %1) elements))
;; =>
[({:text "5d", :strong true, :em true}
{:text "xx", :em true}
{:text "damn", :strong true, :em true})
({:text "c6"})
({:text "qwe", :em true})
({:text "asd"})
({:text "qqq", :strong true, :em true})]

然后您可以使用 reduce 处理它以创建类似打嗝的结构:

(defn group->tag [acc group]                                                                                                   
(cond
(nil? group)
acc

(:em (first group))
(conj
acc
(vec
(concat [:em]
(mapv
(fn [elt]
(if (contains? elt :strong)
[:strong (:text elt)]
(:text elt)))
group))))

:otherwise
(vec (concat acc (mapv :text group)))))

(defn elements->hiccup [elements]
(reduce
group->tag
[]
(partition-by #(:em %1) elements)))

上面看起来像它产生了你所要求的:

(elements->hiccup elements)                                                                                                    
;; =>
[[:em
[:strong "5d"]
"xx"
[:strong "damn"]]
"c6"
[:em "qwe"]
"asd"
[:em [:strong "qqq"]]]

关于html - 从一种 HTML 表示形式转换为另一种 HTML 表示形式的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21928451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com