mirror of https://github.com/logseq/logseq
Working POC!
parent
a748b4f6b3
commit
76c4e49f34
4
bb.edn
4
bb.edn
|
@ -34,6 +34,10 @@
|
|||
dev:build-publishing
|
||||
logseq.tasks.dev/build-publishing
|
||||
|
||||
dev:publish
|
||||
(apply shell {:dir "deps/publish-spa"} "nbb-logseq -cp src -m logseq.publish-spa"
|
||||
*command-line-args*)
|
||||
|
||||
dev:npx-cap-run-ios
|
||||
logseq.tasks.dev.mobile/npx-cap-run-ios
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
/.clj-kondo/.cache
|
||||
.nbb
|
|
@ -0,0 +1,4 @@
|
|||
{:deps
|
||||
{logseq/graph-parser
|
||||
;; Nbb bug. Should just be "../graph-parser"
|
||||
{:local/root "../../../../graph-parser"}}}
|
|
@ -1,16 +1,19 @@
|
|||
(ns logseq.tasks.dev.publish
|
||||
(ns logseq.publish-spa
|
||||
(:require [promesa.core :as p]
|
||||
["path" :as path]
|
||||
["fs-extra$default" :as fs]))
|
||||
["fs-extra$default" :as fs]
|
||||
[datascript.transit :as dt]
|
||||
[logseq.graph-parser.cli :as gp-cli]
|
||||
[logseq.publish-spa.html :as html]))
|
||||
|
||||
(defn- handle-export-publish-assets
|
||||
[html custom-css-path export-css-path repo-path asset-filenames output-path]
|
||||
(let [app-path "static"
|
||||
(let [app-path "../../static"
|
||||
root-dir output-path
|
||||
static-dir (path/join root-dir "static")
|
||||
assets-from-dir (path/join repo-path "assets")
|
||||
assets-to-dir (path/join root-dir "assets")
|
||||
index-html-path (path/join root-dir "index.html")]
|
||||
assets-from-dir (path/join repo-path "assets")
|
||||
assets-to-dir (path/join root-dir "assets")
|
||||
index-html-path (path/join root-dir "index.html")]
|
||||
(p/let [_ (. fs ensureDir static-dir)
|
||||
_ (. fs ensureDir assets-to-dir)
|
||||
_ (p/all (concat
|
||||
|
@ -61,17 +64,25 @@
|
|||
{:type "success"
|
||||
:payload (str "Export public pages and publish assets to " root-dir " successfully 🎉")}))))
|
||||
|
||||
(defn- get-app-state
|
||||
[]
|
||||
{:ui/theme "dark", :ui/sidebar-collapsed-blocks {}, :ui/show-recent? false
|
||||
:config {"local" {:feature/enable-whiteboards? true, :shortcuts {:editor/right ["mod+l" "right"], :ui/toggle-theme "t z"}, :ignored-page-references-keywords #{:description :desc}, :repo/dir-version 3, :default-templates {:journals ""}, :macros {"poem" "Rose is $1, violet's $2. Life's ordered: Org assists you."}, :shortcut/doc-mode-enter-for-new-block? false, :favorites ["foob"], :ui/show-empty-bullets? false, :preferred-file-format :edn, :preferred-workflow :now, :publishing/all-pages-public? true, :ref/default-open-blocks-level 2, :feature/enable-block-timestamps? false, :ref/linked-references-collapsed-threshold 50, :commands [], :meta/version 1, :hidden [], :default-queries {:journals '[{:title "🔨 NOW", :query [:find (pull ?h [*]) :in $ ?start ?today :where [?h :block/marker ?marker] [(contains? #{"NOW" "DOING"} ?marker)] [?h :block/page ?p] [?p :block/journal? true] [?p :block/journal-day ?d] [(>= ?d ?start)] [(<= ?d ?today)]], :inputs [:14d :today], :result-transform (fn [result] (sort-by (fn [h] (get h :block/priority "Z")) result)), :collapsed? false} {:title "📅 NEXT", :query [:find (pull ?h [*]) :in $ ?start ?next :where [?h :block/marker ?marker] [(contains? #{"NOW" "LATER" "TODO"} ?marker)] [?h :block/ref-pages ?p] [?p :block/journal? true] [?p :block/journal-day ?d] [(> ?d ?start)] [(< ?d ?next)]], :inputs [:today :7d-after], :collapsed? false}]}, :ui/enable-tooltip? true, :rich-property-values? false, :property/separated-by-commas #{:comma-prop}, :property-pages/excludelist #{:author}, :graph/settings {:journal? true, :excluded-pages? true, :orphan-pages? false, :builtin-pages? false}, :property-pages/enabled? true, :ui/show-command-doc? true, :preferred-format :markdown}}})
|
||||
|
||||
(defn- get-db [graph-dir]
|
||||
(let [{:keys [conn]} (gp-cli/parse-graph graph-dir {:verbose false})] @conn))
|
||||
|
||||
(defn -main
|
||||
[args]
|
||||
[& args]
|
||||
(let [repo-path (or (first args)
|
||||
(throw (ex-info "GRAPH DIR required" {})))
|
||||
output-path (or (second args)
|
||||
(throw (ex-info "OUT DIR required" {})))
|
||||
html "WOOHOO"
|
||||
; html "WOOHOO"
|
||||
db-str (dt/write-transit-str (get-db repo-path))
|
||||
html (html/publishing-html db-str (pr-str (get-app-state)))
|
||||
custom-css-path (path/join repo-path "logseq" "custom.css")
|
||||
export-css-path (path/join repo-path "logseq" "export.css")
|
||||
;; TODO: Read from repo-path
|
||||
asset-filenames []]
|
||||
(handle-export-publish-assets html custom-css-path export-css-path repo-path asset-filenames output-path)))
|
||||
|
||||
(-main *command-line-args*)
|
|
@ -0,0 +1,122 @@
|
|||
(ns ^:no-doc logseq.publish-spa.html
|
||||
; (:require-macros [hiccups.core])
|
||||
(:require [clojure.string :as string]
|
||||
[goog.string :as gstring]
|
||||
[goog.string.format]
|
||||
#_[hiccups.runtime]))
|
||||
|
||||
(defn- escape-html
|
||||
"Change special characters into HTML character entities."
|
||||
[text]
|
||||
(-> text
|
||||
(string/replace "&" "logseq____&")
|
||||
(string/replace "<" "logseq____<")
|
||||
(string/replace ">" "logseq____>")
|
||||
(string/replace "\"" "logseq____"")
|
||||
(string/replace "'" "logseq____'")))
|
||||
|
||||
;; from https://github.com/babashka/babashka/blob/8c1077af00c818ade9e646dfe1297bbe24b17f4d/examples/notes.clj#L21
|
||||
(defn html [v]
|
||||
(cond (vector? v)
|
||||
(let [tag (first v)
|
||||
attrs (second v)
|
||||
attrs (when (map? attrs) attrs)
|
||||
elts (if attrs (nnext v) (next v))
|
||||
tag-name (name tag)]
|
||||
(gstring/format "<%s%s>%s</%s>\n" tag-name (html attrs) (html elts) tag-name))
|
||||
(map? v)
|
||||
(string/join ""
|
||||
(map (fn [[k v]]
|
||||
(gstring/format " %s=\"%s\"" (name k) v)) v))
|
||||
(seq? v)
|
||||
(string/join " " (map html v))
|
||||
:else (str v)))
|
||||
|
||||
(defn publishing-html
|
||||
[transit-db app-state]
|
||||
;; TODO: Implement get-config
|
||||
(let [{:keys [icon name alias title description url]} (:project {} #_(state/get-config))
|
||||
icon (or icon "static/img/logo.png")
|
||||
project (or alias name)]
|
||||
(str "<!DOCTYPE html>\n"
|
||||
(html
|
||||
(list
|
||||
[:head
|
||||
[:meta {:charset "utf-8"}]
|
||||
[:meta
|
||||
{:content
|
||||
"minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no",
|
||||
:name "viewport"}]
|
||||
[:link {:type "text/css", :href "static/css/tabler-icons.min.css", :rel "stylesheet"}]
|
||||
[:link {:type "text/css", :href "static/css/style.css", :rel "stylesheet"}]
|
||||
[:link {:type "text/css", :href "static/css/custom.css", :rel "stylesheet"}]
|
||||
[:link {:type "text/css", :href "static/css/export.css", :rel "stylesheet"}]
|
||||
[:link
|
||||
{:href icon
|
||||
:type "image/png",
|
||||
:rel "shortcut icon"}]
|
||||
[:link
|
||||
{:href icon
|
||||
:sizes "192x192",
|
||||
:rel "shortcut icon"}]
|
||||
[:link
|
||||
{:href icon
|
||||
:rel "apple-touch-icon"}]
|
||||
|
||||
[:meta {:name "apple-mobile-web-app-title" :content project}]
|
||||
[:meta {:name "apple-mobile-web-app-capable" :content "yes"}]
|
||||
[:meta {:name "apple-touch-fullscreen" :content "yes"}]
|
||||
[:meta {:name "apple-mobile-web-app-status-bar-style" :content "black-translucent"}]
|
||||
[:meta {:name "mobile-web-app-capable" :content "yes"}]
|
||||
|
||||
[:meta {:content title, :property "og:title"}]
|
||||
[:meta {:content "site", :property "og:type"}]
|
||||
(when url [:meta {:content url, :property "og:url"}])
|
||||
[:meta
|
||||
{:content icon
|
||||
:property "og:image"}]
|
||||
[:meta
|
||||
{:content description
|
||||
:property "og:description"}]
|
||||
[:title title]
|
||||
[:meta {:content project, :property "og:site_name"}]
|
||||
[:meta
|
||||
{:description description}]]
|
||||
[:body
|
||||
[:div {:id "root"}]
|
||||
[:script (gstring/format "window.logseq_db=%s" (js/JSON.stringify (escape-html transit-db)))]
|
||||
[:script (str "window.logseq_state=" (js/JSON.stringify app-state))]
|
||||
[:script {:type "text/javascript"}
|
||||
"// Single Page Apps for GitHub Pages
|
||||
// https://github.com/rafgraph/spa-github-pages
|
||||
// Copyright (c) 2016 Rafael Pedicini, licensed under the MIT License
|
||||
// ----------------------------------------------------------------------
|
||||
// This script checks to see if a redirect is present in the query string
|
||||
// and converts it back into the correct url and adds it to the
|
||||
// browser's history using window.history.replaceState(...),
|
||||
// which won't cause the browser to attempt to load the new url.
|
||||
// When the single page app is loaded further down in this file,
|
||||
// the correct url will be waiting in the browser's history for
|
||||
// the single page app to route accordingly.
|
||||
(function(l) {
|
||||
if (l.search) {
|
||||
var q = {};
|
||||
l.search.slice(1).split('&').forEach(function(v) {
|
||||
var a = v.split('=');
|
||||
q[a[0]] = a.slice(1).join('=').replace(/~and~/g, '&');
|
||||
});
|
||||
if (q.p !== undefined) {
|
||||
window.history.replaceState(null, null,
|
||||
l.pathname.slice(0, -1) + (q.p || '') +
|
||||
(q.q ? ('?' + q.q) : '') +
|
||||
l.hash
|
||||
);
|
||||
}
|
||||
}
|
||||
}(window.location))"]
|
||||
;; TODO: should make this configurable
|
||||
[:script {:src "static/js/main.js"}]
|
||||
[:script {:src "static/js/highlight.min.js"}]
|
||||
[:script {:src "static/js/interact.min.js"}]
|
||||
[:script {:src "static/js/katex.min.js"}]
|
||||
[:script {:src "static/js/code-editor.js"}]])))))
|
|
@ -89,6 +89,7 @@
|
|||
:config])
|
||||
state (update state :config (fn [config]
|
||||
{"local" (get config repo)}))
|
||||
_ (prn :STATE state)
|
||||
raw-html-str (html/publishing-html db-str (pr-str state))
|
||||
html-str (str "data:text/html;charset=UTF-8,"
|
||||
(js/encodeURIComponent raw-html-str))]
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
(defn publishing-html
|
||||
[transit-db app-state]
|
||||
(prn :PROJECT (:project (state/get-config)))
|
||||
(let [{:keys [icon name alias title description url]} (:project (state/get-config))
|
||||
icon (or icon "static/img/logo.png")
|
||||
project (or alias name)]
|
||||
|
@ -84,7 +85,7 @@
|
|||
}
|
||||
}
|
||||
}(window.location))"]
|
||||
;; TODO: should make this configurable
|
||||
;; TODO: should make this configurable
|
||||
[:script {:src "static/js/main.js"}]
|
||||
[:script {:src "static/js/highlight.min.js"}]
|
||||
[:script {:src "static/js/interact.min.js"}]
|
||||
|
|
Loading…
Reference in New Issue