├── .gitignore
├── nbb.edn
├── deps.edn
├── .github
└── workflows
│ ├── test.yml
│ └── ci.yml
├── rdf_export.mjs
├── bb.edn
├── package.json
├── CHANGELOG.md
├── LICENSE.md
├── action.yml
├── src
└── logseq
│ ├── rdf_export
│ └── config.cljs
│ └── rdf_export.cljs
├── README.md
├── yarn.lock
└── test
└── fixtures
├── docs.ttl
└── docs-with-labels.ttl
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /.nbb
3 | /.cpcache
4 |
--------------------------------------------------------------------------------
/nbb.edn:
--------------------------------------------------------------------------------
1 | {:deps
2 | {logseq/graph-parser
3 | {:git/url "https://github.com/logseq/logseq"
4 | :git/sha "65640ed8857199d89268295863cd556f5d90ea0b"
5 | :deps/root "deps/graph-parser"}
6 | #_{:local/root "../logseq/deps/graph-parser"}}}
7 |
--------------------------------------------------------------------------------
/deps.edn:
--------------------------------------------------------------------------------
1 | {:aliases
2 | {:clj-kondo
3 | {:replace-deps {clj-kondo/clj-kondo {:mvn/version "2025.06.05"}}
4 | :main-opts ["-m" "clj-kondo.main"]}
5 | :outdated
6 | {:replace-deps {com.github.liquidz/antq {:mvn/version "RELEASE"}}
7 | :main-opts ["-m" "antq.core" "--exclude" "com.github.liquidz/antq"]}}}
8 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | on: [push]
2 |
3 | jobs:
4 | test:
5 | runs-on: ubuntu-latest
6 | name: Test the action
7 | steps:
8 | - name: Checkout
9 | uses: actions/checkout@v4
10 |
11 | # TODO: Test a real graph
12 | - name: Run github action
13 | uses: logseq/rdf-export@main
14 |
--------------------------------------------------------------------------------
/rdf_export.mjs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import { loadFile, addClassPath } from '@logseq/nbb-logseq'
4 | import { fileURLToPath } from 'url';
5 | import { dirname, resolve } from 'path';
6 |
7 | const __dirname = fileURLToPath(dirname(import.meta.url));
8 | addClassPath(resolve(__dirname, 'src'));
9 | const { main } = await loadFile(resolve(__dirname, 'src/logseq/rdf_export.cljs'));
10 |
11 | // Expects to be called as node X.js ...
12 | const args = process.argv.slice(2)
13 | main.apply(null, args);
14 |
--------------------------------------------------------------------------------
/bb.edn:
--------------------------------------------------------------------------------
1 | {:tasks
2 | {test
3 | {:doc "Regression tests done against local docs repo"
4 | :task
5 | (do
6 | (shell "node rdf_export.mjs docs.ttl -d ../docs")
7 | ;; Fixtures are from docs version https://github.com/logseq/docs/commit/e591e1cfabab4fbb666600b751b3b014d9bd8367
8 | (shell "diff test/fixtures/docs.ttl docs.ttl")
9 | (shell "ttl docs.ttl")
10 | (shell "node rdf_export.mjs docs-with-labels.ttl -d ../docs --add-labels -c '{:exclude-properties [:initial-version :description]}'")
11 | (shell "diff test/fixtures/docs-with-labels.ttl docs-with-labels.ttl")
12 | (shell "ttl docs-with-labels.ttl")
13 | (println "Success!"))}}}
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@logseq/rdf-export",
3 | "version": "1.0.0",
4 | "description": "Exports a configurable subset of a logseq graph to RDF",
5 | "bin": {
6 | "logseq-rdf-export": "rdf_export.mjs"
7 | },
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/logseq/rdf-export.git"
11 | },
12 | "keywords": [],
13 | "author": "",
14 | "license": "ISC",
15 | "bugs": {
16 | "url": "https://github.com/logseq/rdf-export/issues"
17 | },
18 | "homepage": "https://github.com/logseq/rdf-export#readme",
19 | "dependencies": {
20 | "@logseq/nbb-logseq": "logseq/nbb-logseq#feat-db-v24",
21 | "mldoc": "^1.5.9",
22 | "n3": "^1.16.3",
23 | "turtle-validator": "^1.1.1"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 |
6 | jobs:
7 |
8 | lint:
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v4
14 |
15 | - name: Set up Java
16 | uses: actions/setup-java@v4
17 | with:
18 | distribution: 'zulu'
19 | java-version: 17
20 |
21 | - name: Set up Clojure
22 | uses: DeLaGuardo/setup-clojure@master
23 | with:
24 | cli: 1.11.1.1237
25 |
26 | - name: Run clj-kondo lint
27 | run: clojure -M:clj-kondo --lint src
28 |
29 | - name: Check outdated dependencies
30 | uses: liquidz/antq-action@main
31 | with:
32 | excludes: 'clojure/brew-install'
33 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Unreleased
2 |
3 | * Use nbb-logseq and latest logseq deps that supports db-version
4 |
5 | ## 0.2.1
6 | * Remove unused :class-query and :additional-pages config options
7 | * Sort triples for easier diffing
8 |
9 | ## 0.2.0
10 |
11 | * Add support for block level exports
12 | * Use a block's page name as an identity when no name is found
13 | * Add :unique-id-properties config to uniquely identify a block when no
14 | :block/name exists
15 | * Add warnings when a block can't be exported and a :classes-without-ids to
16 | silence them for certain classes
17 | * Add :expand-macros config to expand macros in export
18 | * Add --add-labels CLI option to add labels to all entities and use more
19 | standard vocabs like rdfs and owl. This option allows feeding an export
20 | to a LLM e.g. https://github.com/emptycrown/llama-hub/tree/main/loader_hub/file/rdf
21 | * Add :exclude-properties config to exclude certain properties from export
22 | * Add :type-property config to look up an entity's class
23 |
24 | ## 0.1.0
25 |
26 | * Initial release with rdf being exported to a file and validated
27 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2023 Logseq
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/action.yml:
--------------------------------------------------------------------------------
1 | name: 'Logseq RDF Export'
2 | description: 'Exports a subset of a Logseq graph to RDF'
3 | inputs:
4 | rdfFile:
5 | description: "Name of RDF file to save export"
6 | required: true
7 | default: "test.ttl"
8 | directory:
9 | description: "Graph's root directory"
10 | required: false
11 | default: '.'
12 |
13 | runs:
14 | using: "composite"
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v4
18 | with:
19 | repository: logseq/rdf-export
20 | path: .logseq-rdf-export
21 |
22 | - name: Set up Clojure
23 | uses: DeLaGuardo/setup-clojure@master
24 | with:
25 | cli: 1.11.1.1182
26 | bb: 1.0.164
27 |
28 | - name: Set up Node
29 | uses: actions/setup-node@v3
30 | with:
31 | node-version: '18'
32 | cache: 'yarn'
33 | cache-dependency-path: .logseq-rdf-export/yarn.lock
34 |
35 | - name: Fetch yarn deps
36 | run: cd .logseq-rdf-export && yarn install --immutable
37 | shell: bash
38 |
39 | - name: Nbb cache
40 | uses: actions/cache@v3
41 | id: nbb-deps
42 | with:
43 | path: |
44 | ~/.m2/repository
45 | ~/.gitlibs
46 | .logseq-rdf-export/.nbb/.cache
47 | key: ${{ runner.os }}-nbb-deps-${{ hashFiles('.logseq-rdf-export/nbb.edn') }}
48 | restore-keys: ${{ runner.os }}-nbb-deps-
49 |
50 | - name: Fetch nbb deps
51 | if: steps.nbb-deps.outputs.cache-hit != 'true'
52 | run: cd .logseq-rdf-export && yarn nbb-logseq -e ':fetching-deps'
53 | shell: bash
54 |
55 | - name: Export graph to RDF
56 | run: cd .logseq-rdf-export && node rdf_export.mjs ../${{ inputs.rdfFile }} --directory ${{ inputs.directory }}
57 | shell: bash
58 |
59 | - name: Validate RDF file
60 | run: cd .logseq-rdf-export && yarn ttl ../${{ inputs.rdfFile}}
61 | shell: bash
62 |
--------------------------------------------------------------------------------
/src/logseq/rdf_export/config.cljs:
--------------------------------------------------------------------------------
1 | (ns logseq.rdf-export.config)
2 |
3 | (def default-config
4 | "Graph-specific config to define behaviors for this export"
5 | {;; Recommended: Base url for all pages in the graph
6 | :base-url
7 | "https://example.com/#/page/"
8 |
9 | ;; The rest of these config keys are optional:
10 |
11 | ;; Rdf format to write to. Defaults to turtle.
12 | ;; Other possible values - n-triples, n-quads, trig
13 | :format "turtle"
14 | ;; Shortens urls in turtle output
15 | :prefixes
16 | {:s "https://schema.org/"}
17 | ;; Property used to look up urls of property pages. Defaults
18 | ;; to :url. For example, in order to resolve the description property,
19 | ;; the description page has a url property with its full url.
20 | :url-property :url
21 | ;; Property used to look up a Class of an entity. Default to :type
22 | :type-property :type
23 | ;; When an entity doesn't have a unique string to identify it, usually through
24 | ;; :block/title, look up these properties in order
25 | :unique-id-properties []
26 | ;; Properties that are excluded in export for all entities.
27 | ;; Useful if some properties cause issues with a rdf consumer
28 | :exclude-properties []
29 | ;; When enabled expands macros in entities if they exist
30 | :expand-macros false
31 | ;; Silences warning messages for classes of entities that don't have a unique id
32 | :classes-without-ids #{}
33 |
34 | ;; The rest of the config determines what pages in your graph are included in
35 | ;; the output. All triples/properties of a page are included.
36 | ;; These config keys are all optional as they have useful defaults.
37 | ;;
38 | ;; Query to fetch all pages that are properties.
39 | ;; Defaults to pages with "type:: [[Property]]"
40 | :property-query
41 | '[:find (pull ?b [*])
42 | :in $ %
43 | :where
44 | (page-property ?b :type "Property")]
45 | ;; Query to fetch all entities that are instances of classes.
46 | ;; Defaults to pages with "type:: [[X]]" where X are pages with
47 | ;; "type:: [[Class]]"
48 | :class-instances-query
49 | '[:find (pull ?b2 [*])
50 | :in $ %
51 | :where
52 | (page-property ?b :type "Class")
53 | [?b :block/title ?n]
54 | (page-property ?b2 :type ?n)]
55 | ;; Query to fetch additional instances.
56 | ;; Useful for instances that aren't fetched by :class-instances-query
57 | ;; e.g. block-level instances.
58 | ;; Defaults to nil
59 | :additional-instances-query nil})
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Description
2 |
3 | This is a [github action](https://github.com/features/actions) to export a
4 | configurable portion of a Logseq graph to [RDF](https://www.w3.org/RDF/). Some
5 | basic validation is also done on the exported rdf file. This action can also be
6 | run as a [CLI](#cli).
7 |
8 | ## Usage
9 |
10 | ### Setup
11 |
12 | By default, this action is configured to export the portion of your Logseq graph that:
13 |
14 | * has class pages with properties `type:: [[Class]]`
15 | * has property pages with properties `type:: [[Property]]`
16 | * has pages with properties `type:: [[X]]` where X are pages with `type:: [[Class]]`
17 |
18 | For an example of such a graph, see https://github.com/logseq/docs. If you would like
19 | to organize your graph differently, you can [configure it](#configuration).
20 |
21 | ### Github Action
22 |
23 | To setup this action, add the file `.github/workflows/ci.yml` to your graph's
24 | github repository with the following content:
25 |
26 | ``` yaml
27 | on: [push]
28 |
29 | jobs:
30 | rdf-export:
31 | runs-on: ubuntu-latest
32 | name: Test rdf export
33 | steps:
34 | - name: Checkout
35 | uses: actions/checkout@v4
36 |
37 | - name: Export graph as RDF
38 | uses: logseq/rdf-export@main
39 | ```
40 |
41 | That's it! This job will then run on future git pushes and build RDF files from your graph.
42 |
43 | NOTE: The above example defaults to picking up new changes. If you'd prefer to stay on a stable version use the format `logseq/rdf-export@VERSION` e.g. `logseq/rdf-export@v0.1.0`. See CHANGELOG.md for released versions.
44 |
45 | #### Action Inputs
46 |
47 | This action can take inputs e.g.:
48 |
49 | ```yaml
50 | - name: Export graph as RDF
51 | uses: logseq/rdf-export@main
52 | with:
53 | rdfFile: my-graph-name.ttl
54 | directory: logseq-graph-directory
55 | ```
56 |
57 | This action has the following inputs:
58 |
59 | ##### `rdfFile`
60 |
61 | **Required:** Name of the exported rdf file. Defaults to `test.ttl`.
62 |
63 | ##### `directory`
64 |
65 | Optional: The directory of the graph to rdf. Defaults to `.`.
66 |
67 | #### Use with other actions
68 |
69 | Since this action produces a valid RDF file, it is easy to save this file for
70 | later usage using [upload-artifact](https://github.com/actions/upload-artifact):
71 |
72 | ```yaml
73 | ...
74 | - name: Export graph as RDF
75 | uses: logseq/rdf-export@main
76 | with:
77 | rdfFile: my-graph.ttl
78 |
79 | - uses: actions/upload-artifact@v4
80 | with:
81 | name: Exported RDF
82 | path: my-graph.ttl
83 | ```
84 |
85 | ### CLI
86 |
87 | To use this as a CLI locally, first install
88 | [babashka](https://github.com/babashka/babashka#installation) and
89 | [clojure](https://clojure.org/guides/install_clojure). Then:
90 |
91 | ```sh
92 | $ git clone https://github.com/logseq/rdf-export
93 | $ cd rdf-export && yarn install
94 | $ yarn global add $PWD
95 | ```
96 |
97 | Then use it from any logseq graph directory!
98 | ```sh
99 | $ logseq-rdf-export docs.ttl
100 | Parsing 301 files...
101 | ...
102 | Writing 295 triples to file docs.ttl
103 | ```
104 |
105 | ## Configuration
106 |
107 | To configure how and what is exported to RDF, create a `.rdf-export/config.edn`
108 | file in your graph's directory. It's recommended to configure the `:base-url`
109 | key so that urls point to your Logseq graph. To configure what is exported,
110 | knowledge of [advanced
111 | queries](https://docs.logseq.com/#/page/advanced%20queries) is required. See
112 | [the config
113 | file](https://github.com/logseq/rdf-export/blob/main/src/logseq/rdf_export/config.cljs)
114 | for the full list of configuration keys.
115 |
116 | ## Development
117 |
118 | This github action use [nbb-logseq](https://github.com/logseq/nbb-logseq) and the [graph-parser
119 | library](https://github.com/logseq/logseq/tree/master/deps/graph-parser) to export a Logseq graph
120 | from its database.
121 |
122 | ## LICENSE
123 | See LICENSE.md
124 |
125 | ## Additional Links
126 | * https://github.com/logseq/graph-validator - Github action that this one is modeled after
127 | * https://github.com/Matdata-eu/logseq-rdf-export-docker - Docker image of this repository which
128 | also supports GitLab use
129 | * https://github.com/rdfjs/N3.js - Library that handles the rdf exporting
130 | * https://github.com/logseq/docs - Logseq graph that uses this action
131 |
--------------------------------------------------------------------------------
/src/logseq/rdf_export.cljs:
--------------------------------------------------------------------------------
1 | (ns logseq.rdf-export
2 | "This ns converts a subset of a Logseq graph to an rdf file using
3 | https://github.com/rdfjs/N3.js'
4 |
5 | All of the above pages can be customized with query config options."
6 | (:require ["n3" :refer [DataFactory Writer]]
7 | ["fs" :as fs]
8 | ["path" :as path]
9 | [clojure.string :as string]
10 | [clojure.edn :as edn]
11 | [clojure.set :as set]
12 | [datascript.core :as d]
13 | [logseq.db.file-based.rules :as file-rules]
14 | [babashka.cli :as cli]
15 | [logseq.graph-parser.cli :as gp-cli]
16 | [logseq.rdf-export.config :as config]
17 | [datascript.transit :as dt]))
18 |
19 | (defn- create-entities
20 | "Given a seq of block maps and config options, create entities which consist
21 | of the block's properties and a few built in block attributes"
22 | [{:keys [exclude-properties expand-entity-fn]} result]
23 | (map
24 | (fn [block]
25 | (let [block-name (or (get-in block [:block/properties :title])
26 | (:block/title block)
27 | ;; Use page name for non-journal pre-blocks
28 | (when-not (get-in block [:block/page :block/journal?])
29 | (get-in block [:block/page :block/title])))]
30 | (cond->
31 | (-> (:block/properties block)
32 | ;; TODO: Add proper tags support
33 | (dissoc :title :tags)
34 | ((fn [x] (apply dissoc x exclude-properties)))
35 | expand-entity-fn)
36 | (some? block-name)
37 | (assoc :block/title block-name))))
38 | result))
39 |
40 | (defn- page-url [page-name config]
41 | (str (:base-url config) (js/encodeURIComponent page-name)))
42 |
43 | ;; overly permissive but nothing harmful yet
44 | (defn- url? [s]
45 | (re-matches #"\S+://\S+" s))
46 |
47 | (defn- triplify
48 | "Turns an entity map into a coll of triples"
49 | [m
50 | {:keys [url-property type-property classes-without-ids unique-id-properties] :as config}
51 | property-map]
52 | (if-let [subject (if (:block/title m)
53 | (page-url (:block/title m) config)
54 | (some #(when-let [v (m %)]
55 | (if (url? v) v (page-url v config)))
56 | unique-id-properties))]
57 | (mapcat
58 | (fn [prop]
59 | (map #(vector
60 | subject
61 | ;; predicate
62 | (or (url-property (get property-map prop))
63 | (page-url (name prop) config))
64 | ;; object
65 | %)
66 | (let [v (m prop)]
67 | ;; If a collection, they are refs/pages
68 | (if (coll? v) (map #(page-url % config) v) [v]))))
69 | (keys m))
70 | (do
71 | (when (empty? (set/intersection classes-without-ids (m type-property)))
72 | (println "Skip entity b/c no name or url for entity - " (pr-str m)))
73 | [])))
74 |
75 | (defn- block->label-triple [block]
76 | [(:url block)
77 | "http://www.w3.org/2000/01/rdf-schema#label"
78 | (:block/title block)])
79 |
80 | (defn- build-alias-triples
81 | [ents config]
82 | (->> ents
83 | (filter :alias)
84 | (mapcat #(map (fn [alias]
85 | (block->label-triple
86 | {:url (page-url alias config)
87 | :block/title (:block/title %)}))
88 | (:alias %)))))
89 |
90 | (defn- add-class-instances [db config property-map {:keys [add-labels]}]
91 | (let [ents (->> (d/q (:class-instances-query config)
92 | db
93 | [(:page-property file-rules/query-dsl-rules)])
94 | (map first)
95 | (create-entities config))]
96 | (concat
97 | (mapcat #(triplify % config property-map) ents)
98 | (when add-labels
99 | (build-alias-triples ents config)))))
100 |
101 | (defn- add-additional-instances [db config property-map {:keys [add-labels]}]
102 | (let [ents (->> (d/q (:additional-instances-query config)
103 | db
104 | [])
105 | (map first)
106 | (create-entities config))]
107 | (concat
108 | (mapcat #(triplify % config property-map) ents)
109 | (when add-labels
110 | (build-alias-triples ents config)))))
111 |
112 | (defn- create-quads [_writer db config {:keys [add-labels] :as options}]
113 | (let [properties (->> (d/q (:property-query config)
114 | db
115 | [(:page-property file-rules/query-dsl-rules)])
116 | (map first)
117 | (create-entities config))
118 | built-in-properties {:block/title
119 | {:url (if add-labels
120 | "http://www.w3.org/2000/01/rdf-schema#label"
121 | "https://schema.org/name")}
122 | :alias
123 | {:url (if add-labels
124 | "http://www.w3.org/2002/07/owl#sameAs"
125 | "https://schema.org/sameAs")}}
126 | property-map (into built-in-properties
127 | (map (juxt (comp keyword :block/title) identity)
128 | properties))]
129 | (set
130 | (concat
131 | (add-class-instances db config property-map options)
132 | (when (seq (:additional-instances-query config))
133 | (add-additional-instances db config property-map options))
134 | (when add-labels
135 | (map (fn [[k v]]
136 | (block->label-triple
137 | {:url (:url v) :block/title (name k)}))
138 | (dissoc built-in-properties :block/title)))))))
139 |
140 | (defn- add-quads [writer quads]
141 | (doseq [[q1 q2 q3]
142 | (map (fn [q]
143 | (map #(if (and (string? %) (url? %))
144 | (.namedNode DataFactory %)
145 | (.literal DataFactory %))
146 | q))
147 | (sort quads))]
148 | (.addQuad writer (.quad DataFactory q1 q2 q3))))
149 |
150 | (defn- read-config [config]
151 | (try
152 | (edn/read-string config)
153 | (catch :default _
154 | (println "Error: Failed to parse config. Make sure it is valid EDN")
155 | (js/process.exit 1))))
156 |
157 | (defn get-graph-config [dir user-config]
158 | (merge-with (fn [v1 v2]
159 | (if (and (map? v1) (map? v2))
160 | (merge v1 v2) v2))
161 | config/default-config
162 | (when (fs/existsSync (path/join dir ".rdf-export" "config.edn"))
163 | (read-config
164 | (str (fs/readFileSync (path/join dir ".rdf-export" "config.edn")))))
165 | (when (seq user-config)
166 | (read-config user-config))))
167 |
168 | (def spec
169 | "Options spec"
170 | ;; Adds labels for all entities that are missing them e.g. properties and
171 | ;; aliased entities
172 | {:add-labels {:coerce :boolean
173 | :alias :a
174 | :desc "Add rdfs:labels for all entities"}
175 | :cache-dir {:alias :C
176 | :desc "Cache directory for db"}
177 | :config {:alias :c
178 | :desc "Edn config map"}
179 | :directory {:desc "Graph directory to export"
180 | :alias :d
181 | :default "."}
182 | :help {:alias :h
183 | :coerce :boolean
184 | :desc "Print help"}})
185 |
186 | (defn- get-db
187 | "If cached db exists get it, otherwise parse for a fresh db"
188 | [graph-dir cache-dir]
189 | ;; cache-db from https://github.com/logseq/bb-tasks
190 | (let [cache-file (path/join (or cache-dir ".") ".cached-db-transit.json")]
191 | (if (fs/existsSync cache-file)
192 | (do
193 | (println "Reading from cached db")
194 | (dt/read-transit-str (fs/readFileSync cache-file)))
195 | (let [{:keys [conn]} (gp-cli/parse-graph graph-dir {:verbose false})] @conn))))
196 |
197 | (defn- macro-subs
198 | [macro-content arguments]
199 | (loop [s macro-content
200 | args arguments
201 | n 1]
202 | (if (seq args)
203 | (recur
204 | (string/replace s (str "$" n) (first args))
205 | (rest args)
206 | (inc n))
207 | s)))
208 |
209 | (defn- macro-expand-entity
210 | "Checks each ent value for a macro and expands it if there's a logseq config for it"
211 | [m logseq-config]
212 | (update-vals m
213 | #(if-let [[_ macro args] (and (string? %)
214 | (seq (re-matches #"\{\{(\S+)\s+(.*)\}\}" %)))]
215 | (if-let [content (get-in logseq-config [:macros macro])]
216 | (macro-subs content (string/split args #"\s+"))
217 | %)
218 | %)))
219 |
220 | (defn write-rdf-file
221 | "Given a graph's dir, covert to rdf and write to given file."
222 | [dir file & [options]]
223 | (let [graph-config (get-graph-config dir (:config options))
224 | db (get-db dir (:cache-dir options))
225 | logseq-config (if (fs/existsSync (path/join dir "logseq" "config.edn"))
226 | (-> (path/join dir "logseq" "config.edn") fs/readFileSync str edn/read-string)
227 | {})
228 | writer (Writer. (clj->js {:prefixes (:prefixes graph-config)
229 | :format (:format graph-config)}))
230 | graph-config' (if (:expand-macros graph-config)
231 | (assoc graph-config :expand-entity-fn #(macro-expand-entity % logseq-config))
232 | (assoc graph-config :expand-entity-fn identity))
233 | quads (create-quads writer db graph-config' options)]
234 | (add-quads writer quads)
235 | (.end writer (fn [_err result]
236 | (println "Writing" (count quads) "triples to file" file)
237 | (fs/writeFileSync file result)))))
238 |
239 | (defn -main [& args]
240 | (let [{:keys [directory help] :as options} (cli/parse-opts args {:spec spec})
241 | _ (when (or help (zero? (count args)))
242 | (println (str "Usage: logseq-rdf-export FILE [OPTIONS]\nOptions:\n"
243 | (cli/format-opts {:spec spec})))
244 | (js/process.exit 1))
245 | ;; In CI, move up a directory since the script is run in subdirectory of
246 | ;; a project
247 | directory' (if js/process.env.CI (path/join ".." directory) directory)]
248 | (write-rdf-file directory' (first args) (select-keys options [:cache-dir :config :add-labels]))))
249 |
250 | #js {:main -main}
251 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@logseq/nbb-logseq@logseq/nbb-logseq#feat-db-v24":
6 | version "1.2.173-feat-db-v24"
7 | resolved "https://codeload.github.com/logseq/nbb-logseq/tar.gz/3d5b78b0382c7253bf9874c1f38586dd338434f4"
8 | dependencies:
9 | import-meta-resolve "^4.1.0"
10 |
11 | abort-controller@^3.0.0:
12 | version "3.0.0"
13 | resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
14 | integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
15 | dependencies:
16 | event-target-shim "^5.0.0"
17 |
18 | ansi-regex@^2.0.0:
19 | version "2.1.1"
20 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
21 | integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==
22 |
23 | ansi-regex@^3.0.0:
24 | version "3.0.1"
25 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1"
26 | integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==
27 |
28 | base64-js@^1.3.1:
29 | version "1.5.1"
30 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
31 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
32 |
33 | buffer@^6.0.3:
34 | version "6.0.3"
35 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
36 | integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
37 | dependencies:
38 | base64-js "^1.3.1"
39 | ieee754 "^1.2.1"
40 |
41 | camelcase@^5.0.0:
42 | version "5.3.1"
43 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
44 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
45 |
46 | cliui@^4.0.0:
47 | version "4.1.0"
48 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
49 | integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==
50 | dependencies:
51 | string-width "^2.1.1"
52 | strip-ansi "^4.0.0"
53 | wrap-ansi "^2.0.0"
54 |
55 | code-point-at@^1.0.0:
56 | version "1.1.0"
57 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
58 | integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==
59 |
60 | cross-spawn@^6.0.0:
61 | version "6.0.5"
62 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
63 | integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
64 | dependencies:
65 | nice-try "^1.0.4"
66 | path-key "^2.0.1"
67 | semver "^5.5.0"
68 | shebang-command "^1.2.0"
69 | which "^1.2.9"
70 |
71 | decamelize@^1.2.0:
72 | version "1.2.0"
73 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
74 | integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
75 |
76 | end-of-stream@^1.1.0:
77 | version "1.4.4"
78 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
79 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
80 | dependencies:
81 | once "^1.4.0"
82 |
83 | event-target-shim@^5.0.0:
84 | version "5.0.1"
85 | resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
86 | integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
87 |
88 | events@^3.3.0:
89 | version "3.3.0"
90 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
91 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
92 |
93 | execa@^1.0.0:
94 | version "1.0.0"
95 | resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
96 | integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
97 | dependencies:
98 | cross-spawn "^6.0.0"
99 | get-stream "^4.0.0"
100 | is-stream "^1.1.0"
101 | npm-run-path "^2.0.0"
102 | p-finally "^1.0.0"
103 | signal-exit "^3.0.0"
104 | strip-eof "^1.0.0"
105 |
106 | find-up@^3.0.0:
107 | version "3.0.0"
108 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
109 | integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
110 | dependencies:
111 | locate-path "^3.0.0"
112 |
113 | get-caller-file@^1.0.1:
114 | version "1.0.3"
115 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
116 | integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
117 |
118 | get-stream@^4.0.0:
119 | version "4.1.0"
120 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
121 | integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
122 | dependencies:
123 | pump "^3.0.0"
124 |
125 | ieee754@^1.2.1:
126 | version "1.2.1"
127 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
128 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
129 |
130 | import-meta-resolve@^4.1.0:
131 | version "4.1.0"
132 | resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz#f9db8bead9fafa61adb811db77a2bf22c5399706"
133 | integrity sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==
134 |
135 | invert-kv@^2.0.0:
136 | version "2.0.0"
137 | resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
138 | integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
139 |
140 | is-fullwidth-code-point@^1.0.0:
141 | version "1.0.0"
142 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
143 | integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==
144 | dependencies:
145 | number-is-nan "^1.0.0"
146 |
147 | is-fullwidth-code-point@^2.0.0:
148 | version "2.0.0"
149 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
150 | integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==
151 |
152 | is-stream@^1.1.0:
153 | version "1.1.0"
154 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
155 | integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
156 |
157 | isexe@^2.0.0:
158 | version "2.0.0"
159 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
160 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
161 |
162 | lcid@^2.0.0:
163 | version "2.0.0"
164 | resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
165 | integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==
166 | dependencies:
167 | invert-kv "^2.0.0"
168 |
169 | locate-path@^3.0.0:
170 | version "3.0.0"
171 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
172 | integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
173 | dependencies:
174 | p-locate "^3.0.0"
175 | path-exists "^3.0.0"
176 |
177 | map-age-cleaner@^0.1.1:
178 | version "0.1.3"
179 | resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
180 | integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
181 | dependencies:
182 | p-defer "^1.0.0"
183 |
184 | mem@^4.0.0:
185 | version "4.3.0"
186 | resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
187 | integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==
188 | dependencies:
189 | map-age-cleaner "^0.1.1"
190 | mimic-fn "^2.0.0"
191 | p-is-promise "^2.0.0"
192 |
193 | mimic-fn@^2.0.0:
194 | version "2.1.0"
195 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
196 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
197 |
198 | mldoc@^1.5.9:
199 | version "1.5.9"
200 | resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-1.5.9.tgz#43d740351c64285f0f4988ac9497922d54ae66fc"
201 | integrity sha512-87FQ7hseS87tsk+VdpIigpu8LH+GwmbbFgpxgFwvnbH5oOjmIrc47laH4Dyggzqiy8/vMjDHkl7vsId0eXhCDQ==
202 | dependencies:
203 | yargs "^12.0.2"
204 |
205 | n3@^1.16.3, n3@^1.4.0:
206 | version "1.16.3"
207 | resolved "https://registry.yarnpkg.com/n3/-/n3-1.16.3.tgz#d339dca14c79648b1595a3252c5410b800b896f8"
208 | integrity sha512-9caLSZuMW1kdlPxEN4ka6E4E8a5QKoZ2emxpW+zHMofI+Bo92nJhN//wNub15S5T9I4c6saEqdGEu+YXJqMZVA==
209 | dependencies:
210 | queue-microtask "^1.1.2"
211 | readable-stream "^4.0.0"
212 |
213 | nice-try@^1.0.4:
214 | version "1.0.5"
215 | resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
216 | integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
217 |
218 | npm-run-path@^2.0.0:
219 | version "2.0.2"
220 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
221 | integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==
222 | dependencies:
223 | path-key "^2.0.0"
224 |
225 | number-is-nan@^1.0.0:
226 | version "1.0.1"
227 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
228 | integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==
229 |
230 | once@^1.3.1, once@^1.4.0:
231 | version "1.4.0"
232 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
233 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
234 | dependencies:
235 | wrappy "1"
236 |
237 | os-locale@^3.0.0:
238 | version "3.1.0"
239 | resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
240 | integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
241 | dependencies:
242 | execa "^1.0.0"
243 | lcid "^2.0.0"
244 | mem "^4.0.0"
245 |
246 | p-defer@^1.0.0:
247 | version "1.0.0"
248 | resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
249 | integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==
250 |
251 | p-finally@^1.0.0:
252 | version "1.0.0"
253 | resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
254 | integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
255 |
256 | p-is-promise@^2.0.0:
257 | version "2.1.0"
258 | resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
259 | integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
260 |
261 | p-limit@^2.0.0:
262 | version "2.3.0"
263 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
264 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
265 | dependencies:
266 | p-try "^2.0.0"
267 |
268 | p-locate@^3.0.0:
269 | version "3.0.0"
270 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
271 | integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
272 | dependencies:
273 | p-limit "^2.0.0"
274 |
275 | p-try@^2.0.0:
276 | version "2.2.0"
277 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
278 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
279 |
280 | path-exists@^3.0.0:
281 | version "3.0.0"
282 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
283 | integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==
284 |
285 | path-key@^2.0.0, path-key@^2.0.1:
286 | version "2.0.1"
287 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
288 | integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==
289 |
290 | process@^0.11.10:
291 | version "0.11.10"
292 | resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
293 | integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
294 |
295 | pump@^3.0.0:
296 | version "3.0.0"
297 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
298 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
299 | dependencies:
300 | end-of-stream "^1.1.0"
301 | once "^1.3.1"
302 |
303 | queue-microtask@^1.1.2:
304 | version "1.2.3"
305 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
306 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
307 |
308 | readable-stream@^4.0.0:
309 | version "4.3.0"
310 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.3.0.tgz#0914d0c72db03b316c9733bb3461d64a3cc50cba"
311 | integrity sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ==
312 | dependencies:
313 | abort-controller "^3.0.0"
314 | buffer "^6.0.3"
315 | events "^3.3.0"
316 | process "^0.11.10"
317 |
318 | require-directory@^2.1.1:
319 | version "2.1.1"
320 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
321 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
322 |
323 | require-main-filename@^1.0.1:
324 | version "1.0.1"
325 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
326 | integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==
327 |
328 | semver@^5.5.0:
329 | version "5.7.1"
330 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
331 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
332 |
333 | set-blocking@^2.0.0:
334 | version "2.0.0"
335 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
336 | integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
337 |
338 | shebang-command@^1.2.0:
339 | version "1.2.0"
340 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
341 | integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==
342 | dependencies:
343 | shebang-regex "^1.0.0"
344 |
345 | shebang-regex@^1.0.0:
346 | version "1.0.0"
347 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
348 | integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==
349 |
350 | signal-exit@^3.0.0:
351 | version "3.0.7"
352 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
353 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
354 |
355 | string-width@^1.0.1:
356 | version "1.0.2"
357 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
358 | integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==
359 | dependencies:
360 | code-point-at "^1.0.0"
361 | is-fullwidth-code-point "^1.0.0"
362 | strip-ansi "^3.0.0"
363 |
364 | string-width@^2.0.0, string-width@^2.1.1:
365 | version "2.1.1"
366 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
367 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
368 | dependencies:
369 | is-fullwidth-code-point "^2.0.0"
370 | strip-ansi "^4.0.0"
371 |
372 | strip-ansi@^3.0.0, strip-ansi@^3.0.1:
373 | version "3.0.1"
374 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
375 | integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==
376 | dependencies:
377 | ansi-regex "^2.0.0"
378 |
379 | strip-ansi@^4.0.0:
380 | version "4.0.0"
381 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
382 | integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==
383 | dependencies:
384 | ansi-regex "^3.0.0"
385 |
386 | strip-eof@^1.0.0:
387 | version "1.0.0"
388 | resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
389 | integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==
390 |
391 | turtle-validator@^1.1.1:
392 | version "1.1.1"
393 | resolved "https://registry.yarnpkg.com/turtle-validator/-/turtle-validator-1.1.1.tgz#7077544a85ed330231fa1cab15bac18cf17c0f39"
394 | integrity sha512-k7HgLYUATigmdMvU7cdzvW6hOORwX7tBLBoFzXC0wIlN1hrvmJcJouElc+qVvIiJlBkiDY8jkxMenQ+HrVyS9w==
395 | dependencies:
396 | n3 "^1.4.0"
397 |
398 | which-module@^2.0.0:
399 | version "2.0.0"
400 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
401 | integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==
402 |
403 | which@^1.2.9:
404 | version "1.3.1"
405 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
406 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
407 | dependencies:
408 | isexe "^2.0.0"
409 |
410 | wrap-ansi@^2.0.0:
411 | version "2.1.0"
412 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
413 | integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==
414 | dependencies:
415 | string-width "^1.0.1"
416 | strip-ansi "^3.0.1"
417 |
418 | wrappy@1:
419 | version "1.0.2"
420 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
421 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
422 |
423 | "y18n@^3.2.1 || ^4.0.0":
424 | version "4.0.3"
425 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
426 | integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
427 |
428 | yargs-parser@^11.1.1:
429 | version "11.1.1"
430 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
431 | integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==
432 | dependencies:
433 | camelcase "^5.0.0"
434 | decamelize "^1.2.0"
435 |
436 | yargs@^12.0.2:
437 | version "12.0.5"
438 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
439 | integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
440 | dependencies:
441 | cliui "^4.0.0"
442 | decamelize "^1.2.0"
443 | find-up "^3.0.0"
444 | get-caller-file "^1.0.1"
445 | os-locale "^3.0.0"
446 | require-directory "^2.1.1"
447 | require-main-filename "^1.0.1"
448 | set-blocking "^2.0.0"
449 | string-width "^2.0.0"
450 | which-module "^2.0.0"
451 | y18n "^3.2.1 || ^4.0.0"
452 | yargs-parser "^11.1.1"
453 |
--------------------------------------------------------------------------------
/test/fixtures/docs.ttl:
--------------------------------------------------------------------------------
1 | @prefix s: .
2 | @prefix d: .
3 |
4 | d:Academic a d:FeatureTag;
5 | s:name "Academic".
6 | a d:Feature;
7 | d:platforms ;
8 | s:description "Advanced queries are written with [Datalog](https://en.wikipedia.org/wiki/Datalog) and query the [Datascript](https://github.com/tonsky/datascript) database.";
9 | s:name "Advanced Queries".
10 | a d:Feature;
11 | d:platforms , ;
12 | s:description "Advanced functionality that can be invoked from any block";
13 | s:name "Advanced commands".
14 | a d:Platform;
15 | s:name "All Platforms".
16 | a d:Feature;
17 | d:platforms ;
18 | s:description "Page dedicated to page management - search, delete and sort pages.";
19 | s:name "All pages".
20 | d:Android a d:Platform;
21 | s:name "Android".
22 | a d:Feature;
23 | d:initial-version "unreleased";
24 | d:platforms d:Desktop;
25 | s:name "Assets alias".
26 | a d:Feature;
27 | d:platforms ;
28 | s:description "Clickable link to a particular Logseq block e.g. `((123e4567-e89b-12d3-a456-426614174000))`. Produced by putting a unique [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) inside parenthesis `(())`";
29 | s:name "Block Reference";
30 | s:sameAs .
31 | a d:Feature;
32 | d:platforms ;
33 | s:description "Also known as block embedding, this allows a portion of a page to be displayed within another. Edits made to the embedded content are also made in the referenced content.";
34 | s:name "Block embed";
35 | s:sameAs .
36 | d:Boolean a d:Class;
37 | s:name "Boolean";
38 | s:url s:Boolean;
39 | d:DataType.
40 | d:Calculator a d:Command;
41 | s:description "The calculator supports basic operations like `+ - / * ^` and advanced operations (factorial, modular division, and scientific functions).";
42 | s:name "Calculator".
43 | d:Class a d:Class;
44 | d:sameas ;
45 | s:description "Defines user defined classes/types in this graph";
46 | s:name "Class";
47 | s:url d:Class;
48 | d:Thing.
49 | a d:Feature;
50 | d:platforms , ;
51 | s:description "Run ClojureScript in a block using [sci](https://github.com/babashka/sci)";
52 | s:name "ClojureScript Eval in a Block".
53 | d:Cloze a d:Command;
54 | s:description d:Flashcards;
55 | s:name "Cloze".
56 | a d:Feature;
57 | d:platforms ;
58 | s:description d:Codemirror;
59 | s:name "Code block".
60 | d:Command a d:Class;
61 | s:description , ;
62 | s:name "Command";
63 | s:url d:Command;
64 | d:Feature.
65 | d:Commands a d:Feature;
66 | d:platforms , ;
67 | s:description "Functionality that can be invoked from any block";
68 | s:name "Commands".
69 | a d:Feature;
70 | d:platforms , ;
71 | s:description "Describes copy and the difference between formatted and raw paste";
72 | s:name "Copy and Paste".
73 | a d:Feature;
74 | d:platforms , ;
75 | s:name "Custom theme".
76 | d:DataType a d:Class;
77 | s:description "Provides basic data types such as integers, strings, etc. See https://www.w3.org/TR/rdf12-concepts/#section-Datatypes for additional datatypes that could be possible";
78 | s:name "DataType";
79 | s:url s:DataType;
80 | d:Class.
81 | d:Desktop a d:Platform;
82 | s:description "Desktop environments we support are osx, linux and windows. We use [Electron](https://www.electronjs.org/) for desktop.";
83 | s:name "Desktop".
84 | d:Draw a d:Command;
85 | s:description "Draw in blocks using an embedded Excalidraw canvas";
86 | s:name "Draw".
87 | d:Export a d:Feature;
88 | d:platforms ;
89 | s:description "The Logseq Export feature allows users to export their data in various formats, including text, HTML, OPML, PNG, EDN, JSON, and standard Markdown. It supports exporting text selections, blocks, individual pages, or the entire graph with customizable options.";
90 | s:name "Export".
91 | d:Feature a d:Class;
92 | s:description "A user-facing piece of functionality. This can be a small piece or it can be a big one that consists of subfeatures";
93 | s:name "Feature";
94 | s:url d:Feature;
95 | d:Thing.
96 | d:FeatureTag a d:Class;
97 | s:description "Tags to categorize features";
98 | s:name "FeatureTag";
99 | s:url d:FeatureTag;
100 | d:Thing.
101 | a d:Feature;
102 | d:initial-version "0.8.9";
103 | d:platforms d:Desktop;
104 | s:description "Allow users to migrate the filenames to the latest format";
105 | s:name "Filename format".
106 | a d:Feature;
107 | d:initial-version "0.8.3";
108 | d:platforms d:Desktop;
109 | s:description "Finds any text that is visible or loaded into the current page";
110 | s:name "Find in page".
111 | d:Flashcards a d:Feature;
112 | d:platforms ;
113 | s:description "Cards are blocks that are intended to be used as an aid in memorization";
114 | s:name "Flashcards".
115 | a d:Feature;
116 | d:platforms d:Desktop;
117 | s:description "Automatically save commit changes to a git repository.";
118 | s:name "Git Auto-Commit".
119 | a d:Feature;
120 | d:initial-version "0.8.6";
121 | d:platforms d:Desktop;
122 | s:description ;
123 | s:name "Global config.edn".
124 | a d:Feature;
125 | d:initial-version "0.8.6";
126 | d:platforms d:Desktop;
127 | s:description , ;
128 | s:name "Global configuration".
129 | d:Handbook a d:Feature;
130 | d:initial-version "0.9.20";
131 | d:platforms , ;
132 | s:description "Provides in app documentation in the form of short tutorials";
133 | s:name "Handbook".
134 | d:Headings a d:Feature;
135 | d:platforms ;
136 | s:description "Creating headings on a page";
137 | s:name "Headings".
138 | d:Import a d:Feature;
139 | d:platforms , ;
140 | s:name "Import".
141 | a d:Feature;
142 | d:platforms ;
143 | s:name "Journals page".
144 | a d:Feature;
145 | d:platforms ;
146 | s:description "Provides keyboards shortcuts for running core commands and actions. Shortcuts can be customized through user configuration.";
147 | s:name "Keyboard shortcuts".
148 | a d:Feature;
149 | d:platforms ;
150 | s:description "Graph view of your whole graph";
151 | s:name "Knowledge Graph";
152 | s:sameAs .
153 | a ;
154 | s:name "Left sidebar".
155 | a d:Feature;
156 | d:platforms ;
157 | s:name "Linked References".
158 | a d:Feature;
159 | d:initial-version "0.8.15";
160 | d:platforms d:Desktop;
161 | s:description "local HTTP server to access logseq's graph";
162 | s:name "Local Http server".
163 | a d:Feature;
164 | d:platforms , , d:Web;
165 | s:description "Paid feature that provides encrypted synchronization of graphs between devices.";
166 | s:name "Logseq Sync".
167 | a d:Feature;
168 | d:platforms ;
169 | s:name "Logseq Sync Encryption".
170 | d:Macros a d:Feature;
171 | d:platforms ;
172 | s:description "Provides a way to write and maintain reusable text. This text can render as html and can invoke some other features";
173 | s:name "Macros".
174 | a d:Feature;
175 | d:platforms ;
176 | s:description "Write and render math using https://katex.org/ syntax";
177 | s:name "Math Block".
178 | d:Namespaces a d:Feature;
179 | d:platforms ;
180 | s:description "Used to group a set of related pages";
181 | s:name "Namespaces".
182 | a d:Feature;
183 | d:initial-version "0.9.5";
184 | d:platforms ;
185 | s:description "Provides numbered (ordered) lists with each list item being a block.";
186 | s:name "Numbered List".
187 | a d:Feature;
188 | d:platforms d:Desktop;
189 | s:name "PDF highlights".
190 | a d:Feature;
191 | d:platforms ;
192 | s:name "Page and block references".
193 | a d:Feature;
194 | d:platforms ;
195 | s:description ;
196 | s:name "Page embed";
197 | s:sameAs .
198 | a d:Feature;
199 | d:platforms ;
200 | s:description ;
201 | s:name "Page graph".
202 | d:Platform a d:Class;
203 | s:description "One or more platforms, usually for a feature";
204 | s:name "Platform";
205 | s:url d:Platform;
206 | d:Thing.
207 | d:Plugins a d:Feature;
208 | d:platforms d:Desktop;
209 | s:description "Extends the functionality of logseq with third party tools";
210 | s:name "Plugins".
211 | d:Properties a d:Feature;
212 | d:platforms ;
213 | s:description "Annotates any block or page with multiple pairs of values e.g. `rating:: 8` or `name:: foo`. Building block for organizing graphs";
214 | s:name "Properties".
215 | d:Property a d:Class;
216 | d:sameas ;
217 | s:description "Defines user defined properties in this graph";
218 | s:name "Property";
219 | s:url d:Property;
220 | d:Thing.
221 | a d:Platform;
222 | s:description d:Web;
223 | s:name "Publish Web".
224 | d:Publishing a d:Feature;
225 | d:platforms d:Desktop;
226 | s:description ;
227 | s:name "Publishing".
228 | d:Queries a d:Feature;
229 | d:platforms ;
230 | s:description "Also known as simple queries";
231 | s:name "Queries".
232 | d:Query a d:Command;
233 | s:description d:Queries;
234 | s:name "Query".
235 | a d:Feature;
236 | d:platforms ;
237 | s:description d:Queries;
238 | s:name "Query Builder".
239 | a d:Feature;
240 | d:initial-version "0.2.6";
241 | d:platforms ;
242 | s:description "This runs custom transformations on a query's results, usually to calculate aggregations";
243 | s:name "Query function".
244 | a ;
245 | s:description , d:Queries;
246 | s:name "Query table".
247 | a ;
248 | s:name "Right sidebar".
249 | d:Search a d:Feature;
250 | d:platforms ;
251 | s:name "Search".
252 | d:Settings a ;
253 | s:name "Settings".
254 | a d:Feature;
255 | d:initial-version "0.9.10";
256 | d:platforms ;
257 | s:description "Snap shapes to canvas grid";
258 | s:name "Snap to grid".
259 | d:String a d:Class;
260 | d:meta "Prefer the name string over text as it maps with xsd:string";
261 | s:name "String";
262 | s:url s:Text;
263 | d:DataType.
264 | d:StringWithRefs a d:Class;
265 | s:description "String that can have page references";
266 | s:name "StringWithRefs";
267 | s:url d:StringWithRefs;
268 | d:DataType.
269 | d:Tables a ;
270 | s:description "Tables are our first versioned component, accepting props to control the output.";
271 | s:name "Tables".
272 | d:Tags a d:Feature;
273 | d:platforms ;
274 | s:description "Annotates pages or blocks with a single value";
275 | s:name "Tags".
276 | d:Tasks a d:Feature;
277 | d:platforms ;
278 | s:name "Tasks";
279 | s:sameAs d:Todos.
280 | d:Thing a d:Class;
281 | s:description "The simplest concept which all classes inherit from.";
282 | s:name "Thing";
283 | s:url s:Thing.
284 | a d:Class;
285 | s:description "A well-defined piece of the UI that usually has a name";
286 | s:name "UI Element";
287 | s:url ;
288 | d:Thing.
289 | a d:Feature;
290 | d:platforms , ;
291 | s:description "Allows users to revert or reapply changes made during their editing sessions. It also enhances the user experience by providing a convenient way to correct mistakes and explore alternative edits.";
292 | s:name "Undo and Redo".
293 | a d:Feature;
294 | d:platforms ;
295 | s:name "Unlinked References".
296 | d:Uri a d:Class;
297 | d:meta "Couldn't use URL since we're case insensitive and url is already taken";
298 | s:name "Uri";
299 | s:url s:URL;
300 | d:DataType.
301 | a d:Feature;
302 | d:platforms ;
303 | s:description "Users can configure logseq with a number of files.";
304 | s:name "User configuration".
305 | d:Web a d:Platform;
306 | s:name "Web".
307 | d:Whiteboard a d:Feature;
308 | d:platforms ;
309 | s:description "Put thoughts from your knowledge base as well as new ones next to each other on a spatial canvas together with shapes, drawings, website embeds and connectors. Built on a fork of [tldraw](https://github.com/tldraw/tldraw).";
310 | s:name "Whiteboard";
311 | s:sameAs d:Whiteboards.
312 | a ;
313 | s:description "Selected objects (eg. drawing, shapes, blocks, pages) all have an Object Action Bar that allows the user to change it's appearance (eg. color, text size and style) or interact with it (link, open in right sidebar).";
314 | s:name "Whiteboard/Action Bar";
315 | s:sameAs .
316 | a ;
317 | s:description ;
318 | s:name "Whiteboard/Canvas";
319 | s:sameAs d:Canvas.
320 | a ;
321 | s:description ;
322 | s:name "Whiteboard/Context Menu";
323 | s:sameAs .
324 | a ;
325 | s:description "A page where you can manage your Whiteboards.";
326 | s:name "Whiteboard/Dashboard";
327 | s:sameAs .
328 | a d:Feature;
329 | d:initial-version "0.9.4";
330 | d:platforms , ;
331 | s:description "Allows locking whiteboard elements, rendering them unmodifiable";
332 | s:name "Whiteboard/Element locking";
333 | s:sameAs .
334 | a ;
335 | s:name "Whiteboard/Embed";
336 | s:sameAs .
337 | a d:Class;
338 | s:description d:Blocks, d:Graph, d:Pages, ;
339 | s:name "Whiteboard/Object";
340 | s:sameAs , ;
341 | s:url ;
342 | .
343 | a ;
344 | d:supports "Link to page/block, Mobile context menu";
345 | s:name "Whiteboard/Object/Image";
346 | s:sameAs d:Image.
347 | a ;
348 | d:supports "Edit PDF, Link to page/block";
349 | s:description "Embedded PDF";
350 | s:name "Whiteboard/Object/PDF";
351 | s:sameAs d:PDF.
352 | a ;
353 | d:supports "Url, Link to page/block, Mobile context menu";
354 | s:description "Embedded tweets";
355 | s:name "Whiteboard/Object/Tweet";
356 | s:sameAs d:Tweet, d:Tweets.
357 | a ;
358 | d:supports "Url, Link to page/block, Mobile context menu";
359 | s:description "Embedded Youtube videos";
360 | s:name "Whiteboard/Object/Youtube";
361 | s:sameAs d:Youtube, , .
362 | a ;
363 | d:supports "Reload, Url, Open, Link to page/block, Mobile context menu";
364 | s:name "Whiteboard/Object/iFrame";
365 | s:sameAs d:iFrame.
366 | a ;
367 | s:description d:Block, d:Canvas, , d:Page, d:Whiteboard;
368 | s:name "Whiteboard/Quick Add";
369 | s:sameAs .
370 | a d:Class;
371 | s:description ;
372 | s:name "Whiteboard/Tool";
373 | s:sameAs d:Tool, d:Tools, ;
374 | s:url ;
375 | d:Feature.
376 | a d:Tool, ;
377 | s:description "Connect any element on the canvas with a line. Add arrows to signal a direction. Add text on the connector. Can also be used to draw lines that are not connected to anything.";
378 | s:name "Whiteboard/Tool/Connector";
379 | s:sameAs d:Connector.
380 | a d:Tool, ;
381 | d:initial-version "0.8.12";
382 | d:platforms , ;
383 | s:description "Sets the global color";
384 | s:name "Whiteboard/Tool/Global color swatch";
385 | s:sameAs .
386 | a d:Tool, ;
387 | d:initial-version "0.9.3";
388 | d:platforms , ;
389 | s:description "Sets the global scale level";
390 | s:name "Whiteboard/Tool/Global scale select";
391 | s:sameAs .
392 | a d:Tool, ;
393 | s:description "Freeform highlighting on the canvas";
394 | s:name "Whiteboard/Tool/Highlight";
395 | s:sameAs d:Highlight.
396 | a d:Tool, ;
397 | d:supports "Color Swatch, Link to page/block, Mobile context menu";
398 | s:description "Freeform pencil drawings on the canvas";
399 | s:name "Whiteboard/Tool/Pencil";
400 | s:sameAs d:Pencil.
401 | a d:Tool, ;
402 | s:description "Create rectangle, circle and triangle shapes on the canvas";
403 | s:name "Whiteboard/Tool/Shape";
404 | s:sameAs d:Shape, d:Shapes.
405 | a d:Tool, ;
406 | s:description "Create circles";
407 | s:name "Whiteboard/Tool/Shape/Circle";
408 | s:sameAs d:Circle.
409 | a d:Tool, ;
410 | s:description "Create rectangles";
411 | s:name "Whiteboard/Tool/Shape/Rectangle";
412 | s:sameAs d:Rect, d:Rectangle.
413 | a d:Tool, ;
414 | s:description "Create triangles";
415 | s:name "Whiteboard/Tool/Shape/Triangle";
416 | s:sameAs d:Triangle.
417 | a d:Tool, ;
418 | s:description "Create text elements";
419 | s:name "Whiteboard/Tool/Text";
420 | s:sameAs d:Text.
421 | a ;
422 | s:name "Whiteboard/Toolbar";
423 | s:sameAs d:Toolbar.
424 | a d:Feature;
425 | d:platforms d:Desktop;
426 | s:name "Youtube timestamp".
427 | d:Zotero a d:Feature;
428 | d:platforms , ;
429 | s:description "Built in integration that helps import your Zotero items as pages seamlessly. [Zotero](https://www.zotero.org/) is a free, easy-to-use tool to help you collect, organize, cite, and share research.";
430 | s:name "Zotero".
431 | a d:Feature;
432 | d:platforms ;
433 | s:description "Local config file, `logseq/config.edn`, is the main configuration file for a graph";
434 | s:name "config.edn".
435 | a d:Feature;
436 | d:platforms ;
437 | s:description "Local config file, logseq/custom.css, loads custom css for a graph on startup";
438 | s:name "custom.css".
439 | a d:Feature;
440 | d:platforms ;
441 | s:description "Local config file, logseq/custom.js, loads custom js for a graph on startup";
442 | s:name "custom.js".
443 | d:description a d:Property;
444 | d:rangeIncludes d:StringWithRefs;
445 | s:name "description";
446 | s:url s:description.
447 | d:domainincludes a d:Property;
448 | d:domainIncludes d:Property;
449 | d:rangeIncludes d:Class;
450 | d:sameas s:domainIncludes;
451 | s:description "A more useful version of rdfs:domain as it can be one of multiple values";
452 | s:name "domainincludes";
453 | s:url d:domainIncludes.
454 | a d:Feature;
455 | d:platforms ;
456 | s:description "Local config file, logseq/export.css, loads custom css for a published graph";
457 | s:name "export.css".
458 | d:iOS a d:Platform;
459 | s:description "This refers to iOS on mobile. Only versions 14 and greater are supported.";
460 | s:name "iOS".
461 | d:initial-version a d:Property;
462 | d:domainIncludes d:Feature, d:Tool;
463 | d:rangeIncludes d:String;
464 | s:name "initial-version";
465 | s:url d:initial-version.
466 | d:meta a d:Property;
467 | d:rangeIncludes d:String;
468 | s:description "Meta description field which usually discusses organizing thing instead of thing itself";
469 | s:name "meta";
470 | s:url d:meta.
471 | d:name a d:Property;
472 | d:rangeIncludes d:String;
473 | d:unique true;
474 | s:name "name";
475 | s:url s:name.
476 | d:parent a d:Property;
477 | d:domainIncludes d:Class;
478 | d:rangeIncludes d:Class;
479 | s:description "Used to connect a class with its parent class";
480 | s:name "parent";
481 | s:url .
482 | d:platforms a d:Property;
483 | d:domainIncludes d:Feature, d:Tool;
484 | d:rangeIncludes d:Platform;
485 | s:name "platforms";
486 | s:url d:platforms.
487 | a d:Feature;
488 | d:initial-version "0.8.9";
489 | d:platforms d:Desktop;
490 | s:description d:Plugins;
491 | s:name "plugins.edn".
492 | d:rangeincludes a d:Property;
493 | d:domainIncludes d:Property;
494 | d:rangeIncludes d:Class;
495 | d:sameas s:rangeIncludes;
496 | s:description "List of values a property can have";
497 | s:name "rangeincludes";
498 | s:url d:rangeIncludes.
499 | d:sameAs a d:Property;
500 | d:rangeIncludes d:Uri;
501 | s:description "Indicates that two URIs are equivalent";
502 | s:name "sameAs";
503 | s:url .
504 | d:slide a d:Feature;
505 | d:platforms ;
506 | s:name "slide";
507 | s:sameAs d:Presentation.
508 | d:supports a d:Property;
509 | d:domainIncludes d:Tool, ;
510 | d:rangeIncludes d:String;
511 | s:name "supports";
512 | s:url d:supports.
513 | d:templates a d:Feature;
514 | d:platforms , ;
515 | s:name "templates".
516 | a d:Feature;
517 | d:platforms ;
518 | s:description "Provides a readable alias for a page. A page can have multiple aliases. Page references with the alias will automatically redirect to the original page";
519 | s:name "term/alias";
520 | s:sameAs .
521 | d:type a d:Property;
522 | d:rangeIncludes d:Class;
523 | s:name "type";
524 | s:url .
525 | d:unique a d:Property;
526 | d:domainIncludes d:Property;
527 | d:rangeIncludes d:Boolean;
528 | s:name "unique";
529 | s:url d:unique.
530 | d:url a d:Property;
531 | d:rangeIncludes d:Uri;
532 | d:unique true;
533 | s:name "url";
534 | s:url s:url.
535 |
--------------------------------------------------------------------------------
/test/fixtures/docs-with-labels.ttl:
--------------------------------------------------------------------------------
1 | @prefix s: .
2 | @prefix d: .
3 |
4 | "alias".
5 | d:Academic a d:FeatureTag;
6 | "Academic".
7 | a d:Feature;
8 | "Advanced Queries";
9 | d:platforms .
10 | a d:Feature;
11 | "Advanced commands";
12 | d:platforms , .
13 | a d:Platform;
14 | "All Platforms".
15 | a d:Feature;
16 | "All pages";
17 | d:platforms .
18 | d:Android a d:Platform;
19 | "Android".
20 | a d:Feature;
21 | "Assets alias";
22 | d:platforms d:Desktop.
23 | a d:Feature;
24 | "Block Reference";
25 | ;
26 | d:platforms .
27 | a d:Feature;
28 | "Block embed";
29 | ;
30 | d:platforms .
31 | d:Boolean a d:Class;
32 | "Boolean";
33 | s:url s:Boolean;
34 | d:DataType.
35 | d:Calculator a d:Command;
36 | "Calculator".
37 | d:Canvas "Whiteboard/Canvas".
38 | d:Circle "Whiteboard/Tool/Shape/Circle".
39 | d:Class a d:Class;
40 | "Class";
41 | d:sameas