Compare commits
No commits in common. "master" and "0.4.0" have entirely different histories.
7 changed files with 37 additions and 114 deletions
|
@ -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
|
|
|
@ -1,4 +1,4 @@
|
||||||
name: 'CI'
|
name: 'test'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
@ -7,7 +7,7 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
tests:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
25
README.md
25
README.md
|
@ -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).
|
||||||
|
|
2
hsx.asd
2
hsx.asd
|
@ -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
6
qlfile
|
@ -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
|
||||||
|
|
24
qlfile.lock
24
qlfile.lock
|
@ -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"))
|
||||||
|
|
16
src/dsl.lisp
16
src/dsl.lisp
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue