Compare commits

..

No commits in common. "master" and "0.4.0" have entirely different histories.

7 changed files with 37 additions and 114 deletions

View file

@ -1,70 +0,0 @@
name: 'CI'
on:
push:
branches:
- 'master'
pull_request:
jobs:
test:
runs-on: docker
strategy:
matrix:
lisp:
- sbcl-bin
steps:
- uses: actions/checkout@v4
- name: Restore cache
id: restore-cache
uses: actions/cache/restore@v4
with:
path: |
~/.roswell
/usr/local/bin/ros
/usr/local/etc/roswell/
qlfile
qlfile.lock
.qlot
~/.cache/common-lisp/
key: roswell-${{ runner.os }}-${{ matrix.lisp }}-${{ hashFiles('qlfile', 'qlfile.lock', '*.asd') }}
- name: Install Roswell
if: steps.restore-cache.outputs.cache-hit != 'true'
env:
LISP: ${{ matrix.lisp }}
run: |
curl -L https://raw.githubusercontent.com/roswell/roswell/master/scripts/install-for-ci.sh | sh
- name: Install Qlot
if: steps.restore-cache.outputs.cache-hit != 'true'
run: |
ros install fukamachi/qlot
- name: Install dependencies
if: steps.restore-cache.outputs.cache-hit != 'true'
run: |
PATH="~/.roswell/bin:$PATH"
qlot install
qlot exec ros install hsx
- name: Save cache
id: save-cache
uses: actions/cache/save@v4
if: steps.restore-cache.outputs.cache-hit != 'true'
with:
path: |
~/.roswell
/usr/local/bin/ros
/usr/local/etc/roswell/
qlfile
qlfile.lock
.qlot
~/.cache/common-lisp/
key: ${{ steps.restore-cache.outputs.cache-primary-key }}
- name: Run tests
run: .qlot/bin/rove hsx.asd

View file

@ -1,4 +1,4 @@
name: 'CI' name: 'test'
on: on:
push: push:
@ -7,15 +7,15 @@ on:
pull_request: pull_request:
jobs: jobs:
test: tests:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
lisp: lisp:
- sbcl-bin - sbcl-bin
- ccl-bin - ccl-bin
env: env:
LISP: ${{ matrix.lisp }} LISP: ${{ matrix.lisp }}

View file

