Skip to content

Commit

Permalink
Merge pull request #47 from 40ants/plugin-system
Browse files Browse the repository at this point in the history
Plugin system
  • Loading branch information
svetlyak40wt authored May 14, 2024
2 parents 4ebdb55 + 903bb15 commit cfad005
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 87 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,4 @@
]
}
}
}
}
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
"tag_prefix": "v"
},
"env": {
"GITHUB_TOKEN": "${{ secrets.GITHUB_TOKEN }}"
"GITHUB_TOKEN": "${{ secrets.RELEASE_TOKEN }}"
}
}
]
}
}
}
}
69 changes: 66 additions & 3 deletions full/highlight.lisp → full/plugins/highlightjs.lisp
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
(uiop:define-package #:40ants-doc-full/highlight
(uiop:define-package #:40ants-doc-full/plugins/highlightjs
(:use #:cl)
(:import-from #:40ants-doc-full/themes/api
#:copy-static
#:inject-into-page-header)
(:import-from #:spinneret
#:with-html-string)
(:import-from #:40ants-doc-full/utils
#:make-relative-path)
(:import-from #:dexador)
(:import-from #:log)
(:import-from #:alexandria
Expand All @@ -14,9 +21,59 @@
;; (:import-from #:trivial-extract
;; #:extract-zip)
(:import-from #:which)
(:import-from #:jonathan))
(:import-from #:jonathan)
(:export #:highlightjs))
(in-package #:40ants-doc-full/plugins/highlightjs)

(in-package #:40ants-doc-full/highlight)

(defvar *default-languages*
'("lisp" "bash" "css" "json" "yaml" "plaintext" "xml" "markdown"))


(defvar *default-theme*
"atom-one-dark")


(defclass highlightjs ()
((languages :initform *default-languages*
:initarg :languages
:reader highlight-languages)
(theme :initform *default-theme*
:initarg :theme
:reader highlight-theme))
(:documentation "Injects a necessary scripts to use Highlightjs for rendering math formulas in your documentation."))


(defun highlightjs (&key (languages *default-languages*)
(theme *default-theme*))
"Creates a Highlightjs plugin.
You can redefine languages list and color theme like this:
```
(make-instance '40ants-doc-full/themes/light:light-theme
:plugins (list
(highlightjs :theme \"magula\"
:languages '(\"lisp\" \"python\"))))
```
"
(make-instance 'highlightjs
:languages languages
:theme theme))


(defmethod inject-into-page-header ((plugin highlightjs) uri)
(with-html-string
(let ((highlight-css-uri (make-relative-path uri "highlight.min.css"))
(highlight-js-uri (make-relative-path uri "highlight.min.js")))
(:link :rel "stylesheet"
:type "text/css"
:href highlight-css-uri)
(:script :type "text/javascript"
:src highlight-js-uri)
(:script :type "text/javascript"
"hljs.highlightAll();"))))


(defvar *supported-languages*
Expand Down Expand Up @@ -311,3 +368,9 @@
(write-string-into-file metadata metadata-path
:if-exists :supersede))))))
(values))


(defmethod copy-static ((plugin highlightjs) target-dir)
(download-highlight-js (highlight-languages plugin)
:to target-dir
:theme (highlight-theme plugin)))
46 changes: 46 additions & 0 deletions full/plugins/mathjax.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
(uiop:define-package #:40ants-doc-full/plugins/mathjax
(:use #:cl)
(:import-from #:40ants-doc-full/themes/api
#:inject-after-content)
(:import-from #:spinneret
#:with-html-string)
(:export #:mathjax))
(in-package #:40ants-doc-full/plugins/mathjax)


(defclass mathjax ()
()
(:documentation "Injects a necessary scripts to use MathJax for rendering math formulas in your documentation."))


(defun mathjax ()
"Creates a MathJax plugin."
(make-instance 'mathjax))


(defmethod inject-after-content ((plugin mathjax) uri)
(with-html-string
;; MathJax configuration to display inline formulas
(:script :type "text/javascript"
;; Here we need this :RAW
;; because of the bug in the Spinneret
;; https://github.com/ruricolist/spinneret/issues/59
(:raw "
MathJax = {
options: {
ignoreHtmlClass: 'page',
processHtmlClass: 'content'
},
tex: {
inlineMath: [['$','$']]
},
svg: {
fontCache: 'global'
}
};
"))
(:script :type "text/javascript"
:src "https://polyfill.io/v3/polyfill.min.js?features=es6")
(:script :type "text/javascript"
:async t
:src "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js")))
86 changes: 73 additions & 13 deletions full/themes/api.lisp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
(uiop:define-package #:40ants-doc-full/themes/api
(:use #:cl)
(:import-from #:40ants-doc-full/highlight
#:download-highlight-js)
(:import-from #:alexandria
#:once-only)
(:export #:render-css
Expand All @@ -17,7 +15,12 @@
#:render-page-header
#:render-page-footer
#:highlight-languages
#:highlight-theme))
#:highlight-theme
#:inject-into-page-header
#:theme-plugins
#:inject-before-content
#:inject-after-content
#:copy-static))
(in-package #:40ants-doc-full/themes/api)

(defvar *theme*)
Expand All @@ -29,19 +32,43 @@
(t ,theme))))
,@body)))


(defgeneric theme-plugins (theme)
(:documentation "Returns a list of plugin objects which will be used to inject additional information into the pages.")
(:method ((theme t))
nil))


(defgeneric highlight-languages (theme)
(:documentation "Returns a list of languages to highlight in snippets. Each language should be supported by Highlight.js.")
(:documentation "Returns a list of languages to highlight in snippets. Each language should be supported by Highlight.js.
**Deprecated!** will be removed after 2024-11-13.
Pass languages and highlight theme as arguments to highlighjs plugin.")
(:method ((theme t))
(list :lisp
:bash)))

(defgeneric highlight-theme (theme)
(:documentation "Returns a string with the name of the Highlight.js color theme for highlighted snippets.
To preview themes, use this site: <https://highlightjs.org/static/demo/>")
To preview themes, use this site: <https://highlightjs.org/static/demo/>
**Deprecated!** Will be removed after 2024-11-13.
Pass languages and highlight theme as arguments to highlighjs plugin.")
(:method ((theme t))
"magula"))


(defgeneric copy-static (plugin target-dir)
(:documentation "Define a method for this function if your plugin need to some static assets to work.
TARGET-DIR argument is an absolute directory pathname pointing to the root of the site.
By default does nothing.")
(:method ((theme t) (target-dir t))
(values)))


(defgeneric render-css (theme)
(:documentation "Returns a string with CSS."))

Expand All @@ -51,6 +78,36 @@
(defgeneric render-page-header (theme uri title)
(:documentation "Renders whole page header. Does nothing by default."))

(defgeneric inject-into-page-header (plugin uri)
(:documentation "Plugins can define a method for this generic-function to add some code to the end of a page header.
Each method should return a string which will be inserted without \"escaping\" so
the plugin's responsibility to escape all user input's if necessary.
Does nothing by default.")
(:method ((plugin t) uri)
nil))

(defgeneric inject-before-content (plugin uri)
(:documentation "Plugins can define a method for this generic-function to add some HTML before the main content of the page.
Each method should return a string which will be inserted without \"escaping\" so
the plugin's responsibility to escape all user input's if necessary.
Does nothing by default.")
(:method ((plugin t) uri)
nil))

(defgeneric inject-after-content (plugin uri)
(:documentation "Plugins can define a method for this generic-function to add some HTML after the main content of the page.
Each method should return a string which will be inserted without \"escaping\" so
the plugin's responsibility to escape all user input's if necessary.
Does nothing by default.")
(:method ((plugin t) uri)
nil))

(defgeneric render-page-footer (theme uri)
(:documentation "Renders whole page footer. Does nothing by default."))

Expand Down Expand Up @@ -91,14 +148,13 @@
(write-string (render-css *theme*)
stream)
(terpri stream))

(when (or highlight-languages
highlight-theme)
(warn "Deprecated, will be removed after 2024-11-13.
Pass languages and highlight theme as arguments to highlighjs plugin of the theme ~A"
*theme*))

(download-highlight-js (or highlight-languages
(highlight-languages *theme*))
:to absolute-dir
:theme (or highlight-theme
(highlight-theme *theme*)))

;; TODO: Probably let to override these files too
(loop with paths = '(("toc.js" "toc.js")
("search/searchtools.js" "searchtools.js")
("search/language_data.js" "language_data.js")
Expand All @@ -109,7 +165,11 @@
do (uiop:copy-file (asdf:system-relative-pathname :40ants-doc
(concatenate 'string
"static/" from))
(uiop:merge-pathnames* to absolute-dir)))))
(uiop:merge-pathnames* to absolute-dir)))

;; Plugins can override or remove some of the files written above:
(loop for plugin in (theme-plugins *theme*)
do (copy-static plugin absolute-dir))))

(defun call-with-page-template (func uri title toc)
(check-type uri string)
Expand Down
3 changes: 0 additions & 3 deletions full/themes/dark.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,3 @@
:background ,font-color)
((.toc-active > a)
:color ,background)))))))

(defmethod 40ants-doc-full/themes/api:highlight-theme ((theme dark-theme))
"atom-one-dark")
Loading

0 comments on commit cfad005

Please sign in to comment.