Skip to content

Instantly share code, notes, and snippets.

@danielsz
Created December 15, 2024 20:12
Show Gist options
  • Save danielsz/3fc6ea187c589c533cd660de35e9d213 to your computer and use it in GitHub Desktop.
Save danielsz/3fc6ea187c589c533cd660de35e9d213 to your computer and use it in GitHub Desktop.
Text decoration à la Bluesky
(defn size-table [{:keys [text urls tags mentions]}]
{:text {:content text
:size (count (.getBytes text StandardCharsets/UTF_8))}
:urls (map (fn [url] {:content url
:size (count (.getBytes url StandardCharsets/UTF_8))}) urls)
:tags (map (fn [tag] {:content tag
:size (count (.getBytes tag StandardCharsets/UTF_8))}) tags)
:mentions (map (fn [mention] {:content mention
:size (count (.getBytes mention StandardCharsets/UTF_8))}) mentions)})
(defmulti create-facet (fn [m] (key (first m))))
(defmethod create-facet :uri [m]
{:$type "app.bsky.richtext.facet#link"
:uri (val (first m))})
(defmethod create-facet :tag [m]
{:$type "app.bsky.richtext.facet#tag"
:tag (val (first m))})
(defmethod create-facet :mention [m]
{:$type "app.bsky.richtext.facet#mention"
:did (val (first m))})
(defn create-index [start end]
{:index {:byteStart start
:byteEnd end}})
(defn create-feature [facet]
{:features [facet]})
(defn facets [start-bytes k v]
(loop [els v
result []
start start-bytes]
(if els
(let [{content :content size :size} (first els)
end (inc (+ start size))]
(recur (next els)
(conj result (merge (create-index start end)
(create-feature (create-facet {k content}))))
(inc (+ start size))))
result)))
;; And now we can use it like this, for example
(defn decoration-payload [info]
(let [xs (size-table info)
start-bytes-url (inc (:size (:text xs)))
facets-url (facets start-bytes-url :uri (:urls xs))
start-bytes-tags (+ start-bytes-url (reduce (fn [prev url] (+ prev (:size url))) 0 (:urls xs)))
facets-tags (facets start-bytes-tags :tag (:tags xs))]
(into facets-url facets-tags)))
(comment
(let [post {:text "Hello, World!" :urls ["https://example.org"] :tags ["#yay" "#lol"]}]
(decoration-payload post)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment