CL-RemiGemini
CL-RemiGemini is a small and lightweight library for interfacing with the Gemini Protocol using Common Lisp. It includes classes that aid in the implementation of clients and servers that can handle multiple concurrent connections.
Wanna support Remilia? Buy me a coffee on Ko-Fi, or support me through Liberapay.
How do I get set up?
Most dependencies can be installed using QuickLisp (though this hasn't been tested). The exception is the CL-SDM library, which can be obtained here.
You will need Fossil installed to clone this repo.
Place this library (and the CL-SDM dependency) somewhere where ASDF can find them, then run this in your REPL:
(asdf:load-system :cl-remigemini)
Usage
There are a few examples in the root of the repository.
Example client:
(gemini:response-body-str (gemini:client-get "gemini://gemini.circumlunar.space/"))
Example server:
;; Simple server that listens on localhost. If the user navigates to
;; /file then a binary file is served. Otherwise, "Hello World" is
;; returned.
(defun run-server ()
(let ((lparallel:*kernel* (lparallel:make-kernel 4)))
(cl-remigemini:with-server (server '("127.0.0.1")
"/path/to/key.pem"
"/path/to/cert.pem")
;; This is the handler function. This is called for each connection
;; request.
#'(lambda (req)
;; If the request is for /file then serve a file.
(if (string= (quri:uri-path (cl-remigemini:request-uri req)) "/file")
;; Open the file stream.
(cl-remigemini:make-response :body (open #P"/path/to/some/file"
:direction :input
:element-type '(unsigned-byte 8)))
;; All other pages get this
(cl-remigemini:with-output-to-success-response (out)
(format out "Hello, world!~%"))))
;; Wait for the server to finish.
(loop while (cl-remigemini:server-listening-p server)
for msg = (lparallel:receive-result (cl-remigemini:server-handler-chan server))
when msg do (print msg)))))
(run-server)
Generating Gemtext:
(use-package :gemini)
(with-output-to-gemtext (t)
(put-h1 "Hello, world!~%")
(put-line "foo~%")
(put-quote "Hello~%")
(put-quote "World")
(put-line "~%yep, ~a~%" "this is lisp")
(put-quote "quoted")
(put-line "")
(put-list 1 2 3)
(put-line "")
(put-pre "this is
a
test"))
Development
Style info
I use a slightly unorthodox style for my code. Aside from these differences, please use normal Lisp formatting.
- Keep lines 118 characters or shorter. Obviously sometimes you can't, but please try. Use 115 characters for Markdown files, though.
- I mark types using the form
T/....
. For example,T/SOME-NEAT-TYPE
. For predicates on these, useSOME-NEAT-TYPE-P
. - No tabs. Only spaces.
How do I contribute?
- Go to https://chiselapp.com/user/MistressRemilia/repository/cl-remigemini and clone the Fossil repository.
- Create a new branch for your feature.
- Push locally to the new branch.
- Create a bundle with Fossil that contains your changes.
- Get in contact with me.
Contributors
- Remilia Scarlet - creator and maintainer
- Homepage: https://remilia.sdf.org/
- Gemini: gemini://nanako.mooo.com/
- Mastodon: @MistressRemilia@social.sdf.org
- Email: zremiliaz@postzeoz.jpz My real address does not contain Z's
Links and Licenses
CL-RemiGemini is under the GNU Affero General Public License version 3.