Created
February 20, 2023 09:52
-
-
Save jdevera/4a708abe505cb008478e69d1f35c90b7 to your computer and use it in GitHub Desktop.
Namespaces Catalog for Roam Research (v.1.0)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns namespaces-catalog-v1.0 | |
(:require [roam.datascript :as rd] | |
[roam.util :refer [parse]])) | |
(def SEP "/") | |
(defn namespaced-pages | |
" Get all pages in the graph that have a namespace (they contain / in the title)" | |
[] | |
(map first | |
(rd/q '[:find ?fulltitle | |
:where [?e :node/title ?fulltitle] | |
[(clojure.string/includes? ?fulltitle "/")]]))) | |
(defn page-exists? | |
"Checks whether a given page title exists in the graph" | |
[page] | |
(not (nil? (first (rd/q '[:find ?fulltitle | |
:in $ ?page | |
:where [?p :node/title ?page] | |
[?p :node/title ?fulltitle]] page))))) | |
(defn page-link | |
"Linkify page title if it exists in the graph. Otherwise, return the title as is." | |
[name] | |
(if (page-exists? name) | |
(parse (str "[[" name "]]")) | |
name)) | |
(defn expand | |
"Given a namespace path as a list of its parts, return a list of progressively | |
longer paths that ends with the given path. | |
Example: [a b c] -> [[] [a] [a b] [a b c]]" | |
[path-parts] | |
(->> path-parts | |
(reduce (fn [acc x] (conj acc (conj (last acc) x))) [[]]) | |
(map #(clojure.string/join SEP %)))) | |
(defn indent | |
"Given a vector starting with a path as a string, prepend the depth of the path | |
as the number of parts in it. | |
Example: [a/b/c _] -> [3 a/b/c _]" | |
[path] | |
(into [(count (clojure.string/split (first path) SEP))] path)) | |
(defn count-pages-for-namespaces | |
"For a list of pages, give back a list of namespaces and the count of pages | |
in each. Note that it expands to all levels of namespaces. An indication of | |
the level of indentation is also returned: [indentation path page-count] | |
Example: [a/b/page d/page2] -> [[1 a 1] [2 a/b 1] [1 d 1]]" | |
[pages] | |
(->> pages | |
sort | |
(map #(clojure.string/split % SEP)) | |
(map drop-last) | |
(map expand) | |
flatten | |
(remove empty?) | |
frequencies | |
sort | |
(map indent))) | |
(defn make-row | |
"Turn a vector of indentation, namespace and page-count into a table row for | |
presentation. The indentation value is used to style the namespace left padding." | |
[indentation path page-count] | |
[:tr | |
[:td {:style {:padding-left (str indentation "ex")}} (page-link path)] | |
[:td page-count]]) | |
(defn make-table | |
"Create a table with the namespace results." | |
[rows] | |
(def HEADER [:tr [:th "Namespace"] [:th "Number of pages"]]) | |
[:table | |
HEADER | |
(map #(apply make-row %) rows) | |
]) | |
(defn main | |
[] | |
(make-table (count-pages-for-namespaces (namespaced-pages)))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Instructions to use:
clojure
somewhere in your Roam graph.{{roam/render: ((auxjxGG3h))}}
(whereauxjxGG3h
is the block reference you got on step 2