Compare commits

...

3 commits

Author SHA1 Message Date
31a825b033
Migrate from GitHub to Forgejo
All checks were successful
CI / test (sbcl-bin) (push) Successful in 24s
2025-01-12 19:03:34 +09:00
a73af8d936 Update description
Some checks failed
test / tests (ccl-bin) (push) Has been cancelled
test / tests (sbcl-bin) (push) Has been cancelled
2024-12-20 23:41:46 +09:00
fa7fc1605e Modify the wording 2024-12-17 16:14:46 +09:00
7 changed files with 114 additions and 37 deletions

70
.forgejo/workflows/ci.yml Normal file
View file

@ -0,0 +1,70 @@
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: 'test'
name: 'CI'
on:
push:
@ -7,15 +7,15 @@ on:
pull_request:
jobs:
tests:
test:
runs-on: ubuntu-latest
strategy:
matrix:
lisp:
- sbcl-bin
- ccl-bin
env:
LISP: ${{ matrix.lisp }}

View file

@ -1,6 +1,7 @@
# HSX
HSX (Hypertext S-expression) is a simple yet powerful HTML5 generation library for Common Lisp.
HSX (Hypertext S-expression) is a simple and powerful HTML (Living Standard)
generation library for Common Lisp.
This project is a fork of [ailisp/flute](https://github.com/ailisp/flute/).
@ -8,13 +9,16 @@ 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.
Please check the [release notes](https://github.com/skyizwhite/hsx/releases) for updates.
Please check the [release notes](https://code.skyizwhite.dev/paku/hsx/releases)
for updates.
## Getting Started
### Basic Usage
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.
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.
```lisp
(hsx
@ -32,7 +36,8 @@ This generates:
</div>
```
To convert an HSX object into an HTML string, use the `render-to-string` function:
To convert an HSX object into an HTML string, use the `render-to-string`
function:
```lisp
(render-to-string
@ -43,7 +48,8 @@ To convert an HSX object into an HTML string, use the `render-to-string` functio
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 `hsx` macro again.
When working with HSX elements inside embedded Lisp forms, you should use the
`hsx` macro again.
```lisp
(hsx
@ -76,7 +82,8 @@ This might generate:
### 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
(hsx
@ -96,7 +103,9 @@ This generates:
### Creating Components
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.
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.
```lisp
(defcomp ~card (&key title children)
@ -140,5 +149,3 @@ This project is licensed under the MIT License.
© 2024 skyizwhite
© 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"
:version "0.4.0"
:description "Hypertext S-expression"
:description "Simple and powerful HTML generation library."
:author "skyizwhite, Bo Yao"
:maintainer "skyizwhite <paku@skyizwhite.dev>"
:license "MIT"

6
qlfile
View file

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

View file

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

View file

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