@ -1,7 +1,6 @@
# HSX # HSX
HSX (Hypertext S-expression) is a simple and powerful HTML (Living Standard) HSX (Hypertext S-expression) is a simple yet powerful HTML5 generation library for Common Lisp.
generation library for Common Lisp.
This project is a fork of [ailisp/flute](https://github.com/ailisp/flute/). This project is a fork of [ailisp/flute](https://github.com/ailisp/flute/).
@ -9,16 +8,13 @@ This project is a fork of [ailisp/flute](https://github.com/ailisp/flute/).
This software is still in ALPHA quality. The APIs are likely to change. This software is still in ALPHA quality. The APIs are likely to change.
Please check the [release notes](https://code.skyizwhite.dev/paku/hsx/releases) Please check the [release notes](https://github.com/skyizwhite/hsx/releases) for updates.
for updates.
## Getting Started ## Getting Started
### Basic Usage ### Basic Usage
Use the `hsx` macro to create HTML elements. Attributes are specified using a Use the `hsx` macro to create HTML elements. Attributes are specified using a property list after the element name, and child elements are nested directly inside.
property list after the element name, and child elements are nested directly
inside.
```lisp ```lisp
(hsx (hsx
@ -36,8 +32,7 @@ This generates:
</div> </div>
``` ```
To convert an HSX object into an HTML string, use the `render-to-string` To convert an HSX object into an HTML string, use the `render-to-string` function:
function:
```lisp ```lisp
(render-to-string (render-to-string
@ -48,8 +43,7 @@ function:
HSX allows you to embed Common Lisp forms directly within your HTML structure. HSX allows you to embed Common Lisp forms directly within your HTML structure.
When working with HSX elements inside embedded Lisp forms, you should use the When working with HSX elements inside embedded Lisp forms, you should use the `hsx` macro again.
`hsx` macro again.
```lisp ```lisp
(hsx (hsx
@ -82,8 +76,7 @@ This might generate:
### Using Fragments ### Using Fragments
To group multiple elements without adding an extra wrapper, use the fragment To group multiple elements without adding an extra wrapper, use the fragment `<>`.
`<>`.
```lisp ```lisp
(hsx (hsx
@ -103,9 +96,7 @@ This generates:
### Creating Components ### Creating Components
You can define reusable components using the `defcomp` macro. Component names You can define reusable components using the `defcomp` macro. Component names must begin with a tilde (`~`). Properties should be declared using `&key`, `&rest`, or both. The body must return an HSX element.
must begin with a tilde (`~`). Properties should be declared using `&key`,
`&rest`, or both. The body must return an HSX element.
```lisp ```lisp
(defcomp ~card (&key title children) (defcomp ~card (&key title children)
@ -149,3 +140,5 @@ This project is licensed under the MIT License.
© 2024 skyizwhite © 2024 skyizwhite
© 2018 Bo Yao © 2018 Bo Yao
Feel free to contribute to the project and report any issues or feature requests on the [GitHub repository](https://github.com/skyizwhite/hsx).

View file

@ -1,6 +1,6 @@
(defsystem "hsx" (defsystem "hsx"
:version "0.4.0" :version "0.4.0"
:description "Simple and powerful HTML generation library." :description "Hypertext S-expression"
:author "skyizwhite, Bo Yao" :author "skyizwhite, Bo Yao"
:maintainer "skyizwhite <paku@skyizwhite.dev>" :maintainer "skyizwhite <paku@skyizwhite.dev>"
:license "MIT" :license "MIT"

6
qlfile
View file

@ -1,6 +1,6 @@
ql alexandria ql alexandria
ql cl-str ql cl-str
git rove https://github.com/fukamachi/rove github rove fukamachi/rove
git dissect https://github.com/Shinmera/dissect ; workaround github dissect Shinmera/dissect ; workaround
git mstrings https://git.sr.ht/~shunter/mstrings ql mstrings

View file

@ -1,24 +1,24 @@
("quicklisp" . ("quicklisp" .
(:class qlot/source/dist:source-dist (:class qlot/source/dist:source-dist
:initargs (:distribution "https://beta.quicklisp.org/dist/quicklisp.txt" :%version :latest) :initargs (:distribution "https://beta.quicklisp.org/dist/quicklisp.txt" :%version :latest)
:version "2024-10-12")) :version "2023-10-21"))
("alexandria" . ("alexandria" .
(:class qlot/source/ql:source-ql (:class qlot/source/ql:source-ql
:initargs (:%version :latest) :initargs (:%version :latest)
:version "ql-2024-10-12")) :version "ql-2023-10-21"))
("cl-str" . ("cl-str" .
(:class qlot/source/ql:source-ql (:class qlot/source/ql:source-ql
:initargs (:%version :latest) :initargs (:%version :latest)
:version "ql-2024-10-12")) :version "ql-2023-10-21"))
("rove" . ("rove" .
(:class qlot/source/git:source-git (:class qlot/source/github:source-github
:initargs (:remote-url "https://github.com/fukamachi/rove") :initargs (:repos "fukamachi/rove" :ref nil :branch nil :tag nil)
:version "git-cacea7331c10fe9d8398d104b2dfd579bf7ea353")) :version "github-cacea7331c10fe9d8398d104b2dfd579bf7ea353"))
("dissect" . ("dissect" .
(:class qlot/source/git:source-git (:class qlot/source/github:source-github
:initargs (:remote-url "https://github.com/Shinmera/dissect") :initargs (:repos "Shinmera/dissect" :ref nil :branch nil :tag nil)
:version "git-a70cabcd748cf7c041196efd711e2dcca2bbbb2c")) :version "github-a70cabcd748cf7c041196efd711e2dcca2bbbb2c"))
("mstrings" . ("mstrings" .
(:class qlot/source/git:source-git (:class qlot/source/ql:source-ql
:initargs (:remote-url "https://git.sr.ht/~shunter/mstrings") :initargs (:%version :latest)
:version "git-7a94c070141c7cd03bbd3648b17724c3bf143393")) :version "ql-2023-10-21"))

View file

@ -16,7 +16,7 @@
"Detect HSX elements and automatically import them." "Detect HSX elements and automatically import them."
(detect-elements form)) (detect-elements form))
(defun detect-builtin-symbol (sym) (defun get-builtin-symbol (sym)
(multiple-value-bind (builtin-sym kind) (multiple-value-bind (builtin-sym kind)
(find-symbol (string sym) :hsx/builtin) (find-symbol (string sym) :hsx/builtin)
(and (eq kind :external) builtin-sym))) (and (eq kind :external) builtin-sym)))
@ -24,7 +24,7 @@
(defun start-with-tilde-p (sym) (defun start-with-tilde-p (sym)
(string= "~" (subseq (string sym) 0 1))) (string= "~" (subseq (string sym) 0 1)))
(defun detect-component-symbol (sym) (defun get-component-symbol (sym)
(and (start-with-tilde-p sym) sym)) (and (start-with-tilde-p sym) sym))
(defun detect-elements (form) (defun detect-elements (form)
@ -34,8 +34,8 @@
(well-formed-p (listp tail)) (well-formed-p (listp tail))
(detected-sym (and (symbolp head) (detected-sym (and (symbolp head)
(not (keywordp head)) (not (keywordp head))
(or (detect-builtin-symbol head) (or (get-builtin-symbol head)
(detect-component-symbol head))))) (get-component-symbol head)))))
(if (and well-formed-p detected-sym) (if (and well-formed-p detected-sym)
(cons detected-sym (cons detected-sym
(mapcar (lambda (sub-form) (mapcar (lambda (sub-form)
@ -75,16 +75,16 @@
(defhsx ,name ,(make-keyword name)))) (defhsx ,name ,(make-keyword name))))
(defmacro defcomp (~name props &body body) (defmacro defcomp (~name props &body body)
"Define an HSX function component. "Define a function component for HSX.
The component name must start with a tilde (~). The component name must start with a tilde (~).
Component properties must be declared using &key, &rest, or both. Properties must be declared using &key, &rest, or both.
The body of the component must produce a valid HSX element." The body must return an HSX element."
(unless (start-with-tilde-p ~name) (unless (start-with-tilde-p ~name)
(error "The component name must start with a tilde (~~).")) (error "The component name must start with a tilde (~~)."))
(unless (or (null props) (unless (or (null props)
(member '&key props) (member '&key props)
(member '&rest props)) (member '&rest props))
(error "Component properties must be declared using &key, &rest, or both.")) (error "Component properties must be declared with either &key, &rest, or both."))
(let ((%name (symbolicate '% ~name))) (let ((%name (symbolicate '% ~name)))
`(eval-when (:compile-toplevel :load-toplevel :execute) `(eval-when (:compile-toplevel :load-toplevel :execute)
(defun ,%name ,props (defun ,%name ,props