Compare commits
72 commits
Author | SHA1 | Date | |
---|---|---|---|
0516ba6985 | |||
4375c4d125 | |||
d47b443d45 | |||
5b0abcc8fe | |||
e5807b9f51 | |||
6a1f13c66d | |||
b3940516d9 | |||
edbb9dc3d4 | |||
2fcd46c146 | |||
c4a4ae31fa | |||
bec0370638 | |||
f0b015ec87 | |||
9f900eb078 | |||
665895bd83 | |||
2943986e2a | |||
6c7d85726a | |||
c3f17edbf3 | |||
4cbb4d9cc2 | |||
999db22888 | |||
7d076e0742 | |||
f2ca738a57 | |||
2229a06295 | |||
05a594830e | |||
f052c87c9c | |||
e67d5b114f | |||
49261be7ef | |||
04f9401497 | |||
ac176553f8 | |||
b64d7d47e0 | |||
2e134c7644 | |||
9aea82ad59 | |||
88bef35a83 | |||
70b25cf2af | |||
fd9152ab0e | |||
432b620d8c | |||
a7eb272b02 | |||
ce1d017b99 | |||
a1dcd6e9c0 | |||
054dfdc7eb | |||
685af4956a | |||
30a3780663 | |||
09bff636e3 | |||
4983b40f78 | |||
5508d23290 | |||
baec19a6d7 | |||
5fb4cc7674 | |||
af165e5539 | |||
2f7fc40901 | |||
c5ad5e7b7b | |||
130f36989d | |||
7a0172ae64 | |||
f44b4f36fa | |||
7f56115ccf | |||
4982e32350 | |||
eccbd26ac0 | |||
7ace3f606f | |||
334e0259d9 | |||
8b37c58e55 | |||
a3823bf993 | |||
7bc26d0864 | |||
c81dbccac1 | |||
145127b430 | |||
7b9e5d2d18 | |||
d78aa17404 | |||
2847291391 | |||
3ec5520936 | |||
d23aa937a6 | |||
44e621a9d0 | |||
fe8ecbcd75 | |||
3b16b06255 | |||
016b945815 | |||
c4f84f3de9 |
92 changed files with 2725 additions and 652 deletions
81
.dev-log
81
.dev-log
|
@ -1,22 +1,87 @@
|
||||||
24/12/2023
|
2024/01/21
|
||||||
- published about sections
|
- .txt -> .scm for better source viewing in git forge
|
||||||
|
- fix footer styling (tagged section is cramped with flex-row
|
||||||
|
especially on mobile)
|
||||||
|
- pick a license
|
||||||
|
- add view source link to every page (git forge of source/resource
|
||||||
|
not static/resource; we're here for the sexprs)
|
||||||
TODO:
|
TODO:
|
||||||
- modify publish script to ensure rollback on failure
|
- refactor publish script for atomic, idempotent execution (follow
|
||||||
- create update script to publish updates to existing posts
|
rollback thunk + compose accumulator pattern in modify script)
|
||||||
|
|
||||||
21/12/2023
|
2024/01/17
|
||||||
|
- add html cache directories to build script
|
||||||
|
TODO:
|
||||||
|
- putting content in atom will require changing csv parsing;
|
||||||
|
that's for v2
|
||||||
|
|
||||||
|
2024/01/15
|
||||||
|
- cache static logic
|
||||||
|
- START HERE:
|
||||||
|
- test caching everywhere
|
||||||
|
- add content in atom
|
||||||
|
|
||||||
|
2024/01/14
|
||||||
|
- fix stylesheets
|
||||||
|
- update all url references
|
||||||
|
- START HERE:
|
||||||
|
- add content in atom
|
||||||
|
- cache static logic
|
||||||
|
|
||||||
|
2024/01/13
|
||||||
|
- update atom-table-writing
|
||||||
|
- finish atom-feed-recreation in modify
|
||||||
|
- modify functionality complete
|
||||||
|
- START HERE:
|
||||||
|
- update all references to old url
|
||||||
|
- TODO:
|
||||||
|
- add content in atom <entry><content /></>
|
||||||
|
- re-publish stuff in publish branch
|
||||||
|
|
||||||
|
2024/01/11
|
||||||
|
- rebuilding post-footer
|
||||||
|
- created tools/utils.rkt to put utils shared between modify
|
||||||
|
and publish (includes new url)
|
||||||
|
- update-atom-table writing
|
||||||
|
- START HERE:
|
||||||
|
- update-atom-table needs description for post
|
||||||
|
|
||||||
|
2024/01/08
|
||||||
|
- rb-thunks accumulating via compose
|
||||||
|
- update-res-table now adding update-history to data/<resource>.csv
|
||||||
|
- started loading tag-list for rebuilding post-footer
|
||||||
|
- START HERE:
|
||||||
|
- rebuild post-footer
|
||||||
|
- update-atom-table
|
||||||
|
- TODO:
|
||||||
|
- update all references to old url (especially in atom feed)
|
||||||
|
- update light-mode style
|
||||||
|
|
||||||
|
2024/01/07
|
||||||
|
- returning to project
|
||||||
|
- refactor get-res-table and get-output-file for returning input and output ports
|
||||||
|
- rb thunk will require read from input-file-port to rewrite contents on fail
|
||||||
|
- TODO:
|
||||||
|
- initialize rb-thunks and ensure they accumulate on passage to each handler
|
||||||
|
|
||||||
|
2023/12/30
|
||||||
|
- starting work on "modify" script
|
||||||
|
- custom errors that emit a list of "rollback thunks" to enable resetting
|
||||||
|
to prior state if any error is raised
|
||||||
|
|
||||||
|
2023/12/21
|
||||||
- broke "about" into smaller sections and linked from "/"
|
- broke "about" into smaller sections and linked from "/"
|
||||||
- removed "about" from header - now just [settled | unsettled | feed]
|
- removed "about" from header - now just [settled | unsettled | feed]
|
||||||
- added "now" and "this" sections and linked from "/"
|
- added "now" and "this" sections and linked from "/"
|
||||||
|
|
||||||
10/12/2023
|
2023/12/10
|
||||||
- added resource/index builder to publish script
|
- added resource/index builder to publish script
|
||||||
|
|
||||||
4/12/2023
|
2023/12/04
|
||||||
- added function to build index source xexpr file for tagged/'tag
|
- added function to build index source xexpr file for tagged/'tag
|
||||||
- fixed tagged/ index source xexpr printing to file so that it can be read
|
- fixed tagged/ index source xexpr printing to file so that it can be read
|
||||||
|
|
||||||
30/11/2023
|
2023/11/30
|
||||||
- added function to build an index source xexpr file for tagged/
|
- added function to build an index source xexpr file for tagged/
|
||||||
- have not tested to see if it builds tagged/ properly yet
|
- have not tested to see if it builds tagged/ properly yet
|
||||||
|
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -3,5 +3,6 @@
|
||||||
sorrel/**
|
sorrel/**
|
||||||
deploy-dir/**
|
deploy-dir/**
|
||||||
tool/**
|
tool/**
|
||||||
|
static/**/**.html
|
||||||
publish-test/**
|
publish-test/**
|
||||||
compiled/**
|
todo.txt
|
||||||
|
|
47
.idea-log
47
.idea-log
|
@ -1,12 +1,43 @@
|
||||||
24/12/2023
|
IDEAS in progress
|
||||||
- posted:
|
----- - - - - - -
|
||||||
- this
|
- root/links
|
||||||
- now
|
- unsettled/latl-primitives
|
||||||
- about
|
|
||||||
- contact
|
|
||||||
- very-earnest-disclaimer
|
|
||||||
|
|
||||||
21/12/2023
|
IDEAS for future time
|
||||||
|
_____ - - - - - - - -
|
||||||
|
- unsettled/that-has-no-name
|
||||||
|
- - event system
|
||||||
|
- - story as graph
|
||||||
|
- unsettled/input-messenger
|
||||||
|
- settled/go
|
||||||
|
- - client only
|
||||||
|
- settled/this-post-is-atomic (oxaliq.net utility scripts and atomicity)
|
||||||
|
- unsettled/syntax-considered-harmful #playful
|
||||||
|
- unsettled/ddd #playful
|
||||||
|
- unsettled/library ????
|
||||||
|
|
||||||
|
TH' LOG
|
||||||
|
-------
|
||||||
|
2024/02/07
|
||||||
|
- working through the giant latl-primitives writeup
|
||||||
|
- should really fix the post id thing before i publish it
|
||||||
|
|
||||||
|
2023/01/25
|
||||||
|
- published fca writeup
|
||||||
|
|
||||||
|
2023/01/19
|
||||||
|
- published about posts linked from index page
|
||||||
|
- published beginning-latl
|
||||||
|
- in-progress
|
||||||
|
- links ?
|
||||||
|
- to write next
|
||||||
|
- conlanging-tools
|
||||||
|
- latl-primitives
|
||||||
|
- what is in a sound change rule?
|
||||||
|
- syntax-considered-harmful ? (playful)
|
||||||
|
- (l)ddd (living)-documentation-driven-development ? (playful)
|
||||||
|
|
||||||
|
2023/12/21
|
||||||
- beginning latl effectively finished and ready for post once ci is fixed
|
- beginning latl effectively finished and ready for post once ci is fixed
|
||||||
- projects to write about
|
- projects to write about
|
||||||
- input-messenger
|
- input-messenger
|
||||||
|
|
32
.woodpecker/build-and-deploy.yml
Normal file
32
.woodpecker/build-and-deploy.yml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
when:
|
||||||
|
branch:
|
||||||
|
include: [ main ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
|
||||||
|
build:
|
||||||
|
image: debian:bookworm-slim
|
||||||
|
commands:
|
||||||
|
- apt update
|
||||||
|
- apt -yq install racket ca-certificates
|
||||||
|
- yes Y | raco pkg install --no-docs csv-reading
|
||||||
|
- raco exe oxaliq.net.rkt
|
||||||
|
- raco distribute dist oxaliq.net
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
image: alpine:latest
|
||||||
|
secrets:
|
||||||
|
- oxaliq_deploy_ssh
|
||||||
|
commands:
|
||||||
|
- echo "SETTING UP SSH"
|
||||||
|
- apk add openssh-client
|
||||||
|
- mkdir -p $HOME/.ssh
|
||||||
|
- ssh-keyscan -t ed25519 oxaliq.net >> $HOME/.ssh/known_hosts
|
||||||
|
- echo "$oxaliq_deploy_ssh" > $HOME/.ssh/id_ed25519
|
||||||
|
- chmod 0600 $HOME/.ssh/id_ed25519
|
||||||
|
- echo "SSH SETUP DONE"
|
||||||
|
- echo "RUNNING DEPLOY SCRIPT"
|
||||||
|
- ./.woodpecker/deploy.sh
|
||||||
|
when:
|
||||||
|
# Only try to deploy if previous step is successful
|
||||||
|
status: success
|
48
.woodpecker/deploy.sh
Executable file
48
.woodpecker/deploy.sh
Executable file
|
@ -0,0 +1,48 @@
|
||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
# hello variables
|
||||||
|
host=root@oxaliq.net
|
||||||
|
|
||||||
|
# organize the files
|
||||||
|
echo "ORGANIZING THE FILES NICELY"
|
||||||
|
mkdir oxaliq
|
||||||
|
mv dist oxaliq/.
|
||||||
|
mv source oxaliq/.
|
||||||
|
mv static oxaliq/.
|
||||||
|
|
||||||
|
# add html cache directories
|
||||||
|
echo "ADDING HTML CACHE DIRECTORIES"
|
||||||
|
mkdir fragment
|
||||||
|
mkdir settled
|
||||||
|
mkdir unsettled
|
||||||
|
mkdir tagged
|
||||||
|
cp -r settled fragment/.
|
||||||
|
cp -r unsettled fragment/.
|
||||||
|
cp -r tagged fragment/.
|
||||||
|
mv fragment oxaliq/static/.
|
||||||
|
mkdir page
|
||||||
|
mv settled page/.
|
||||||
|
mv unsettled page/.
|
||||||
|
mv tagged page/.
|
||||||
|
mv page oxaliq/static/.
|
||||||
|
|
||||||
|
# put them on the deployment target
|
||||||
|
echo "COPYING FILES TO DEPLOYMENT TARGET"
|
||||||
|
scp -r oxaliq "$host":~/
|
||||||
|
|
||||||
|
# do everything on the server that's necessary to run the new thing
|
||||||
|
# TODO make this not remove the old-working version until
|
||||||
|
# the new version is confirmed working
|
||||||
|
echo "SETTING OWNERSHIP AND PERMISSIONS"
|
||||||
|
ssh $host 'chown -R oxaliqdotnet:oxaliqdotnet oxaliq/'
|
||||||
|
ssh $host 'chmod -R 755 oxaliq/'
|
||||||
|
|
||||||
|
echo "REPLACING PREVIOUS DEPLOYMENT"
|
||||||
|
ssh $host 'rm -rf /srv/oxaliq || true'
|
||||||
|
ssh $host 'mv oxaliq /srv/.'
|
||||||
|
|
||||||
|
echo "RESTARTING SERVICE"
|
||||||
|
ssh $host 'systemctl restart oxaliqdotnet.service'
|
||||||
|
|
||||||
|
echo "SUCCESS!"
|
||||||
|
exit 0
|
|
@ -1,9 +0,0 @@
|
||||||
FROM debian:bookworm-slim
|
|
||||||
COPY . .
|
|
||||||
RUN rm -rf data/
|
|
||||||
RUN rm -rf in-progress
|
|
||||||
RUN apt update
|
|
||||||
RUN apt -yq install racket ca-certificates
|
|
||||||
RUN yes Y | raco pkg install --no-docs csv-reading
|
|
||||||
RUN raco exe sorrel.dev.rkt
|
|
||||||
RUN raco distribute dist sorrel.dev
|
|
662
LICENSE
Normal file
662
LICENSE
Normal file
|
@ -0,0 +1,662 @@
|
||||||
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 19 November 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU Affero General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works, specifically designed to ensure
|
||||||
|
cooperation with the community in the case of network server software.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
our General Public Licenses are intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
Developers that use our General Public Licenses protect your rights
|
||||||
|
with two steps: (1) assert copyright on the software, and (2) offer
|
||||||
|
you this License which gives you legal permission to copy, distribute
|
||||||
|
and/or modify the software.
|
||||||
|
|
||||||
|
A secondary benefit of defending all users' freedom is that
|
||||||
|
improvements made in alternate versions of the program, if they
|
||||||
|
receive widespread use, become available for other developers to
|
||||||
|
incorporate. Many developers of free software are heartened and
|
||||||
|
encouraged by the resulting cooperation. However, in the case of
|
||||||
|
software used on network servers, this result may fail to come about.
|
||||||
|
The GNU General Public License permits making a modified version and
|
||||||
|
letting the public access it on a server without ever releasing its
|
||||||
|
source code to the public.
|
||||||
|
|
||||||
|
The GNU Affero General Public License is designed specifically to
|
||||||
|
ensure that, in such cases, the modified source code becomes available
|
||||||
|
to the community. It requires the operator of a network server to
|
||||||
|
provide the source code of the modified version running there to the
|
||||||
|
users of that server. Therefore, public use of a modified version, on
|
||||||
|
a publicly accessible server, gives the public access to the source
|
||||||
|
code of the modified version.
|
||||||
|
|
||||||
|
An older license, called the Affero General Public License and
|
||||||
|
published by Affero, was designed to accomplish similar goals. This is
|
||||||
|
a different license, not a version of the Affero GPL, but Affero has
|
||||||
|
released a new version of the Affero GPL which permits relicensing under
|
||||||
|
this license.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, if you modify the
|
||||||
|
Program, your modified version must prominently offer all users
|
||||||
|
interacting with it remotely through a computer network (if your version
|
||||||
|
supports such interaction) an opportunity to receive the Corresponding
|
||||||
|
Source of your version by providing access to the Corresponding Source
|
||||||
|
from a network server at no charge, through some standard or customary
|
||||||
|
means of facilitating copying of software. This Corresponding Source
|
||||||
|
shall include the Corresponding Source for any work covered by version 3
|
||||||
|
of the GNU General Public License that is incorporated pursuant to the
|
||||||
|
following paragraph.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the work with which it is combined will remain governed by version
|
||||||
|
3 of the GNU General Public License.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU Affero General Public License from time to time. Such new versions
|
||||||
|
will be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU Affero General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU Affero General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU Affero General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If your software can interact with users remotely through a computer
|
||||||
|
network, you should also make sure that it provides a way for users to
|
||||||
|
get its source. For example, if your program is a web application, its
|
||||||
|
interface could display a "Source" link that leads users to an archive
|
||||||
|
of the code. There are many ways you could offer source, and different
|
||||||
|
solutions will be better for different programs; see section 13 for the
|
||||||
|
specific requirements.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||||
|
<https://www.gnu.org/licenses/>.
|
||||||
|
|
32
README
32
README
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
| λ sorrel.dev |\
|
| λ oxaliq.net |\
|
||||||
\--------------\ \
|
\--------------\ \
|
||||||
\______________\|
|
\______________\|
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ expressivity!) someday, i might turn it into a proper dsl with support for htmx'
|
||||||
|
|
||||||
i make generous use of `racket/web-server` with a dispatcher for `hx/` prefixed content
|
i make generous use of `racket/web-server` with a dispatcher for `hx/` prefixed content
|
||||||
(snippets of html), and plain `/` (for rendering full pages.) handlers build the
|
(snippets of html), and plain `/` (for rendering full pages.) handlers build the
|
||||||
content from the little sexpr .txt files (they're not valid racket on they're own,
|
content from the little sexpr .scm files (they're not valid racket on they're own,
|
||||||
they get read and evaluated as data.) it's all real small and everything, but i figured
|
they get read and evaluated as data.) it's all real small and everything, but i figured
|
||||||
why not save the generated html in a `static/` directory so it doesn't need to be built
|
why not save the generated html in a `static/` directory so it doesn't need to be built
|
||||||
on each request? so that's what happens.
|
on each request? so that's what happens.
|
||||||
|
@ -105,5 +105,33 @@ there's a couple things this'll do.
|
||||||
|
|
||||||
so that's simple enough.
|
so that's simple enough.
|
||||||
|
|
||||||
|
______________________
|
||||||
|
|----------------------|
|
||||||
|
| HOW TO MODIFY A POST |
|
||||||
|
|----------------------|
|
||||||
|
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||||
|
so, some things aren't done til yr dead. some of those things might be posts. `publish`
|
||||||
|
is always going to move yr text into archive/ and you'll be able to move that file back
|
||||||
|
to in-progress/ when yr ready to start working on it again.
|
||||||
|
|
||||||
|
then you can use the "modify" tool. here's how it works
|
||||||
|
```
|
||||||
|
$ modify -i in-progress/ex.txt \ # -i is for the input
|
||||||
|
-r unsettled \ # -r is for the resource type
|
||||||
|
-l "An Example Text" \ # -l is for the head_l_ine (title)
|
||||||
|
```
|
||||||
|
you can't currently change the description or the tags on existing posts.
|
||||||
|
what this does:
|
||||||
|
- update the csv files for the resource type
|
||||||
|
- rebuilds the source with footer and metadata and tags
|
||||||
|
- update the atom feed, but this time with a "updated" tag in the entry
|
||||||
|
|
||||||
|
if at any point the script encounters a problem, any changes will be rolled back
|
||||||
|
|
||||||
|
_________
|
||||||
|
| LICENSE |
|
||||||
|
¯¯¯¯¯¯¯¯¯
|
||||||
|
the source code is available under GNU AGPLv3 : /LICENSE
|
||||||
|
the content (in source directory) is available under
|
||||||
|
CC-BY-SA-4.0 : static/license/license.txt
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
"a plant called sorrel")
|
"a plant called sorrel")
|
||||||
" and i live in the mountains of southern appalachia on "
|
" and i live in the mountains of southern appalachia on "
|
||||||
(span ((lang "chr")) "ᏣᎳᎩ")
|
(span ((lang "chr")) "ᏣᎳᎩ")
|
||||||
" (tsalagi/cherokee) land. i live with some cats and a whole mess of plants
|
" (tsalagi/cherokee) land")
|
||||||
(most of them food) and a cordswain and i have sweet neighbors")
|
|
||||||
(p
|
(p
|
||||||
"i have never identified with the term 'hacker' but i have learned, in the
|
"i have never identified with the term 'hacker' but i have learned, in the
|
||||||
past few years, that i do like to orchestrate computer machines and i do
|
past few years, that i do like to orchestrate computer machines and i do
|
||||||
|
@ -42,7 +41,13 @@
|
||||||
"language (computer) to make languages (human)"))))
|
"language (computer) to make languages (human)"))))
|
||||||
;; mmt bullet
|
;; mmt bullet
|
||||||
(li (p "mmt, but make it anarchist "
|
(li (p "mmt, but make it anarchist "
|
||||||
(small "and get rid of all that \"sovereignty\" stuff, ew")))
|
(small "-- get rid of all that \"sovereignty\" stuff, ew")))
|
||||||
|
;; library bullet
|
||||||
|
(li (p "make everything a library and everyone a librarian"))
|
||||||
|
;; end user programming bullet
|
||||||
|
(li (p "do things that aren't computer. compute more with regular computer ppl
|
||||||
|
and less with tech-brained ppl. most ppl know how to compute, and don't
|
||||||
|
need to know what is an abstract factory factory"))
|
||||||
;; neuroqueer bullet
|
;; neuroqueer bullet
|
||||||
(li (p "got a spicy brained, trans lady-fied experience.
|
(li (p "got a spicy brained, trans lady-fied experience.
|
||||||
i have feelings about these things that inevitably weave thru
|
i have feelings about these things that inevitably weave thru
|
|
@ -65,7 +65,7 @@
|
||||||
for a multi-purpose conlanging tool that was beginning to take shape in my head")
|
for a multi-purpose conlanging tool that was beginning to take shape in my head")
|
||||||
(p "i tried anyway")
|
(p "i tried anyway")
|
||||||
(p "and i made "
|
(p "and i made "
|
||||||
(a ((href "settled/1"))
|
(a ((href "/settled/1"))
|
||||||
"a bad first draft of a sound change tool"))
|
"a bad first draft of a sound change tool"))
|
||||||
(p
|
(p
|
||||||
"there's an e-bnf grammar in that project somewhere! the hubris i
|
"there's an e-bnf grammar in that project somewhere! the hubris i
|
||||||
|
@ -123,14 +123,14 @@
|
||||||
(hr))
|
(hr))
|
||||||
(p
|
(p
|
||||||
"i'm just gonna fly right through these. there's going to be a lot
|
"i'm just gonna fly right through these. there's going to be a lot
|
||||||
to read up on, to explore, to think and talk through, before it
|
to read up on, to explore, to think and talk through, to build
|
||||||
gets time to prototyping and to building a workable tool. so,
|
toy versions of before it gets time for larger prototyping and
|
||||||
here's the very start of the thinking-in-public. each of these
|
building a workable tool. so, here's the very start of the
|
||||||
little thoughts is going to get at least it's own writeup (if not
|
thinking-in-public. each of these little thoughts is going to get
|
||||||
several) and i'll update with additional sections and links to
|
at least it's own writeup (if not several) and i'll update with
|
||||||
the writeups as i go. a note: it would be impossible for me (and
|
additional sections and links to the writeups as i go. a note: it
|
||||||
probably most ppl) to create the full vision in the time i'll be
|
would be impossible for me (and probably most ppl) to create the
|
||||||
working on it fulltime")
|
full vision in the time i'll be working on it fulltime")
|
||||||
(section
|
(section
|
||||||
(h3 "notes on the goals")
|
(h3 "notes on the goals")
|
||||||
(p
|
(p
|
6
archive/contact.scm
Normal file
6
archive/contact.scm
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
(section
|
||||||
|
(h2 "contact")
|
||||||
|
(p (code "email [at] [this domain]") " to send me a good ol' fashioned email")
|
||||||
|
(p
|
||||||
|
"i have avoided 'online' for a long time, but i'm getting hip to it. i'm
|
||||||
|
on the mastodon.social server @oxaliq"))
|
|
@ -1,12 +0,0 @@
|
||||||
(section
|
|
||||||
(h2 "contact")
|
|
||||||
(p "e-m-"
|
|
||||||
(span "a-i")
|
|
||||||
(span "-l [ at ")
|
|
||||||
(span "] s-o-")
|
|
||||||
(span "r-r-e-l [ d o")
|
|
||||||
(span "t ] d-e")
|
|
||||||
(span "-v is a good place to do the email"))
|
|
||||||
(p
|
|
||||||
"i have avoided 'online' for a long time, but i'm getting hip to it. i'm
|
|
||||||
on the big mastodon server @oxaliq"))
|
|
100
archive/feature-change-applier.scm
Normal file
100
archive/feature-change-applier.scm
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
(article
|
||||||
|
(hgroup
|
||||||
|
(h1 "feature change applier")
|
||||||
|
(p (em "a first attempt at a conlanging tool")))
|
||||||
|
(section
|
||||||
|
(hgroup
|
||||||
|
(h2 "what is this?")
|
||||||
|
(p
|
||||||
|
(em
|
||||||
|
"a tool for conlanging: a feature-based sound-change applier
|
||||||
|
capable of applying multiple sets of rules at once."))
|
||||||
|
(hr))
|
||||||
|
(p
|
||||||
|
"you can try it out here: "
|
||||||
|
(a ((href "https://sorrelbri.github.io/feature-change-applier/"))
|
||||||
|
"feature change applier app"))
|
||||||
|
(img ((src "/static/img/settled/1/fca.jpg")
|
||||||
|
(alt "an image of Feature Change Applier application. visible
|
||||||
|
are labeled sections. 'proto language lexicon' is a text
|
||||||
|
field with nonsense weirds. 'phonetic features' is a list
|
||||||
|
of binary values shuch as '+ back' / '- back' and
|
||||||
|
characters representing associated sounds like 'a / u / ɯ'
|
||||||
|
/ 'ə', 'epoch 1' is a text field with a list of phonetic
|
||||||
|
rules such as
|
||||||
|
'[+ occlusive - nasal]>[+ occlusive + nasal]/n_.' and
|
||||||
|
buttons to 'Remove epoch 1' or 'Add Epoch'. 'modeling
|
||||||
|
options' is a single selected radio button labeled
|
||||||
|
'Default output' with buttons labeled 'Run Changes' and
|
||||||
|
'Clear Output'. 'Results of Run' is a list headed 'epoch
|
||||||
|
1' and containing newline separated words 'annɯ anat ant
|
||||||
|
annɯ tʰa nnɯ")))
|
||||||
|
(h3 "an unfinished project")
|
||||||
|
(p
|
||||||
|
"some background on conlanging and my interst in conlanging software
|
||||||
|
can be found in this "
|
||||||
|
(a ((href "/unsettled/1"))
|
||||||
|
"introductory post about conlanging software"))
|
||||||
|
(p
|
||||||
|
"this project was initially intended to function as a sound change
|
||||||
|
applier: a software tool that takes as input a list of lexical items
|
||||||
|
in a language and a list of sound change rules and produces as
|
||||||
|
output a new list of lexical items resulting from the application of
|
||||||
|
each rule to each of the lexical items in the input. more info about
|
||||||
|
sound change appliers will be available: "
|
||||||
|
(a ((href "/unsettled/?"))
|
||||||
|
"[pending] review of existing conlanging tools"))
|
||||||
|
(p
|
||||||
|
"there are two ways in which i sought to extend the functionality of
|
||||||
|
the typical sound change applier: through feature-based rules, and
|
||||||
|
through the processing of multiple rule sets at one time. "
|
||||||
|
(a ((href "https://en.wikipedia.org/wiki/Distinctive_feature"))
|
||||||
|
"phonological features")
|
||||||
|
" are proposed binary attributes of phonology that can be used to
|
||||||
|
distinguish different phonemes. [+/- nasal] is the distinguishing
|
||||||
|
feature in the minimal pair of phones [n][d]. the processing of
|
||||||
|
multiple rule sets is accomplished in this project via the notion
|
||||||
|
of an 'epoch.' at least one epoch must be defined, which takes as
|
||||||
|
its input the initial lexicon. any additional epochs must have
|
||||||
|
their input lexicons configured by the user, but they will default
|
||||||
|
to running in sequence. what this allows is for 'snapshots' of
|
||||||
|
lexicons between suites of rules (analogous to 'intermediate'
|
||||||
|
phases in historical linguistics, such as old english>middle
|
||||||
|
english>early modern english>modern english.) this also allows for
|
||||||
|
comparisons of different rule sets or the simulation of sound
|
||||||
|
changes across a family of related languages (analogous to vulgar
|
||||||
|
latin>italo-western, vulgar-latin>eastern romance, vulgar
|
||||||
|
latin>southern romance)")
|
||||||
|
(p
|
||||||
|
"both of these additional features are present, although the app is
|
||||||
|
quite buggy and unreliable"))
|
||||||
|
(section
|
||||||
|
(hgroup
|
||||||
|
(h2 "how does it work?")
|
||||||
|
(p (em "i'll tell you what i remember"))
|
||||||
|
(hr))
|
||||||
|
(p
|
||||||
|
"i made this a few years ago, right after i first learning how to
|
||||||
|
write web apps and so i used the tools that i knew a few years ago.
|
||||||
|
this means that it's javascript! specifically, a react app, where
|
||||||
|
all the fun processing stuff happens via the react hooks useReducer
|
||||||
|
pattern. "
|
||||||
|
(a
|
||||||
|
((href
|
||||||
|
"https://github.com/sorrelbri/feature-change-applier/tree/sj_latl/src/reducers"
|
||||||
|
)) "all of the reducers are here"))
|
||||||
|
(p
|
||||||
|
"at the end of my meaningful work on the project, i started using a "
|
||||||
|
(a ((href "https://nearley.js.org/"))
|
||||||
|
"javascript earley parser called nearley")
|
||||||
|
" as i started conceptualizing the tool as just one component in a
|
||||||
|
larger suite of tools i hoped to create. the language part never got
|
||||||
|
very far--writing a language is hard! writing a language when you've
|
||||||
|
not had significant programming experience is hard! ill advised? "
|
||||||
|
(a
|
||||||
|
((href
|
||||||
|
"https://github.com/sorrelbri/feature-change-applier/blob/sj_latl/src/utils/latl/grammar.ne"))
|
||||||
|
"there's the start of something like an ebnf grammar for the
|
||||||
|
project"))
|
||||||
|
(p
|
||||||
|
"this project isn't done! and it never will be!")))
|
55
archive/latl-primitives.scm
Normal file
55
archive/latl-primitives.scm
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
'(article
|
||||||
|
((id "latl-primitives")
|
||||||
|
(class "composed-article"))
|
||||||
|
;; brief intro - restate the problem
|
||||||
|
(section
|
||||||
|
((id "intro"))
|
||||||
|
(hgroup
|
||||||
|
(h1 "what must be true of latl primitives")
|
||||||
|
(p (em "what will latl need to " (u "do") " out of the box?")))
|
||||||
|
(p "i've talked a little about "
|
||||||
|
(a ((href "/unsettled/1")) "conlanging and latl")
|
||||||
|
" previously here. the short version is this: making languages (for theoretical conscious beings) is fun! it's been a consistent hobby and artistic pursuit for me for much of my life. i've had different approaches from making extremely regular languages, to simulating the evolution of a family of spoken languages, to a family of synthesizer languages for a fractured machine society. every language project requires keeping track of a dictionary and a grammar (even if they never become more than quick sketches) and any sufficiently involved project can benefit from tools for generating new words that fit a language's 'phonotactics', generating derived words based on grammatical rules, simulating language change over time. conlanging is a hobby with enough overlap with computation, that some conlangers have created tools for some of these tasks. my own projects have become too ambitious to have my work live in spreadsheets over here and latex files over there and text files with the defintions i provide to web-based tools somewhere else entirely. i want to build on the work of those came before and create a substrate upon which any tool a conlanger needs could be built and in which i can define the entirety of a language in one system.")
|
||||||
|
(p "at it's base latl will be a tool for operating on languages, invented (or otherwise... maybe.) it helps then to think of the sorts of things that encompass language. spoken and signed languages will be the assumed base case, as those are the things real human beings usually use to communicate with each other. the modality of a language needn't be important to the primitives used, but it's always a good practice to state assumptions"))
|
||||||
|
(section
|
||||||
|
((id "contents"))
|
||||||
|
(ul (li (a ((href "#what-is-language")) "go to what-is-language"))
|
||||||
|
(li (a ((href "#what-conlangers-do")) "go to what-conlangers-do"))
|
||||||
|
(li (a ((href "#proposed-latl-primitives")) "go to proposed-latl-primitives"))
|
||||||
|
(li (a ((href "#signoff")) "go to signoff"))))
|
||||||
|
;; article contains three main sections:
|
||||||
|
;; 1. thinking about language
|
||||||
|
;; 2. talking about conlangers
|
||||||
|
;; 3. working through some ideas for primitives
|
||||||
|
;; ---
|
||||||
|
;; section 1. thinking about language
|
||||||
|
(section
|
||||||
|
((id "what-is-language"))
|
||||||
|
(hgroup
|
||||||
|
(h2 "thinking about what language is for a moment"))
|
||||||
|
(a ((href "/unsettled/latl-primitives_what-is-language")
|
||||||
|
(hx-get "/hx/unsettled/latl-primitives_what-is-language")
|
||||||
|
(hx-target "#what-is-language")
|
||||||
|
(hx-swap "outerHTML"))
|
||||||
|
"what-is-language"))
|
||||||
|
;; section 2. okay but conlangers
|
||||||
|
(section
|
||||||
|
((id "what-conlangers-do"))
|
||||||
|
(hgroup
|
||||||
|
(h2 "what conlangers do")
|
||||||
|
(p (em "moving from a pile of language stuff to a pile of problems to solve")))
|
||||||
|
(p "coming soon"))
|
||||||
|
;; section 3. introducing the primitives
|
||||||
|
(section
|
||||||
|
((id "proposed-latl-primitives"))
|
||||||
|
(hgroup
|
||||||
|
(h2 "introducing the primitives")
|
||||||
|
(p (em "things that definitely need to be present in latl")))
|
||||||
|
(p "coming soon"))
|
||||||
|
;; brief conclusion and next steps
|
||||||
|
(section
|
||||||
|
((id "signoff"))
|
||||||
|
(hgroup
|
||||||
|
(h2 "signing off")
|
||||||
|
(p (em "what's next for latl thinking?")))
|
||||||
|
"coming soon"))
|
60
archive/latl-primitives_what-is-language.scm
Normal file
60
archive/latl-primitives_what-is-language.scm
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
(section
|
||||||
|
((id "what-is-language"))
|
||||||
|
(hgroup
|
||||||
|
(h2 "thinking about what language is for a moment"))
|
||||||
|
(p "by way of an opening query: what does a language need? naturally our base case spoken languages have sounds and our base case signed languages have gestures. for each of these, we have an articulatory mechanism: the vocal tract, or the face and hands and arms; and a perceptual mechanism: the auditory system, or the visual system. the unique thing about language among other forms of communication is how languages use time. it might seem basic, but it's easy to forget that 'my cat scratched the post' and 'the post scratched my cat' mean very different things. and the same sounds in a different sequence can become a smattering of ideas as in 'the my scratched cat post' or even lose meaning all together as in 'cra catsm sde thymst opsh'. languages differ on how they use time--some languages allow more freedom for word order than others, but relationships between articulations through time are essential to all known languages. for now, let's start with those articulatory bits! (more on time and on meaning later)")
|
||||||
|
;; 1.1 phonemes
|
||||||
|
(section
|
||||||
|
((id "phonemes"))
|
||||||
|
(hgroup
|
||||||
|
(h3 "phonemes")
|
||||||
|
(p (em "what even are they?")))
|
||||||
|
(p "no talk of letters here! no "
|
||||||
|
(q ((style "font-family: serif; font-style: italic; padding: 1px 2px;"))
|
||||||
|
"'ghoti' is pronounced 'fish'")
|
||||||
|
" jokes! instead, let's imagine how to describe the difference in articulation and in reception between 'mine' and 'fine' and 'wine' and 'dine' or between '"
|
||||||
|
;; add ASL rhymes
|
||||||
|
"'. these words rhyme! which (for short words) is a way of saying that most of their sounds are the same, and the similar bits come at the end. "
|
||||||
|
(footnote "rhyme is a little more complicated than that, encompassing stress patterns") ;; describe ASL rhymes
|
||||||
|
;; awkward
|
||||||
|
""
|
||||||
|
"it is uncontroversial to suggest that there is a basic articulatory/perceptual unit in any given modality which, when strung together, produces the basic units of meaning. this basic unit, no matter the modality, is called the 'phoneme'."
|
||||||
|
(footnote "historically, called a 'chereme' in sign languages")
|
||||||
|
"in selecting the words i have, i've already hinted at how linguists support the existence of these phonemes. 'dine' and 'fine' together form a 'minimal pair' of words with a different meaning whose difference is found in only one perceptually distinct part of their articulation. because we know from english language usage that 'mine' and 'fine' and 'wine' and 'dine' are distinct words with distinct meaning, we have a clue that there is some phonemic difference between /m/ and /f/ and /w/ and /d/. by collecting more examples of these minimal pairs ('do' and 'moo' and 'wed' and 'dead' and on and on) we can begin to describe the physical sounds associated with each phoneme and how each is articulated.")
|
||||||
|
(p "human bodies are inexact things--perception is important here! it does us no good to describe an extra-tightly clenched middle finger in a closed hand shape as indicative of a distinct phoneme as it would be unlikely to be perceptible to an interlocutor and so could never disambiguate between two signs. environments are noisy and so articulation is also important! in my dialect of english the word 'put' /pʊt/, in a noisy environment, might be pronounced roughly [pʰʊtʰ]. in casual speach, however this same word is frequently realized as [pʰɵʔ] with the only audible consonant at the end being the glottal closure of 'uh-oh'. the only ghost of the exaggerated realization is typically an inaudible tongue placement behind the alveolar ridge. a speaker recognizes what the phoneme 'could be' with more effort, but typically such effort is unnecessary for understanding. this suggests that there phonemes are not simply sounds or handshapes or mouth movements. something must be underlying the equality of meaning between [pʰʊtʰ] and [pʰɵʔ]")
|
||||||
|
(p "there's a fairly wide consensus amongst linguists that, despite being the minimal constituent needed to represent meaning in language, phonemes are " (strong "not atomic.") " a phoneme can be decomposed into constituent features and minimal pairs of phonemes can be shown to be distinct only in their realization of one feature. by way of example, the [b] in the word 'shabby' and the [m] in the word 'shammy' differ only in that the [m] is pronounced with air passing through the nasal cavity. the feature [+/- nasal] is therefore taken to be a salient feature in english phonology")
|
||||||
|
(p "all well and good, but things start to get tricky when we start defining features. firstly, there is no single agreed upon set of features by which to analyze all languages of a given modality. as stated, there's broad agreement that phonetic features exist and many proposed features are uncontroversial, yet even linguists analyzing the same language can disagree upon featural details. vowels in particular are quite slippery to analyze, with [+/- back], [+/- close], [+/- front], [+/- low], [+/- high], [+/- tongue root retracted], [+/- rounded] among the features present in different systems. there are also some linguists who, relying on auditory analysis, analyze vowels primarily via formant analysis. (formants are measures of what is sometimes referred to as 'resonance' or 'vowel color' -- they are the pitches above the fundamental frequency with the greatest relative amplitude.) it is this amateur crank's opinion that because articulation and perception are subject to different constraints and pressures, what is deemed a feature can elide a relationship between speach actor and interlocutor. thankfully, should latl allow for user definition of features and their phonemes, it can remain agnostic to the hairy work of actual linguistics")
|
||||||
|
(p "users should therefore be able to define their own phonetic feature sets and use those to compose their phonemes. (i'm going to sneak in the undefended assertion here that users should be able to use "(em "other users'") " definitions as well. forgive me.) if you're reading this and are familiar with linguistics, you might now be wondering about the curious case of place of articulation. should place features be treated as hierarchichal -- should [coronal] place of articulation be required for [+/- anterior] feature of the crown of the tongue? if so, how are coarticulations like [tʷ] or [k͡p] to be expressed in featural terms? here again, latl will allow for the definition of hierarchichal features and make no assumptions about their use")
|
||||||
|
(p "yet another problem is hiding in the view i've thus provided of phonological features. there is a wide (but not universal) belief that distinctive features in phonology are inherently binary. this is convenient from a computational perspective, but may not be descriptive of real language. firstly, it is possible to analyze [coronal] in the previous paragraph as a unary feature relevant to place of articulation. more distressingly, a proposed feature set that includes [+/- high] and [+/- low] predicts the nonsense value set: {[+ high] [+ low]}. one approach to this conundrum is to propose a feature scale [-1/0/1 height]. this is far from a settled matter, but latl should prioritize a user's ability to define such feature scales over implementation considerations or linguistic debate")
|
||||||
|
(p "it's been a few paragraphs without any mention of sign languages, so it is worth gesturing at how their phonological features relate to these considerations to ensure latl doesn't start it's life with a modality bias. sign languages are widely understood to have phonological systems that are featural. as is the case with spoken languages, specifics of feature sets vary based on language and researcher. features can be salient to a language and form minimal pairs ie [+/- palm prone] is one way of reading the difference between the ASL fingerspelling signs for /p/ and /k/. research suggests that there is a high degree of hierarchichal complexity in the phonological features of sign languages, which maps very neatly to the place of articulation problem in spoken languages. features related to handshape, such as [+/- flex] or [+/- extension] only make sense in regards to selected fingers. i have not seen any research about featural scales in sign languages, but it would be unsurprising to analogize the same issues arising from nonsense combinations of binary features") ;; TODO add some ASL images (maybe sound for some of the english bits?
|
||||||
|
(p "let's zoom back out to phonemes for a moment to add another wrinkle to the featural representation. the notion (unconscious or not) a speaker of a language has for what constitutes a single sound is understood to be a 'bundle' of features, but not every feature holds the same importance in every environment. by way of example, the /t/ phoneme in my dialect of english can be realized in a number of different ways depending on its location. it can be aspirated [tʰɑk] with [+ spread glottis] (or [+ delayed onset] if you prefer an auditory approach) in 'tock', without aspiration [stɑk] [- spread glottis] in 'stock', or as a flap [ˈbʌ.ɾək] in 'buttock'. this flap differs from the others at least in having [+ sonorant] and [+ voice], but retaining [coronal] [+ anterior]. yet, if i heard *[ɾɑk] in isolation, i would assume the speaker was referring to a stone or a genre of music. this situation is called allophony and latl must maintain a way to treat phonemes like /t/ as salient bundles of features distinct from the more discrete phones [tʰ], [t], [ɾ] (or [ʔ] from the earlier example) whose features are more specified. once again, we see a similar situation with regards the ASL phoneme, /e handshape/ which has allophonic representations [+ open aperture] (the unmarked /e/ familiar in the fingerspelled alphabet) and [- open aperture] in certain environments")
|
||||||
|
(p "warning! that [r] in my dialect of english, is an allophone of two different phonemes! the realization of the words /bæt.ər/ and /bæd.ər/ ('batter' and 'badder') is the same: [bæɾ.ɚ]. this 'under-specification' of not unique to my dialect of english and some linguists propose an archiphoneme /D/ which is a kind of set of /t/ and /d/ to account for this. in this view 'batter' and 'badder' are orthographically distinct, but phonemically both /bæD.ər/. is this 'really' what is going on? i'm not qualified to say, but i am confident that latl can be made to handle this situation without straining our abstractions too much")
|
||||||
|
(p "to recap thus far, we have phonemes, which for the purpose of latl are bundles of features of some value. features may be defined by the user of latl into feature systems, whereby they are usually but not always binary and may each have a dependency on another feature in the system. phonemes may have features of varying saliency allowing for allophony. these allophones are phones whose features are slightly different but retain the salient features of their phoneme, whether that phoneme is specified or an underspecified archiphoneme that could represent multiple phonemes. as an additional item, it is helpful to have a shorthand to refer to phonemes and their allophones, ie "(code "/t/") ", "(code "[tʰ]") ", " (code "[t]") ", and " (code "[ɾ]") " or " (code "/D/"))
|
||||||
|
(p "an EBNF grammar (because grammars are fun!) of this relationship might be ")
|
||||||
|
(code "phoneme = positive-integer * phone { phoneme } ) ; (* a phoneme must be a set of phones and optional (archi-)phoneme *)" (br)
|
||||||
|
"phone = positive-integer * feature ; (* a phone must be a set of features *)" (br)
|
||||||
|
"feature = ( value, identifier ) | positive-integer * feature ; (* a feature must be a value with some identifier or a set of (dependent) features *)" (br)
|
||||||
|
"value = non-negative integer ;" (br)
|
||||||
|
"identifier = letter, { letter | \"-\" } ; (* lispy identifiers assumed for now *)" (br)
|
||||||
|
"non-negative-integer = digit , { digit } ; (* from here i'll take for granted the definition of digits and letters *)" (br))
|
||||||
|
(p "this grammar is insufficient to the purpose, but i include it to point at the recursive nature of both phonemes and features revealed by the constraints defined so far. an additional constraint must be that features are bound in a global feature system and a featural definition of a phone requires values for every possible feature within that feature system. additionally, a feature value can be any within a bound set where each feature can be associated with a different set; so, [+/- nasal] and [-1/0/1 high] can exist within the same feature system, but any instance of [nasal] must have a value of [+] or [-] and any value of [high] must have [-1], [0], or [1]. the grammar handwaves with non-negative-integer by analogy with enums in many programming languages. this grammar also defines a language that would be repetitive and finicky to work with. instead of optimizing, i'd like to take a moment to consider the phoneme already solved in latl and think a little bit about how they're used"))
|
||||||
|
;; 1.2 lexemes
|
||||||
|
(section
|
||||||
|
((id "lexemes"))
|
||||||
|
(hgroup
|
||||||
|
(h3 "lexemes")
|
||||||
|
(p (em "zooming out a little to the fundamental unit of meaning")))
|
||||||
|
(p "note! for the purpose of this exploration, a lexeme is assumed to be synonymous with 'root morpheme'." (small " if you don't know what this note means, please be aware that i'm being a little bit of a crank again. if you do know what this note means and are suspicious, run with me here for a sec; we'll get to it"))
|
||||||
|
(p "for now i'll posit that a lexeme is an ordered sequence of phoneme(s) that corresponds to a productive, atomic meaning. a lexeme MAY be subject to derivation rules which transform its meaning or its role in an utterance, for now called 'derived forms'. this definition allows for any 'part of speach' so long as the lexeme is not derived. taking for granted, for a moment, the category 'word', here's a selection of english words that fit this definition of lexeme: 'a', 'she', 'her', 'for', 'four', 'write', 'right', 'quick', 'quit', 'dirigible', 'abstract'")
|
||||||
|
(p "included are 'function words' (the closed set of grammatically necessary words without independent meaning) like 'a', 'she', 'her', and 'for'. 'content words' are also included (the open set of words with semantic weight) beginning with 'four'. but of course, i've also chosen these words to illustrate some potential traps. we have some phonetic ambiguities: 'for' and 'four' are distinct in some english dialects, but i pronounce them both /fɔɹ/. 'write' and 'right' are indistinguishable from each other in every english and sound something like /ɹajt/. the situation is tricky in this case semantically as well! this is one sequence of sounds upon which multiple different etymologies (encoding mark-making, correctness, directionality, or politics) have converged. if the written forms are any hint, there should be at least two separate lexemes")
|
||||||
|
(p "i've also snuck in the pair 'she' and 'her'. traditionally, 'her' is held to be a derived form of 'she' violating our 'root morpheme' assumption. leaving aside the linguistic reasons to consider 'her' a derived form, there's still the question of what plausible derivation rule could turn the sound sequence /ʃi/ into /hɜɹ/? (" (small "the ancestral form of 'her' probably was transparently derived from the ancestral form of 'she', but in this project i'm concerned with how these derivations are obscured by language change through time") ")")
|
||||||
|
(p "the write/right example and the she/her example, in slightly different ways, both recall the bidirectional nature of language. an idealized speaker *knows* which specific meaning (specific lexeme?!) of /ɹajt/ they are referring to, but their interlocutor must derive the appropriate meaning from context. likewise, a proficient speaker produces /ʃi/ and /hɜɹ/ in the appropriate position within a sentence without difficulty, while a language learner may struggle to hear the connection between the two forms. (other interesting possibilities include using one or the other form in all locations or in random distribution; analogizing the regularity of /hi/->/hɪm/ ('he'/'him') to /ʃi/->/ʃɪm/ where a /hɜɹ/ is expected; or using /hi/, /ʃi/, /ðej/ 'they' or other third person pronouns interchangeably. all of these point at some other juicy stuff that will have to be shelved for now.) this bidirectionality means that latl will need to support the mapping of a sequence of phonemes to an arbitrary number of lexemes, although for now it's safe to assume that a lexeme has only one associated sequence of phonemes. (ignoring, for the moment, variant pronunciations as in 'the' /ði/~/ðə/)")
|
||||||
|
(p "a lexeme will probably need some additional stuff, tho. at the very least a 'dictionary definition' and, of course, a shorthand, ie " (code "/ʃi/") ", " (code "/hɜɹ/") ", or " (code "/ɹajt/")". there's absolutely more to what latl will require from a lexeme (and users should be able to extend the lexeme primitive to their own ends) but that will have to wait for now")
|
||||||
|
(p "before moving on"))
|
||||||
|
;; 1.3 morphosyntax or morphemes?
|
||||||
|
(section
|
||||||
|
((id "morphosyntax"))
|
||||||
|
(hgroup
|
||||||
|
(h3 "morphosyntax")
|
||||||
|
(p (em "where meaning and phonology and time start getting funky"))))
|
||||||
|
(p ""))
|
44
archive/notes-from-rc.scm
Normal file
44
archive/notes-from-rc.scm
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
(article
|
||||||
|
((id "oxaliq-at-rc"))
|
||||||
|
(hgroup
|
||||||
|
(h1 "oxaliq at rc")
|
||||||
|
(p (em "dispatches from the edge of my abilities")))
|
||||||
|
(section
|
||||||
|
((id "week-1"))
|
||||||
|
(h2 "week 1")
|
||||||
|
(p "well, i'm here. at " (a ((href "https://recurse.com")) "recurse center") " very recent life events had me unsure if this would be possible. but, here i am! writing about my feelings, and putting the "
|
||||||
|
(a ((href "https://www.recurse.com/self-directives")) "self directives") " here, so i can reference them as i reflect")
|
||||||
|
(p (strong "work at the edge of yr abilities") (br)
|
||||||
|
"be ambitions about what you can achieve and honest in yr current capacity")
|
||||||
|
(p (strong "build yr volitional muscles") (br)
|
||||||
|
"practice making decisions based on intrinsic motivators, yr curiosity and joy")
|
||||||
|
(p (strong "learn generously") (br)
|
||||||
|
"seek support when needed, offer when asked, share, share, share yr interests yr struggles yr successes yr enthusiasm for others")
|
||||||
|
(p "it's funny. there are a lot of ways i feel less-than as a developer. in more than a few workplaces i've been shunted to the corner to figure things out on my own, because i am generally 'autodidactic' as a former boss called me. but, i have not felt free to share my enthusiasm or my struggles in professional contexts. i'm absolutely a generalist of the higher end of the stack, with no particular specialization and i ... have feelings ... about that. however, the larger impediment to my growth has been this feeling of isolation -- of needing to figure things out on my own")
|
||||||
|
(p "i came into this experience certain i was going to work on " (a ((href "/tagged/latl")) "latl") " but as the time to start my batch drew nearer and as the flood of new ideas came on during my first week, that certainty evaporated. dreaming up grand plans is not difficult for me; i am even occassionally honest enough about my capacity to take the lots of baby steps to get there. there were some themes tho, in evaluating the bubbling froth of ideas of where to put my energy for the next eleven weeks. and the most resonant were social utility and the potential of not-working-alone. while i'm at rc, i will be not-working-alone no matter what i do. but the latl idea is so niche that my explanation '(a dsl for conlangers) expanded into '(a racket-hosted domain specific language . for creating tools to construct human languages) into '(a domain-specific programming language . hosted in a technology designed around language oriented programming . treating linguistic data and procedures to manipulate that data homoiconically . allowing for the definition of phonology & phonotactics, lexicon, morphosyntax -- if you believe in that sort of thing --, pragmatics and hopefully even semantics of a given language in the same program as the history of that language's change and any resulting languages in the family). which i still think is really cool! but it's an idea that's been tickling me for years, and it's maybe too niche for this moment in my life. too difficult to associate with the work of other's here. and even worse1 tho i really love the hobby of conlanging and the creativity that tools like this could engender..., the social utility piece just isn't there for me")
|
||||||
|
(p "okay, so a new idea. " (a ((href "/tagged/uf-library")) "lending library software") ". but for scrappy community projects, not powerful institutions. and with the ability for any library member to be a lendor. and any lendor to lend to any member of any library they'd like for as long as they like. similar to fediverse but for physical stuff. this is definitely an idea too ambitious for me to achieve in the next eleven weeks (and maybe at all.) but, maybe if i tell myself this is the goal i'm working towards i can learn a lot from building a piece of this idea. and maybe if i talk about it enough it'll inspire others to contribute to making it something more powerful than the nebulous thing in my head and maybe not")
|
||||||
|
(p "also! i want to use this project as a kind of curriculum. i might not actually write any code that goes into any eventual project that exists. but, what would i need to deeply understand to achieve this? obviously there's some networking involved, clients talking to servers. servers talking to servers. ")
|
||||||
|
(p (strong "so! learning goals scoped to my time at rc:"))
|
||||||
|
(ul
|
||||||
|
(li "stream 1: network. to begin with i want to focus on networking from a lower level than i am used to. no frameworks, just building a server -- i have to think about protocol here, depending on how much i want to focus on the federation thing i might want to do rpc and not http. but either way, there are internals that i have soared over in my abstraction-glider")
|
||||||
|
(li "stream 2: database. i take for granted database connections. i take for granted that someone on my team will have a better knowledge of the query scheduler or more excitement about cte's. exactly what this looks like also depends on the architecture (does every client maintain it's own state? or do member/donor's collections live on a home server). whatever the case, i want to spend less time in abstractions and more in db internals")
|
||||||
|
(li "stream 3: extracurriculurs. i still want to give myself some unstructured time to finally work through the back chapters of sicp, compose goofy little orca pieces, talk about politics and human-computer interaction, and work through the propagation networks in clojure side project. my time here is finite, but having some side-projects helps me from falling into ruts"))
|
||||||
|
(p "altho this is still very fuzzy, narrowing the scope a tiny bit feels good. i've been riding high on excitement all week, and this weekend i definitely crashed hard into feelings of self doubt. i could absolutely engross myself in working through someone else's curriculum for this time, but that's not what any of this is about. i'll maybe post here mid week 2 as my own curriculum starts to cohere")
|
||||||
|
(p "i think that's all i've got for the first week. it's time to get working"))
|
||||||
|
(section
|
||||||
|
((id "week-2"))
|
||||||
|
(hgroup
|
||||||
|
(h2 "week 2")
|
||||||
|
(p (em "drinking-from-firehose intensifies")))
|
||||||
|
(p "ok, there's a lot going on here. i may need to start making some decisions about where to focus my time. i've got a pretty full schedule and have done at least a couple hours of head-down coding each day. the problem is stuff like... a creative coding thing. i wanted to spend a couple hours each week just making beep-boop noises in some esoteric live-coding environments. ("
|
||||||
|
(a ((href "https://100r.co/site/orca.html")) "orca") " and " (a ((href "https://overtone.github.io/")) "overtone")
|
||||||
|
"). there's a new prompt each week, i open up my tools (which themselves are somewhat newt o me--i've only done little things with them. but i'm on a relatively new system (new to linux and using mint on one machine and nixos on another) and i haven't entirely figured out how to patch midi messages from one process to another. so i'll go read about pipewire and now i'm building some programs to help me create pipewire patches and i'm racing through this process wondering if this is what i want to be doing right now. i don't want to just spend a couple hours building dependencies for the tools i intend to use to creatively code, i want to understand what i'm doing. but understanding alsa wasn't really the point of the prompt -- so i need to either slow down and dive deep or pivot to something else")
|
||||||
|
(p "i guess that's kinda how i wound up focusing more on this project than i intended this week: "
|
||||||
|
(a ((href "https://git.bunk.computer/oxaliq/prop-net")) "propagation networks in clojure")
|
||||||
|
". it's fun--it's challenging enough that i'm learning more about the language than i would just following a tutorial. i'm also convincing myself that this is part of the curriculum. i do an intro project to learn the language, this weekend and into next week i put it behind a server. next week i see if i can find someone interested in helping with a rough graph manipulation gui frontend. by next weekend, i package and deploy it--in whatever state it happens to be in.")
|
||||||
|
(p "and i think on week 4 i assess whether to continue building the concepts in the paper or shift my focus to uf-library")
|
||||||
|
(p "okay, so more thinkings from the week and more goals for the next. the other streams have been some thinking with people on human computer interaction (next week we're talking end user programming yay!) the beginnings of a group to talk about doing computer in ways that are more socially oriented, and some study groups--working through the wizard book, the missing cs semester course, and a 'tool time' group as well. both of these are building on some things that i'm already pretty comfortable with and it's nice to have a group to work through the back half of the wizard book + the shell,git,vim tricks i haven't figured out for myself yet and the debugging and profiling stuff i know too little about and the data wrangling techniques that make logs so powerful. excited for tool time too! gonna do some ide hacking maybe? so i've got some homework to that end for the weekend, plus i think i want to do a little spreadsheet side project that (if it works decently) i'd like to present on next week")
|
||||||
|
(p "o! and to do way more pairing. i haven't gotten up to daily pairing sessions yet, but that's definitely something i want to hold myself to next week! leaning on pairing-bot for sure, but also reaching out and being open to impromptu pairing sessions. (plus some pairing sessions with partners on projects outside of rc)")
|
||||||
|
(p "i think that's a wrap for this week's notes. feeling more secure, but also less settled"))
|
||||||
|
;; -- week-3
|
||||||
|
)
|
34
archive/now.scm
Normal file
34
archive/now.scm
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
(section
|
||||||
|
(hgroup
|
||||||
|
(h2 "now")
|
||||||
|
(p "a snapshot of the (mostly) non-computer things of import"))
|
||||||
|
(section
|
||||||
|
(hgroup
|
||||||
|
(h3 "read")
|
||||||
|
(p "stuff i'm taking in"))
|
||||||
|
(ul
|
||||||
|
(li "palo alto, malcolm harris")
|
||||||
|
(li "paul takes the form of a mortal girl, andrea lawlor")
|
||||||
|
(li "annihilation, jeff vandermeer")
|
||||||
|
(li "let the right one in, tomas alfredson")
|
||||||
|
(li "the limits of control, jim jarmusch")
|
||||||
|
(li "the matrices, wachowskis")))
|
||||||
|
(section
|
||||||
|
(hgroup
|
||||||
|
(h3 "eval")
|
||||||
|
(p "stuff i'm crunching on"))
|
||||||
|
(ul
|
||||||
|
(li "starting a community maker space")
|
||||||
|
(li "mostly just spending all my time moving")
|
||||||
|
(li "skating again")))
|
||||||
|
(section
|
||||||
|
(hgroup
|
||||||
|
(h3 "print")
|
||||||
|
(p "stuff i'm putting out"))
|
||||||
|
(ul (li "doing more sewing")
|
||||||
|
(li "baby's first letterpress")))
|
||||||
|
(section
|
||||||
|
(hgroup
|
||||||
|
(h3 "loop")
|
||||||
|
(p "stuff what's on the horizon"))
|
||||||
|
(ul (li "putting my labor on the market"))))
|
|
@ -1,39 +0,0 @@
|
||||||
(section
|
|
||||||
(hgroup
|
|
||||||
(h2 "now")
|
|
||||||
(p "a snapshot of the (mostly) non-computer things of import"))
|
|
||||||
(section
|
|
||||||
(hgroup
|
|
||||||
(h3 "read")
|
|
||||||
(p "stuff i'm taking in"))
|
|
||||||
(ul (li "the paying guests, sarah waters")
|
|
||||||
(li "females, andrea long chu")
|
|
||||||
(li "palo alto, malcolm harris")
|
|
||||||
(li "high pitched and moist, tami t")
|
|
||||||
(li "desolation's flower, ragana")
|
|
||||||
(li "salesforce, lauren bousfield")
|
|
||||||
(li "el mal querer, rosalía")
|
|
||||||
(li "guacamelee, drinkbox")))
|
|
||||||
(section
|
|
||||||
(hgroup
|
|
||||||
(h3 "eval")
|
|
||||||
(p "stuff i'm crunching on"))
|
|
||||||
(ul (li "playing more go")
|
|
||||||
(li "winter garden chores")
|
|
||||||
(li "starting a community maker space")
|
|
||||||
(li "going on more hikes")
|
|
||||||
(li "body stuff")))
|
|
||||||
(section
|
|
||||||
(hgroup
|
|
||||||
(h3 "print")
|
|
||||||
(p "stuff i'm putting out"))
|
|
||||||
(ul (li "fun leatherwork")
|
|
||||||
(li "fun woodwork")
|
|
||||||
(li "relearning how to draw")))
|
|
||||||
(section
|
|
||||||
(hgroup
|
|
||||||
(h3 "loop")
|
|
||||||
(p "stuff what's on the horizon"))
|
|
||||||
(ul (li "being in the northeastern us")
|
|
||||||
(li "putting my labor on the market")
|
|
||||||
(li "maybe making some music again?"))))
|
|
35
archive/pre-introducing-uf-library.scm
Normal file
35
archive/pre-introducing-uf-library.scm
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
(article
|
||||||
|
((id "pre-introducing-uf-library"))
|
||||||
|
(hgroup
|
||||||
|
(h1 "pre-introducing uf-library")
|
||||||
|
(p (em "what if you were a library?")))
|
||||||
|
(section
|
||||||
|
((id "quick-story"))
|
||||||
|
(h2 "part 1: a quick story")
|
||||||
|
(p "i volunteer at a tool library. it's a scrappy project that technically fits the non-profit designation, but has managed to cultivate a do-it-together ethos. there are numerous working groups devoted to tool maintenance, educational workshops, community outreach, developing an on-site print shop, and much more. and we do it all on a pretty slim budget with almost entirely unpaid labor")
|
||||||
|
(p "i also love physical media. i recently had to pack most of my posessions into storage for a short time and was struck by the high percentage of my belongings that are physical media. (yet, i always feel like i'm not looking hard enough for new stuff to read or listen to!) floating out amongst my friends are probably a dozen books -- some of which i've maybe forgotten the location of -- but i've been increasingly feeling that more of them should be circulating. what if i made my little media collection a library for my friends?"))
|
||||||
|
(section
|
||||||
|
((id "software"))
|
||||||
|
(h2 "part 2: software")
|
||||||
|
(p "there's some foss library software out there :"
|
||||||
|
(a ((href "https://koha-community.org/")) "koha ils") ", "
|
||||||
|
(a ((href "https://evergreen-ils.org/")) "evergreen ils") ", "
|
||||||
|
(a ((href "https://openbiblio.de/")) "openbiblio") " (and more.) the only tool or 'thing' oriented software i know of are the foss (unfinished) "
|
||||||
|
(a ((href "https://github.com/chicago-tool-library/circulate")) "circulate") " by the chicago tool library and the closed-source "
|
||||||
|
(a ((href "https://myturn.com/")) "myturn")
|
||||||
|
". i'm not interested in critiquing existing software here, except to say that none of the things i've seen support the kind of library i want to become")
|
||||||
|
(p "i want to be a library amongst libraries. i want my friends and communities to add their collections to the library network and to lend and borrow and restore and maintain more than they ever could as individuals lending and borrowing amongst friends. and i don't care about the distinction between traditional media-library *and* library-of-things/tool-library models. i want library as community platform. i want applied library sciences")
|
||||||
|
(p "wait that wasn't about software. that was about human networking. but the software to represent this kind of social technology doesn't yet exist. and i think it should. and i think it should be as lean and easy to deploy and administer as possible")
|
||||||
|
(p "i don't have the capacity to build this vision at this moment, but i think i can build some of it and build the capacity to build more.
|
||||||
|
i'm participating in "
|
||||||
|
(a ((href "https://recurse.com")) "recurse center hacking retreat") " and " (a ((href "/tagged/rc")) "i'm writing about my rc experience")
|
||||||
|
". that'll be more focused on the 'building my capacity' piece. a lot of that will be about thinking through stuff that doesn't wind up being ultimately implemented. i'll write more "
|
||||||
|
(a ((href "/tagged/uf-library")) "about building library") " separately. (of course there's going to be a lot of interleaving)")
|
||||||
|
(p "the thing to do before hacking next week is to look at the protocols available. (the working-name 'uf-library' is a contraction of 'usufruct', a social-good-oriented property model (can't be giving things latin names tho), but it could also be 'ur-favorite' or 'user-friendly' (what's friendlier than being engaged in community?))"))
|
||||||
|
(section
|
||||||
|
((id "dreaming"))
|
||||||
|
(h2 "part 3: dreaming")
|
||||||
|
(p "this is an experiment. and kind of a long-shot one at that. i hope that it inspires similar experiments, regardless of the success of this iteration. (there might even already be a project out there that hit on the same idea, however it appears to be abandoned (and a dao))")
|
||||||
|
(p "if this is interesting to you "
|
||||||
|
(a ((href "/contact")) "let's talk about it!")
|
||||||
|
" otherwise, wish me luck :)")))
|
|
@ -4,7 +4,7 @@
|
||||||
(p "some kind of colophon"))
|
(p "some kind of colophon"))
|
||||||
(p
|
(p
|
||||||
"all of the code for the website is hosted and deployed from tree, "
|
"all of the code for the website is hosted and deployed from tree, "
|
||||||
(a ((href "https://git.bunk.computer/oxaliq/sorrel.dev"))
|
(a ((href "https://git.bunk.computer/oxaliq/oxaliq.net"))
|
||||||
"bunk computer club's git forge")
|
"bunk computer club's git forge")
|
||||||
"i do almost everything in the main branch, cause it's just me and that way
|
"i do almost everything in the main branch, cause it's just me and that way
|
||||||
i can add links below to the in-progress stuff real easy")
|
i can add links below to the in-progress stuff real easy")
|
||||||
|
@ -28,15 +28,15 @@
|
||||||
"there's some racket scripts i use for tooling that were made with "
|
"there's some racket scripts i use for tooling that were made with "
|
||||||
(a ((href "https://docs.racket-lang.org/cli/"))
|
(a ((href "https://docs.racket-lang.org/cli/"))
|
||||||
"#lang cli"))
|
"#lang cli"))
|
||||||
(p (a ((href "https://git.bunk.computer/oxaliq/sorrel.dev/src/branch/main/.dev-log"))
|
(p (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/.dev-log"))
|
||||||
"you can read about development here"))
|
"you can read about development here"))
|
||||||
(p (a ((href "https://git.bunk.computer/oxaliq/sorrel.dev/src/branch/main/.idea-log"))
|
(p (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/in-progress/.idea-log"))
|
||||||
"you can read about my vague plans here"))
|
"you can read about my vague plans here"))
|
||||||
(p (a ((href "https://git.bunk.computer/oxaliq/sorrel.dev/src/branch/main/in-progress"))
|
(p (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/in-progress/in-progress"))
|
||||||
"or read works in progress here"))
|
"or read works in progress here"))
|
||||||
(p
|
(p
|
||||||
"the image in the header is a crop of the work "
|
"the image in the header is a crop of the work "
|
||||||
(em "'Oxalis acetosella', Otto Wilhelm Thomé (1885)")
|
(em "'Oxalis acetosella', Otto Wilhelm Thomé (1885)")
|
||||||
" run through a generation tool on "
|
" run through a generation tool on "
|
||||||
(a ((href "https://www.asciiart.eu/"))
|
(a ((href "https://www.asciiart.eu/"))
|
||||||
"this ascii art archive")))
|
"this art archive")))
|
13
build.sh
13
build.sh
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/sh -e
|
|
||||||
|
|
||||||
# clean up old build
|
|
||||||
rm -rf sorrel || true
|
|
||||||
|
|
||||||
# compile binary
|
|
||||||
raco cross --target x86_64-linux exe sorrel.dev.rkt
|
|
||||||
|
|
||||||
# distribute
|
|
||||||
raco cross --target x86_64-linux dist sorrel sorrel.dev
|
|
||||||
|
|
||||||
# remove duplicated binary
|
|
||||||
rm sorrel.dev
|
|
|
@ -1,8 +1,15 @@
|
||||||
title,link,summary,published,updated
|
title,link,summary,published,updated
|
||||||
now,https://sorrel.dev/now,what the author of this site is up to,2023-12-24T19:45:57
|
notes from rc,https://oxaliq.net/unsettled/notes-from-rc,dispatches from the edge of my abilities,2024-04-01T13:02:09,2024-04-05T13:48:39
|
||||||
contact,https://sorrel.dev/contact,how to talk to sorrel,2023-12-24T19:45:11
|
pre-introducing uf-library,https://oxaliq.net/unsettled/pre-introducing-uf-library,what if you were a library?,2024-04-01T13:04:37,
|
||||||
disclaimer,https://sorrel.dev/very-earnest-disclaimer,a very earnest disclaimer,2023-12-24T19:43:23
|
notes from rc,https://oxaliq.net/unsettled/notes-from-rc,dispatches from the edge of my abilities,2024-04-01T13:02:09,
|
||||||
this,https://sorrel.dev/this,the site this bitch made,2023-12-24T19:41:47
|
now,https://oxaliq.net/now,what the author of this site is up to (not computer things),2024-01-18T22:22:03,2024-03-23T16:29:58
|
||||||
about,https://sorrel.dev/about,the bitch who made this site,2023-12-24T19:15:34
|
about,https://oxaliq.net/about,about the bitch who made this site,2024-01-18T21:56:45,2024-03-23T16:29:13
|
||||||
about,https://sorrel.dev/about,the bitch who made this site,2023-12-24T19:11:35
|
latl-primitives_what-is-language,https://oxaliq.net/unsettled/latl-primitives_what-is-language,thinking about language from the perspective of latl,2024-02-25T21:36:03,
|
||||||
Beginning LATL,https://sorrel.dev/unsettled/1,beginning the process of thinking through an environment for conlanging and other language shenanigans,2023-12-04T15:20:53
|
latl-primitives,https://oxaliq.net/unsettled/latl-primitives,designing the primitives to be provided by latl,2024-02-25T21:33:06,
|
||||||
|
feature-change-applier,https://oxaliq.net/settled/1,a first attempt at a conlanging tool,2024-01-25T16:26:10,
|
||||||
|
beginning latl,https://oxaliq.net/unsettled/1,beginning the process of thinking through an environment for conlanging and other language shenanigans,2024-01-18T22:39:00,
|
||||||
|
now,https://oxaliq.net/now,what the author of this site is up to (not computer things),2024-01-18T22:22:03,
|
||||||
|
contact,https://oxaliq.net/contact,how to talk to me,2024-01-18T22:21:26,
|
||||||
|
very earnest disclaimer,https://oxaliq.net/very-earnest-disclaimer,being earnest in the streets,2024-01-18T22:20:50,
|
||||||
|
this,https://oxaliq.net/this,the site this bitch made,2024-01-18T22:19:43,
|
||||||
|
about,https://oxaliq.net/about,about the bitch who made this site,2024-01-18T21:56:45,
|
|
|
@ -2,7 +2,7 @@
|
||||||
(let ([feed
|
(let ([feed
|
||||||
`(feed
|
`(feed
|
||||||
((xmlns "http://www.w3.org/2005/Atom"))
|
((xmlns "http://www.w3.org/2005/Atom"))
|
||||||
(title "λ.sorrel.dev")
|
(title "λ.oxaliq.net")
|
||||||
(link ((rel "self")
|
(link ((rel "self")
|
||||||
(href ,feed-ref)))
|
(href ,feed-ref)))
|
||||||
(updated ,update-time)
|
(updated ,update-time)
|
|
@ -1,6 +1,6 @@
|
||||||
id,headline,description,history->
|
id,headline,description,history->
|
||||||
now,now,what the author of this site is up to,2023-12-24T19:45:57
|
now,now,what the author of this site is up to (not computer things),2024-03-23T16:29:58,2024-01-18T22:22:03
|
||||||
contact,contact,how to talk to sorrel,2023-12-24T19:45:11
|
contact,contact,how to talk to me,2024-01-18T22:21:26
|
||||||
very-earnest-disclaimer,disclaimer,a very earnest disclaimer,2023-12-24T19:43:23
|
very-earnest-disclaimer,very earnest disclaimer,being earnest in the streets,2024-01-18T22:20:50
|
||||||
this,this,the site this bitch made,2023-12-24T19:41:47
|
this,this,the site this bitch made,2024-01-18T22:19:43
|
||||||
about,about,the bitch who made this site,2023-12-24T19:15:34
|
about,about,about the bitch who made this site,2024-03-23T16:29:13,2024-01-18T21:56:45
|
|
|
@ -1 +1,2 @@
|
||||||
id,headline,description,history->
|
id,headline,description,history->
|
||||||
|
1,feature-change-applier,a first attempt at a conlanging tool,2024-01-25T16:26:10
|
|
|
@ -1,2 +1,11 @@
|
||||||
tags,->
|
tags,->
|
||||||
about,root/now,root/contact,root/very-earnest-disclaimer,root/this,root/about
|
about,root/now,root/contact,root/very-earnest-disclaimer,root/this,root/about
|
||||||
|
latl,unsettled/latl-primitives_what-is-language,unsettled/latl-primitives,unsettled/1
|
||||||
|
conlang,unsettled/latl-primitives,settled/1,unsettled/1
|
||||||
|
programming-language,unsettled/latl-primitives,unsettled/1
|
||||||
|
tool,settled/1
|
||||||
|
linguistics,unsettled/latl-primitives_what-is-language
|
||||||
|
rc,unsettled/pre-introducing-uf-library,unsettled/notes-from-rc
|
||||||
|
uf-library,unsettled/pre-introducing-uf-library,unsettled/notes-from-rc
|
||||||
|
diary,unsettled/notes-from-rc
|
||||||
|
library,unsettled/pre-introducing-uf-library
|
|
|
@ -1,2 +1,6 @@
|
||||||
id,headline,description,history->
|
id,headline,description,history->
|
||||||
1,Beginning LATL,beginning the process of thinking through an environment for conlanging and other language shenanigans,2023-12-04T15:20:53
|
pre-introducing-uf-library,pre-introducing uf-library,what if you were a library?,2024-04-01T13:04:37
|
||||||
|
notes-from-rc,notes from rc,dispatches from the edge of my abilities,2024-04-05T13:48:39,2024-04-01T13:02:09
|
||||||
|
latl-primitives_what-is-language,latl-primitives_what-is-language,thinking about language from the perspective of latl,2024-02-25T21:36:03
|
||||||
|
latl-primitives,latl-primitives,designing the primitives to be provided by latl,2024-02-25T21:33:06
|
||||||
|
1,beginning latl,beginning the process of thinking through an environment for conlanging and other language shenanigans,2024-01-18T22:39:00
|
|
17
deploy.sh
17
deploy.sh
|
@ -1,17 +0,0 @@
|
||||||
#!/bin/sh -e
|
|
||||||
|
|
||||||
# make a clean slate locally
|
|
||||||
rm -rf ./deploy-dir || true
|
|
||||||
mkdir ./deploy-dir
|
|
||||||
|
|
||||||
# copy all the files into a deploy local directory
|
|
||||||
cp -a ./sorrel/. ./deploy-dir/.
|
|
||||||
cp -a ./static ./deploy-dir/.
|
|
||||||
cp -a ./source ./deploy-dir/.
|
|
||||||
cp -a ./data ./deploy-dir/.
|
|
||||||
|
|
||||||
# make a clean slate remotely
|
|
||||||
ssh deploy@turtle.hup.is 'rm -rf ./sorrel.dev'
|
|
||||||
|
|
||||||
# copy all the files onto remote
|
|
||||||
rsync -avz ./deploy-dir/. deploy@turtle.hup.is:~/sorrel.dev
|
|
0
in-progress/documentation-driven-development.scm
Normal file
0
in-progress/documentation-driven-development.scm
Normal file
0
in-progress/latl-primitives.scm
Normal file
0
in-progress/latl-primitives.scm
Normal file
12
in-progress/latl-primitives_proposed-latl-primitives.scm
Normal file
12
in-progress/latl-primitives_proposed-latl-primitives.scm
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
(section
|
||||||
|
((id "proposed-latl-primitives"))
|
||||||
|
(hgroup
|
||||||
|
(h2 "")
|
||||||
|
(p (em "")))
|
||||||
|
(p "")
|
||||||
|
(section
|
||||||
|
((id ""))
|
||||||
|
(hgroup
|
||||||
|
(h3 "")
|
||||||
|
(p (em "")))
|
||||||
|
(p "")))
|
11
in-progress/latl-primitives_what-conlangers-do.scm
Normal file
11
in-progress/latl-primitives_what-conlangers-do.scm
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
(section
|
||||||
|
((id "what-conlangers-do"))
|
||||||
|
(hgroup
|
||||||
|
(h2 "what conlangers do")
|
||||||
|
(p (em "moving from a pile of language stuff to a pile of problems to solve")))
|
||||||
|
(p "")
|
||||||
|
(section
|
||||||
|
(hgroup
|
||||||
|
(h3 "what's in a sound change rule?")
|
||||||
|
(p (em "using previous work as a starting point")))
|
||||||
|
""))
|
0
in-progress/syntax-considered-harmful.scm
Normal file
0
in-progress/syntax-considered-harmful.scm
Normal file
397
modify.rkt
Normal file
397
modify.rkt
Normal file
|
@ -0,0 +1,397 @@
|
||||||
|
#lang cli
|
||||||
|
|
||||||
|
(require (only-in racket/date current-date date->string date-display-format)
|
||||||
|
(only-in racket/string string-join string-split non-empty-string?)
|
||||||
|
(only-in racket/list first second third fourth fifth last take drop flatten add-between)
|
||||||
|
(only-in racket/format ~a)
|
||||||
|
(only-in racket/exn exn->string)
|
||||||
|
(only-in racket/function thunk identity)
|
||||||
|
(only-in csv-reading csv->list)
|
||||||
|
(only-in xml read-xml)
|
||||||
|
(only-in "./utils.rkt" list->csv resource-link atom-table-entry add-atom-entry
|
||||||
|
make-feed archive-file git-forge source-url))
|
||||||
|
|
||||||
|
(define-namespace-anchor anc)
|
||||||
|
(define ns (namespace-anchor->namespace anc))
|
||||||
|
|
||||||
|
|
||||||
|
;; modify needs to
|
||||||
|
|
||||||
|
;: - take an input file (from archive/), build a source file in the appropriate place in source/
|
||||||
|
|
||||||
|
;; - update the line for the resource in the read-table for resource type, adding the modified date
|
||||||
|
;; this will not! (for now) update the <resource>/index or tagged/<tag>/index pages !
|
||||||
|
;; (these pages do not currently show post history)
|
||||||
|
|
||||||
|
;; - update the atom table and rebuild the atom feed
|
||||||
|
|
||||||
|
;; example
|
||||||
|
;; modify -input-file in-progress/beginning-latl.scm --resource-type unsettled
|
||||||
|
;; --headline "Beginning LATL"
|
||||||
|
;; publish -i in-progress/beginning-latl.scm -r unsettled -l "Beginning LATL"
|
||||||
|
|
||||||
|
(help (usage "modify is here to update existing posts with new content."))
|
||||||
|
|
||||||
|
|
||||||
|
(flag (resource-type #:param [resource-type ""] t)
|
||||||
|
("-r" "--resource-type" "Type of resource [settled|unsettled|root]")
|
||||||
|
(resource-type (cond
|
||||||
|
[(equal? t "settled") "settled"]
|
||||||
|
[(equal? t "unsettled") "unsettled"]
|
||||||
|
[(equal? t "root") "root"]
|
||||||
|
[else (error 'failure "couldn't recognize resource. please use one of 'settled' 'unsettled' 'root'")])))
|
||||||
|
|
||||||
|
(flag (input #:param [input ""] i)
|
||||||
|
("-i" "--input-file" "file to publish")
|
||||||
|
(input (if (file-exists? i)
|
||||||
|
i
|
||||||
|
(error 'failure "couldn't locate file ~a" i))))
|
||||||
|
|
||||||
|
(flag (headline #:param [headline ""] h)
|
||||||
|
("-l" "--headline" "the shortest representation of a post")
|
||||||
|
(headline (if (non-empty-string? h)
|
||||||
|
h
|
||||||
|
(error 'failure "your post needs a headline"))))
|
||||||
|
|
||||||
|
(flag (test-mode)
|
||||||
|
("-x" "--test-mode" "updates only in test directory")
|
||||||
|
(test-mode #t))
|
||||||
|
|
||||||
|
(program
|
||||||
|
(modify)
|
||||||
|
(let ([n-in (input)]
|
||||||
|
[r-type (resource-type)]
|
||||||
|
[l-head (headline)]
|
||||||
|
[x-test (test-mode)]
|
||||||
|
[update-time (date->string (current-date) (date-display-format 'iso-8601))]
|
||||||
|
[rollback-thunks (list)])
|
||||||
|
(displayln "running modify")
|
||||||
|
|
||||||
|
|
||||||
|
;; getting existing file ports
|
||||||
|
;; ---------------------------
|
||||||
|
;; if any of these fail to match, exit modify
|
||||||
|
;; must use #:exists 'update
|
||||||
|
;; this throws an exception if the file does not exist, but it must be manually
|
||||||
|
;; truncated. using #:exists 'must-truncate guarantees file exists, but truncates
|
||||||
|
;; prior to data being read from file
|
||||||
|
|
||||||
|
;; locate existing post in source
|
||||||
|
;; (. -> . input-port? output-port?)
|
||||||
|
(define (get-source-ports)
|
||||||
|
(let*
|
||||||
|
([file-id (last (string-split n-in "/"))]
|
||||||
|
[file-handle (if (equal? r-type "root")
|
||||||
|
(if x-test
|
||||||
|
(build-path "publish-test" "source" file-id)
|
||||||
|
(build-path "source" file-id))
|
||||||
|
(if x-test
|
||||||
|
(build-path "publish-test" "source" r-type file-id)
|
||||||
|
(build-path "source" r-type file-id)))])
|
||||||
|
(values
|
||||||
|
(open-input-file file-handle)
|
||||||
|
(open-output-file file-handle #:exists 'update))))
|
||||||
|
|
||||||
|
;; locate data/resource table
|
||||||
|
;; (. -> . input-port? output-port?)
|
||||||
|
(define (get-res-table-ports)
|
||||||
|
(let ([file-handle (path-add-extension
|
||||||
|
(if x-test
|
||||||
|
(build-path "publish-test" "data" r-type)
|
||||||
|
(build-path "data" r-type))
|
||||||
|
#".csv")])
|
||||||
|
(values
|
||||||
|
(open-input-file file-handle)
|
||||||
|
(open-output-file file-handle #:exists 'update))))
|
||||||
|
|
||||||
|
;; locate data/atom table
|
||||||
|
;; (. -> . input-port? output-port?)
|
||||||
|
(define (get-atom-table-ports)
|
||||||
|
(let ([file-handle (path-add-extension
|
||||||
|
(if x-test
|
||||||
|
(build-path "publish-test" "data" "atom")
|
||||||
|
(build-path "data" "atom"))
|
||||||
|
#".csv")])
|
||||||
|
(values
|
||||||
|
(open-input-file file-handle)
|
||||||
|
(open-output-file file-handle #:exists 'update))))
|
||||||
|
|
||||||
|
;; locate source/feed.atom feed
|
||||||
|
;; (. -> . input-port? output-port?)
|
||||||
|
(define (get-atom-feed-ports)
|
||||||
|
(let ([file-handle (path-add-extension
|
||||||
|
(if x-test
|
||||||
|
(build-path "publish-test" "source" "feed")
|
||||||
|
(build-path "source" "feed"))
|
||||||
|
#".atom")])
|
||||||
|
(values
|
||||||
|
(open-input-file file-handle)
|
||||||
|
(open-output-file file-handle #:exists 'update))))
|
||||||
|
|
||||||
|
;; get make-atom.scm input-port
|
||||||
|
;; (. -> . input-port?)
|
||||||
|
(define (get-make-atom-input-port)
|
||||||
|
(let ([file-handle (path-add-extension
|
||||||
|
(if x-test
|
||||||
|
(build-path "publish-test" "data" "make-atom")
|
||||||
|
(build-path "data" "make-atom"))
|
||||||
|
#".scm")])
|
||||||
|
(open-input-file file-handle)))
|
||||||
|
|
||||||
|
|
||||||
|
(define (handle-error-getting-file expn)
|
||||||
|
(displayln "handle-error-getting-file")
|
||||||
|
(displayln expn)
|
||||||
|
(raise expn))
|
||||||
|
;; ---------------------------
|
||||||
|
|
||||||
|
;; other let-bindings expressions
|
||||||
|
;; ------------------------------
|
||||||
|
(define (get-res-table-and-id res-table-input-port)
|
||||||
|
(let ([res-table (csv->list res-table-input-port)])
|
||||||
|
(values
|
||||||
|
res-table
|
||||||
|
(first
|
||||||
|
;; need to handle errors
|
||||||
|
(findf
|
||||||
|
(lambda (row)
|
||||||
|
(equal? (second row)
|
||||||
|
l-head))
|
||||||
|
res-table)))))
|
||||||
|
|
||||||
|
|
||||||
|
(define (get-tags type id)
|
||||||
|
(let* ([tag-file-handle (path-add-extension
|
||||||
|
(if x-test
|
||||||
|
(build-path "publish-test" "data" "tagged")
|
||||||
|
(build-path "data" "tagged"))
|
||||||
|
#".csv")]
|
||||||
|
[tag-table (csv->list (open-input-file tag-file-handle))]
|
||||||
|
;; id in tagged.csv is <res>/<id>
|
||||||
|
[match-id (string-append type "/" id)])
|
||||||
|
(map
|
||||||
|
first
|
||||||
|
(filter
|
||||||
|
(lambda (tag-row)
|
||||||
|
(member match-id tag-row))
|
||||||
|
tag-table))))
|
||||||
|
|
||||||
|
;; ------------------------------
|
||||||
|
|
||||||
|
;; rollback execution
|
||||||
|
;; ------------------
|
||||||
|
;; all handlers of any exception raised after writes start occurring must evaluate
|
||||||
|
;; all rollback thunks registered up to the point of exception to ensure the
|
||||||
|
;; file system returns to its pre-script execution state. this is written to handle
|
||||||
|
;; any exceptions raised in rollback thunks and retry indefinitely. if there is an
|
||||||
|
;; unresolvable issue, the script will need to be manually exited and the resulting
|
||||||
|
;; mess cleaned up.
|
||||||
|
(define (rollback-exec rb-thunks)
|
||||||
|
(for-each
|
||||||
|
(lambda (th)
|
||||||
|
(call-with-exception-handler
|
||||||
|
(lambda (expn)
|
||||||
|
(displayln (~a "encountered error" (exn->string expn)))
|
||||||
|
(displayln (~a "running " th " again"))
|
||||||
|
(th)))
|
||||||
|
th)
|
||||||
|
rb-thunks))
|
||||||
|
;; ------------------
|
||||||
|
|
||||||
|
;; file-writing
|
||||||
|
;; ------------
|
||||||
|
;; generic file writing and exceptions
|
||||||
|
(struct file-write-exception exn:fail:filesystem (rb-thunks))
|
||||||
|
|
||||||
|
;; handler must unwrap file-write-exception, evaluate all rb-thunks, and raise
|
||||||
|
;; exception value
|
||||||
|
(define (handle-file-write-exception expn)
|
||||||
|
(let ([rb-thunks (file-write-exception-rb-thunks expn)])
|
||||||
|
(rollback-exec rb-thunks)
|
||||||
|
(raise (exn:fail (exn-message expn) (current-continuation-marks)))))
|
||||||
|
|
||||||
|
;; write-to-file must manually truncate since out-ports do not truncate
|
||||||
|
;; (output-port? xexpr? xexpr? rb-thunks? . -> . rb-thunks?)
|
||||||
|
(define (write-to-file out-port new-content old-content accumulator #:print-mode? (is-print #f))
|
||||||
|
(let ([rb-thunks (cons (thunk (write-to-file-with-retries out-port old-content is-print))
|
||||||
|
(hash-ref accumulator 'rb-thunks))])
|
||||||
|
(if (port-try-file-lock? out-port 'exclusive)
|
||||||
|
;; wrap in handler that raises file-write-exception
|
||||||
|
(begin
|
||||||
|
(call-with-exception-handler
|
||||||
|
(lambda (expn)
|
||||||
|
(raise (file-write-exception (exn-message expn)
|
||||||
|
(current-continuation-marks)
|
||||||
|
rb-thunks)))
|
||||||
|
(thunk
|
||||||
|
(file-truncate out-port 0)
|
||||||
|
((if is-print print display) new-content out-port)
|
||||||
|
(port-file-unlock out-port)
|
||||||
|
(close-output-port out-port)))
|
||||||
|
(hash-update accumulator 'rb-thunks
|
||||||
|
(lambda (r) rb-thunks)))
|
||||||
|
(raise (file-write-exception
|
||||||
|
(~a "couldn't obtain file lock on " out-port)
|
||||||
|
(current-continuation-marks)
|
||||||
|
rb-thunks)))))
|
||||||
|
|
||||||
|
(define (write-to-file-with-retries out-port content is-print)
|
||||||
|
(with-handlers
|
||||||
|
([file-write-exception? (lambda (expn)
|
||||||
|
(displayln "filewrite failed with" expn)
|
||||||
|
(displayln "retrying")
|
||||||
|
(write-to-file-with-retries out-port content is-print))])
|
||||||
|
(write-to-file out-port content #:print-mode? is-print)))
|
||||||
|
;; ------------
|
||||||
|
|
||||||
|
;; resource-replacement
|
||||||
|
;; --------------------
|
||||||
|
;; replace resource in source/<type>/id
|
||||||
|
(define (append-post-footer post-xexpr source-url tag-list history-list)
|
||||||
|
(let ([post-footer
|
||||||
|
(read (open-input-file "source/post-footer.scm"))])
|
||||||
|
`(body
|
||||||
|
,post-xexpr
|
||||||
|
,((eval post-footer ns) source-url tag-list history-list))))
|
||||||
|
|
||||||
|
|
||||||
|
;; returns lambda that takes res-table to be passed into replace-resource
|
||||||
|
;; as make-new-content
|
||||||
|
(define (get-new-content source-input-port tag-list id)
|
||||||
|
(let ([new-content-sans-footer (read (open-input-file n-in))])
|
||||||
|
(lambda (res-table)
|
||||||
|
(let ([history-list (drop
|
||||||
|
(findf (lambda (row) (equal? (first row) id))
|
||||||
|
res-table)
|
||||||
|
3)])
|
||||||
|
(append-post-footer new-content-sans-footer (source-url r-type id) tag-list history-list)))))
|
||||||
|
|
||||||
|
|
||||||
|
;; replace-resource compose chain expression
|
||||||
|
(define (replace-resource source-input-port source-output-port make-new-content id)
|
||||||
|
(let ([old-content (read source-input-port)])
|
||||||
|
(lambda (accumulator)
|
||||||
|
(let ([res-table (hash-ref accumulator 'res-table)])
|
||||||
|
(hash-update
|
||||||
|
(hash-remove
|
||||||
|
(write-to-file
|
||||||
|
source-output-port
|
||||||
|
(make-new-content res-table)
|
||||||
|
old-content accumulator #:print-mode? #t)
|
||||||
|
'res-table)
|
||||||
|
'resource
|
||||||
|
identity
|
||||||
|
(findf (lambda (row) (equal? (first row) id)) res-table))))))
|
||||||
|
;; --------------------
|
||||||
|
|
||||||
|
|
||||||
|
;; res-table update
|
||||||
|
;; ----------------
|
||||||
|
(define (update-res-table-with-modification old-res-table id)
|
||||||
|
(map
|
||||||
|
(lambda (row)
|
||||||
|
(if (equal? (first row) id)
|
||||||
|
(flatten (list (take row 3)
|
||||||
|
update-time
|
||||||
|
(drop row 3)))
|
||||||
|
row))
|
||||||
|
old-res-table))
|
||||||
|
|
||||||
|
(define (get-publish-time res-table id)
|
||||||
|
(last (findf (lambda (row) (equal? (first row) id))
|
||||||
|
res-table)))
|
||||||
|
|
||||||
|
;; update-res-table compose chain expression
|
||||||
|
(define (update-res-table old-table rt-output-port id)
|
||||||
|
(let* ([new-table (update-res-table-with-modification old-table id)]
|
||||||
|
[new-content (list->csv new-table)]
|
||||||
|
[publish-time (get-publish-time old-table id)])
|
||||||
|
(lambda (accumulator)
|
||||||
|
(hash-update
|
||||||
|
(hash-update
|
||||||
|
(write-to-file rt-output-port new-content old-table accumulator)
|
||||||
|
'res-table
|
||||||
|
identity
|
||||||
|
new-table)
|
||||||
|
'publish-time
|
||||||
|
identity
|
||||||
|
publish-time))))
|
||||||
|
;; ----------------
|
||||||
|
|
||||||
|
;; atom-table update
|
||||||
|
;; -----------------
|
||||||
|
(define (update-atom-table at-input-port at-output-port res-link)
|
||||||
|
(let ([old-table (csv->list at-input-port)])
|
||||||
|
(lambda (accumulator)
|
||||||
|
(let* ([res-row (hash-ref accumulator 'resource)]
|
||||||
|
[desc (third res-row)]
|
||||||
|
[publish-time (hash-ref accumulator 'publish-time)]
|
||||||
|
[new-table (add-atom-entry old-table
|
||||||
|
(atom-table-entry l-head res-link desc publish-time #:update-time update-time))])
|
||||||
|
(hash-remove
|
||||||
|
(hash-remove
|
||||||
|
(hash-update
|
||||||
|
(write-to-file at-output-port (list->csv new-table) old-table accumulator)
|
||||||
|
'atom-table
|
||||||
|
identity
|
||||||
|
new-table)
|
||||||
|
'resource)
|
||||||
|
'publish-time)))))
|
||||||
|
;; -----------------
|
||||||
|
|
||||||
|
;; atom feed update
|
||||||
|
;; ----------------
|
||||||
|
(define (update-atom-feed af-input-port af-output-port make-af-input-port)
|
||||||
|
(let* ([old-feed (read-xml af-input-port)])
|
||||||
|
(lambda (accumulator)
|
||||||
|
(let* ([atom-table (hash-ref accumulator 'atom-table)]
|
||||||
|
[new-feed (make-feed ns make-af-input-port atom-table update-time)])
|
||||||
|
(write-to-file af-output-port new-feed old-feed accumulator)))))
|
||||||
|
|
||||||
|
;; ----------------
|
||||||
|
|
||||||
|
;; accumulator piped through compose chain
|
||||||
|
;; needed for passing data as well as for accumulating rollback thunks
|
||||||
|
(define (compose-accumulator rb-thunks)
|
||||||
|
(hash 'rb-thunks rb-thunks))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;; run modify with exception handlers
|
||||||
|
;; ----------------------------------
|
||||||
|
;; handlers evaluate rollback thunks in order before raising exception
|
||||||
|
;; to terminate script
|
||||||
|
(with-handlers
|
||||||
|
;; failure to locate one of the necessary existing files
|
||||||
|
([exn:fail:filesystem? handle-error-getting-file]
|
||||||
|
;; failure to write updates to existing file
|
||||||
|
[file-write-exception? handle-file-write-exception])
|
||||||
|
(let*-values
|
||||||
|
;; none of the expressions in let-bindings mutate the filesystem
|
||||||
|
([(source-input-port source-output-port) (get-source-ports)]
|
||||||
|
[(res-table-input-port res-table-output-port) (get-res-table-ports)]
|
||||||
|
[(atom-table-input-port atom-table-output-port) (get-atom-table-ports)]
|
||||||
|
[(atom-feed-input-port atom-feed-output-port) (get-atom-feed-ports)]
|
||||||
|
[(make-atom-input-port) (get-make-atom-input-port)]
|
||||||
|
[(old-res-table id) (get-res-table-and-id res-table-input-port)]
|
||||||
|
[(res-link) (resource-link r-type id)]
|
||||||
|
[(tags) (get-tags r-type id)]
|
||||||
|
[(new-content) (get-new-content source-input-port tags id)])
|
||||||
|
|
||||||
|
|
||||||
|
;; compose chain pipes (hash? accumulator) through each expression
|
||||||
|
;; at minimum accumulator must contain k-v ('rb-thunks . (list proc? . rest)
|
||||||
|
((compose
|
||||||
|
(update-atom-feed atom-feed-input-port atom-feed-output-port make-atom-input-port)
|
||||||
|
(update-atom-table atom-table-input-port atom-table-output-port res-link)
|
||||||
|
;; see above
|
||||||
|
(replace-resource source-input-port source-output-port new-content id)
|
||||||
|
(update-res-table old-res-table res-table-output-port id))
|
||||||
|
(compose-accumulator rollback-thunks))
|
||||||
|
|
||||||
|
;; only archive after everything else is done
|
||||||
|
(archive-file n-in x-test #:modify-mode #t)
|
||||||
|
|
||||||
|
(displayln "modify was successful")))))
|
||||||
|
|
||||||
|
(run modify)
|
256
oxaliq.net.rkt
Normal file
256
oxaliq.net.rkt
Normal file
|
@ -0,0 +1,256 @@
|
||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require racket/date
|
||||||
|
(only-in racket/list first second third rest)
|
||||||
|
(only-in racket/string string-prefix? string-replace)
|
||||||
|
net/url
|
||||||
|
xml
|
||||||
|
web-server/web-server
|
||||||
|
web-server/servlet-dispatch
|
||||||
|
web-server/dispatchers/dispatch
|
||||||
|
web-server/dispatch
|
||||||
|
(prefix-in files: web-server/dispatchers/dispatch-files)
|
||||||
|
(prefix-in filter: web-server/dispatchers/dispatch-filter)
|
||||||
|
(prefix-in sequencer: web-server/dispatchers/dispatch-sequencer)
|
||||||
|
racket/runtime-path
|
||||||
|
web-server/dispatchers/filesystem-map
|
||||||
|
web-server/http
|
||||||
|
csv-reading)
|
||||||
|
|
||||||
|
;; namespace needed for evaluating read files
|
||||||
|
(define-namespace-anchor anc)
|
||||||
|
(define ns (namespace-anchor->namespace anc))
|
||||||
|
|
||||||
|
;; it's all html!
|
||||||
|
(define (html-response content)
|
||||||
|
(response/full
|
||||||
|
200
|
||||||
|
#"OK"
|
||||||
|
(current-seconds)
|
||||||
|
TEXT/HTML-MIME-TYPE
|
||||||
|
'()
|
||||||
|
(list content)))
|
||||||
|
|
||||||
|
;; bound path builders
|
||||||
|
;; extension is always #".scm" because source files are not racket,
|
||||||
|
;; but must be read and evaluated in this namespace
|
||||||
|
(define (make-path-no-param root-folder extension)
|
||||||
|
(lambda (t)
|
||||||
|
(path-add-extension
|
||||||
|
(if (and (non-empty-string? t) (not (eq? t "root")))
|
||||||
|
(build-path root-folder t "index")
|
||||||
|
(build-path root-folder "index"))
|
||||||
|
extension)))
|
||||||
|
|
||||||
|
(define (make-path-id-param root-folder extension)
|
||||||
|
(lambda (t id)
|
||||||
|
(path-add-extension
|
||||||
|
(build-path root-folder
|
||||||
|
(if (eq? t "root")
|
||||||
|
(if (eq? id "")
|
||||||
|
;; if "root/" something weird has happened
|
||||||
|
"index"
|
||||||
|
;; allows for loading "/about" and other root resources
|
||||||
|
(~a id))
|
||||||
|
(if
|
||||||
|
;; if url has trailing backslash, id will be an empty string
|
||||||
|
;; and should return index for that type
|
||||||
|
(or (not (string? id))
|
||||||
|
(non-empty-string? id))
|
||||||
|
(build-path t (~a id))
|
||||||
|
(build-path t "index"))))
|
||||||
|
extension)))
|
||||||
|
|
||||||
|
(define (make-source-path-no-param t)
|
||||||
|
((make-path-no-param "source" #".scm") t))
|
||||||
|
|
||||||
|
(define (make-source-path-id-param t id)
|
||||||
|
((make-path-id-param "source" #".scm") t id))
|
||||||
|
|
||||||
|
(define (make-static-path-no-param api-type t)
|
||||||
|
(let ([root-folder
|
||||||
|
(cond
|
||||||
|
[(eq? api-type 'httpx) "static/fragment"]
|
||||||
|
[(eq? api-type 'page) "static/page"]
|
||||||
|
[else (error "api-type ~a not recognized" api-type)])])
|
||||||
|
((make-path-no-param root-folder #".html") t)))
|
||||||
|
|
||||||
|
(define (make-static-path-id-param api-type t id)
|
||||||
|
(let ([root-folder
|
||||||
|
(cond
|
||||||
|
[(eq? api-type 'httpx) "static/fragment"]
|
||||||
|
[(eq? api-type 'page) "static/page"]
|
||||||
|
[else (error "api-type ~a not recognized" api-type)])])
|
||||||
|
((make-path-id-param root-folder #".html") t id)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(define (static-file-res static-path)
|
||||||
|
(string->bytes/utf-8 (file->string static-path)))
|
||||||
|
|
||||||
|
;; wrapper for resource-processor
|
||||||
|
(define (wrapper-for-resource-processor static-path res-processor)
|
||||||
|
(if (not (file-exists? static-path))
|
||||||
|
(html-response (static-file-res static-path))
|
||||||
|
(res-processor)))
|
||||||
|
|
||||||
|
;; write static-file
|
||||||
|
;; return data that was written
|
||||||
|
(define (write-static-file static-path)
|
||||||
|
(lambda (data)
|
||||||
|
(let ([out-port (open-output-file static-path #:exists 'error)])
|
||||||
|
(if (port-try-file-lock? out-port 'exclusive)
|
||||||
|
(begin
|
||||||
|
(display data out-port)
|
||||||
|
(port-file-unlock out-port)
|
||||||
|
(close-output-port out-port)
|
||||||
|
data)
|
||||||
|
(error "couldn't obtain file lock on ~a" out-port)))))
|
||||||
|
|
||||||
|
|
||||||
|
(define (404-handler api-type)
|
||||||
|
(cond
|
||||||
|
[(eq? api-type 'httpx) (404-hx)]
|
||||||
|
[(eq? api-type 'page) (404-page)]
|
||||||
|
[else (error "api-type ~a not recognized" api-type)]))
|
||||||
|
|
||||||
|
|
||||||
|
;; takes a resource-type (corresponds to the REST resource and the system path or
|
||||||
|
;; an index resource in the source path)
|
||||||
|
;; and a resource-processor (-> file-handle . http-response)
|
||||||
|
;; and returns a valid html-response irrespective of hx/ type fragment of html or full page
|
||||||
|
(define respond-resource-with-processor
|
||||||
|
(lambda (api-type res-type resource-processor)
|
||||||
|
;; this lambda will be called by dispatch-rules
|
||||||
|
;; (req) is the request object
|
||||||
|
(case-lambda
|
||||||
|
[(req)
|
||||||
|
(let ([static-path (make-static-path-no-param api-type res-type)])
|
||||||
|
(if (file-exists? static-path)
|
||||||
|
(html-response (static-file-res static-path))
|
||||||
|
(let ([res-path (make-source-path-no-param res-type)])
|
||||||
|
(if (file-exists? res-path)
|
||||||
|
(html-response
|
||||||
|
(resource-processor res-path (write-static-file static-path)))
|
||||||
|
(404-handler api-type)))))]
|
||||||
|
;; (req id) is (request object . url parameter)
|
||||||
|
[(req id)
|
||||||
|
(let ([static-path (make-static-path-id-param api-type res-type id)])
|
||||||
|
(if (file-exists? static-path)
|
||||||
|
(html-response (static-file-res static-path))
|
||||||
|
(let ([res-path (make-source-path-id-param res-type id)])
|
||||||
|
(if (file-exists? res-path)
|
||||||
|
(html-response (resource-processor res-path (write-static-file static-path)))
|
||||||
|
(404-handler api-type)))))])))
|
||||||
|
;;; httpx
|
||||||
|
;; sends only the requested resource
|
||||||
|
(define (xexpr-file->res file static-write)
|
||||||
|
(string->bytes/utf-8
|
||||||
|
(static-write (xexpr-file->xml file))))
|
||||||
|
|
||||||
|
(define (xexpr-file->xml file)
|
||||||
|
(xexpr->string (read (open-input-file file))))
|
||||||
|
|
||||||
|
(define (404-hx)
|
||||||
|
(let ([static-path "static/fragment/not-found.html"])
|
||||||
|
(html-response
|
||||||
|
(if (file-exists? static-path)
|
||||||
|
(static-file-res static-path)
|
||||||
|
(xexpr-file->res "source/not-found.scm" (write-static-file static-path))))))
|
||||||
|
|
||||||
|
|
||||||
|
(define-values (httpx-app reverse-httpx-uri)
|
||||||
|
(dispatch-rules
|
||||||
|
[("hx" "home") (respond-resource-with-processor 'httpx "root" xexpr-file->res)]
|
||||||
|
[("hx" "settled") (respond-resource-with-processor 'httpx "settled" xexpr-file->res)]
|
||||||
|
[("hx" "settled" (string-arg)) (respond-resource-with-processor 'httpx "settled" xexpr-file->res)]
|
||||||
|
[("hx" "unsettled") (respond-resource-with-processor 'httpx "unsettled" xexpr-file->res)]
|
||||||
|
[("hx" "unsettled" (string-arg)) (respond-resource-with-processor 'httpx "unsettled" xexpr-file->res)]
|
||||||
|
[("hx" "tagged") (respond-resource-with-processor 'httpx "tagged" xexpr-file->res)]
|
||||||
|
[("hx" "tagged" (string-arg)) (respond-resource-with-processor 'httpx "tagged" xexpr-file->res)]
|
||||||
|
[("hx" (string-arg)) (respond-resource-with-processor 'httpx "root" xexpr-file->res)]
|
||||||
|
[else (lambda (req) (404-hx))]))
|
||||||
|
|
||||||
|
;;; page-app
|
||||||
|
;; constructs entire page for each response
|
||||||
|
(define (make-page resource static-write)
|
||||||
|
(string->bytes/utf-8
|
||||||
|
(static-write
|
||||||
|
(string-append
|
||||||
|
"<!DOCTYPE html>\n"
|
||||||
|
(fragment->page resource)))))
|
||||||
|
|
||||||
|
(define (fragment->page resource)
|
||||||
|
(xexpr->string
|
||||||
|
`(html ((lang "en"))
|
||||||
|
,(read (open-input-file "source/head.scm"))
|
||||||
|
(body
|
||||||
|
,(read (open-input-file "source/header.scm"))
|
||||||
|
(main ,(read (open-input-file resource)))))))
|
||||||
|
|
||||||
|
(define (404-page)
|
||||||
|
(let ([static-path "static/page/not-found.html"])
|
||||||
|
(html-response
|
||||||
|
(if (file-exists? static-path)
|
||||||
|
(static-file-res static-path)
|
||||||
|
(make-page "source/not-found.scm" (write-static-file static-path))))))
|
||||||
|
|
||||||
|
(define-values (page-app reverse-page-uri)
|
||||||
|
(dispatch-rules
|
||||||
|
[("") (respond-resource-with-processor 'page "" make-page)]
|
||||||
|
[("home") (respond-resource-with-processor 'page "" make-page)]
|
||||||
|
[("settled") (respond-resource-with-processor 'page "settled" make-page)]
|
||||||
|
[("settled" (string-arg)) (respond-resource-with-processor 'page "settled" make-page)]
|
||||||
|
[("unsettled") (respond-resource-with-processor 'page "unsettled" make-page)]
|
||||||
|
[("unsettled" (string-arg)) (respond-resource-with-processor 'page "unsettled" make-page)]
|
||||||
|
[("tagged") (respond-resource-with-processor 'page "tagged" make-page)]
|
||||||
|
[("tagged" (string-arg)) (respond-resource-with-processor 'page "tagged" make-page)]
|
||||||
|
[((string-arg)) (respond-resource-with-processor 'page "root" make-page)]
|
||||||
|
[else (lambda (req) (404-page))]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;;; from /static
|
||||||
|
(define url->path/static (make-url->path "static"))
|
||||||
|
|
||||||
|
(define static-dispatcher
|
||||||
|
(files:make #:url->path (lambda (u)
|
||||||
|
(url->path/static
|
||||||
|
(struct-copy url u [path (cdr (url-path u))])))))
|
||||||
|
|
||||||
|
;; rss feed
|
||||||
|
(define (xml-response content)
|
||||||
|
(response/full
|
||||||
|
200
|
||||||
|
#"OK"
|
||||||
|
(current-seconds)
|
||||||
|
#"application/atom+xml; charset=utf-8"
|
||||||
|
'()
|
||||||
|
(list content)))
|
||||||
|
|
||||||
|
|
||||||
|
(define (rss-feed request)
|
||||||
|
(xml-response
|
||||||
|
(string->bytes/utf-8 (file->string "source/feed.atom"))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; 404
|
||||||
|
(define (not-found request)
|
||||||
|
(lambda (req) ((404-page))))
|
||||||
|
|
||||||
|
;;; server
|
||||||
|
(define stop
|
||||||
|
(serve
|
||||||
|
#:dispatch (sequencer:make
|
||||||
|
(filter:make #rx"^/static/" static-dispatcher)
|
||||||
|
(dispatch/servlet #:regexp #rx"^/hx/" httpx-app)
|
||||||
|
(dispatch/servlet #:regexp #rx"^/feed.atom" rss-feed)
|
||||||
|
(dispatch/servlet page-app)
|
||||||
|
(dispatch/servlet not-found))
|
||||||
|
#:listen-ip "127.0.0.1"
|
||||||
|
#:port 8000))
|
||||||
|
|
||||||
|
(with-handlers ([exn:break? (lambda (e)
|
||||||
|
(stop))])
|
||||||
|
(sync/enable-break never-evt))
|
||||||
|
|
107
publish.rkt
107
publish.rkt
|
@ -5,13 +5,12 @@
|
||||||
(only-in racket/format ~a)
|
(only-in racket/format ~a)
|
||||||
(only-in racket/list append* first second third fourth fifth rest flatten add-between take)
|
(only-in racket/list append* first second third fourth fifth rest flatten add-between take)
|
||||||
(only-in xml xexpr->string)
|
(only-in xml xexpr->string)
|
||||||
|
(only-in "./utils.rkt" homepage git-forge source-url list->csv add-atom-entry atom-table-entry make-feed archive-file)
|
||||||
csv-reading)
|
csv-reading)
|
||||||
|
|
||||||
(define-namespace-anchor anc)
|
(define-namespace-anchor anc)
|
||||||
(define ns (namespace-anchor->namespace anc))
|
(define ns (namespace-anchor->namespace anc))
|
||||||
|
|
||||||
(define homepage "https://sorrel.dev")
|
|
||||||
|
|
||||||
|
|
||||||
;; publish needs to:
|
;; publish needs to:
|
||||||
|
|
||||||
|
@ -21,15 +20,15 @@
|
||||||
|
|
||||||
;; - update a read-table for resource type
|
;; - update a read-table for resource type
|
||||||
|
|
||||||
;; - update the atom.txt feed
|
;; - update the atom feed
|
||||||
|
|
||||||
;; - move the original input file
|
;; - move the original input file
|
||||||
|
|
||||||
;; example
|
;; example
|
||||||
;; publish -input-file in-progress/beginning-latl.txt --resource-type unsettled --tags latl,conlang \
|
;; publish -input-file in-progress/beginning-latl..scm --resource-type unsettled --tags latl,conlang \
|
||||||
;; --headline "Beginning LATL" --description "beginning the process of thinking through an environment \
|
;; --headline "Beginning LATL" --description "beginning the process of thinking through an environment \
|
||||||
;; for conlanging and other language shenanigans"
|
;; for conlanging and other language shenanigans"
|
||||||
;; publish -i in-progress/beginning-latl.txt -r unsettled -t latl,conlang -l "Beginning LATL" \
|
;; publish -i in-progress/beginning-latl.scm -r unsettled -t latl,conlang -l "Beginning LATL" \
|
||||||
;; -d "beginning the process of thinking through an environment for conlanging and other language shenanigans"
|
;; -d "beginning the process of thinking through an environment for conlanging and other language shenanigans"
|
||||||
(help (usage "Publish is here to put yr posts together."))
|
(help (usage "Publish is here to put yr posts together."))
|
||||||
|
|
||||||
|
@ -74,44 +73,37 @@
|
||||||
(let ([l (eval (read (open-input-file "tag-lookup.rkt")))])
|
(let ([l (eval (read (open-input-file "tag-lookup.rkt")))])
|
||||||
(print l)))
|
(print l)))
|
||||||
|
|
||||||
(define (append-post-footer post-xexpr tag-list history-list)
|
(define (append-post-footer post-xexpr s-url tag-list history-list)
|
||||||
(let ([post-footer
|
(let ([post-footer
|
||||||
(read (open-input-file "source/post-footer.txt"))])
|
(read (open-input-file "source/post-footer.scm"))])
|
||||||
`(body
|
`(body
|
||||||
,post-xexpr
|
,post-xexpr
|
||||||
,((eval post-footer ns) tag-list history-list))))
|
,((eval post-footer ns) s-url tag-list history-list))))
|
||||||
|
|
||||||
(define (make-output-file-handle x-test r-type #:headline [l-headline ""] #:res-id [r-id 0])
|
(define (make-output-file-handle x-test r-type #:headline [l-headline ""] #:res-id [r-id 0])
|
||||||
(define (make-root-file-handle x l)
|
(define (make-root-file-handle x l)
|
||||||
(if (non-empty-string? l)
|
(if (non-empty-string? l)
|
||||||
(path->string (path-add-extension (build-path (if x "publish-test/source" "source")
|
(path->string (path-add-extension (build-path (if x "publish-test/source" "source")
|
||||||
(string-replace l " " "-"))
|
(string-replace l " " "-"))
|
||||||
".txt"))
|
".scm"))
|
||||||
(error "'root resource requires headline")))
|
(error "'root resource requires headline")))
|
||||||
(define (make-res-file-handle x r id)
|
(define (make-res-file-handle x r id)
|
||||||
(if (< 0 id)
|
|
||||||
(path->string (path-add-extension (build-path (if x "publish-test/source" "source") r (~a id))
|
(path->string (path-add-extension (build-path (if x "publish-test/source" "source") r (~a id))
|
||||||
".txt"))
|
".scm")))
|
||||||
(error "~a resource requires r-id" r)))
|
|
||||||
(if (equal? r-type "root")
|
(if (equal? r-type "root")
|
||||||
(make-root-file-handle x-test l-headline)
|
(make-root-file-handle x-test l-headline)
|
||||||
(make-res-file-handle x-test r-type r-id)))
|
(make-res-file-handle x-test r-type r-id)))
|
||||||
|
|
||||||
(define (archive-file i x)
|
|
||||||
(if x
|
|
||||||
(copy-file i (string-replace i "in-progress" "publish-test/archive") #t)
|
|
||||||
(rename-file-or-directory i (string-replace i "in-progress" "archive"))))
|
|
||||||
|
|
||||||
(define (write-new-tagged/index tag-table #:test [x #f])
|
(define (write-new-tagged/index tag-table #:test [x #f])
|
||||||
(displayln "write-new-tagged/index")
|
(displayln "write-new-tagged/index")
|
||||||
(let* ([tags (rest (map (lambda (row) (first row))
|
(let* ([tags (rest (map (lambda (row) (first row))
|
||||||
tag-table))]
|
tag-table))]
|
||||||
[make-index (read (open-input-file "source/make-index.txt"))]
|
[make-index (read (open-input-file "source/make-index.scm"))]
|
||||||
[new-index ((eval make-index ns) "tagged" tags)]
|
[new-index ((eval make-index ns) "tagged" tags)]
|
||||||
[handle (path-add-extension (if x
|
[handle (path-add-extension (if x
|
||||||
(build-path "publish-test" "source" "tagged" "index")
|
(build-path "publish-test" "source" "tagged" "index")
|
||||||
(build-path "source" "tagged" "index"))
|
(build-path "source" "tagged" "index"))
|
||||||
".txt")]
|
".scm")]
|
||||||
[file (open-output-file handle #:exists 'replace)])
|
[file (open-output-file handle #:exists 'replace)])
|
||||||
(if (port-try-file-lock? file 'exclusive)
|
(if (port-try-file-lock? file 'exclusive)
|
||||||
(begin
|
(begin
|
||||||
|
@ -150,15 +142,15 @@
|
||||||
[resources (make-weak-hash)]
|
[resources (make-weak-hash)]
|
||||||
[posts (map (lambda (lookup/id)
|
[posts (map (lambda (lookup/id)
|
||||||
(if (hash-has-key? post-lookup lookup/id)
|
(if (hash-has-key? post-lookup lookup/id)
|
||||||
(hash-ref post-lookup lookup/id)
|
(append (list lookup/id) (rest (hash-ref post-lookup lookup/id)))
|
||||||
(get-post-data lookup/id resources post-lookup x)))
|
(append (list lookup/id) (rest (get-post-data lookup/id resources post-lookup x)))))
|
||||||
(filter non-empty-string? (rest tag-table-row)))]
|
(filter non-empty-string? (rest tag-table-row)))]
|
||||||
[make-index (read (open-input-file "source/make-index.txt"))]
|
[make-index (read (open-input-file "source/make-index.scm"))]
|
||||||
[new-index ((eval make-index ns) (~a "tagged/" tag) posts)]
|
[new-index ((eval make-index ns) (~a "tagged/" tag) posts)]
|
||||||
[handle (path-add-extension (if x
|
[handle (path-add-extension (if x
|
||||||
(build-path "publish-test" "source" "tagged" (first tag-table-row))
|
(build-path "publish-test" "source" "tagged" (first tag-table-row))
|
||||||
(build-path "source" "tagged" tag))
|
(build-path "source" "tagged" tag))
|
||||||
#".txt")]
|
#".scm")]
|
||||||
[file (open-output-file handle #:exists 'replace)])
|
[file (open-output-file handle #:exists 'replace)])
|
||||||
(if (port-try-file-lock? file 'exclusive)
|
(if (port-try-file-lock? file 'exclusive)
|
||||||
(begin
|
(begin
|
||||||
|
@ -170,12 +162,12 @@
|
||||||
|
|
||||||
(define (write-new-resource/index resource resource-table #:test [x #f])
|
(define (write-new-resource/index resource resource-table #:test [x #f])
|
||||||
(displayln "write-new-resource/index")
|
(displayln "write-new-resource/index")
|
||||||
(let* ([make-index (read (open-input-file "source/make-index.txt"))]
|
(let* ([make-index (read (open-input-file "source/make-index.scm"))]
|
||||||
[new-index ((eval make-index ns) resource (rest resource-table))]
|
[new-index ((eval make-index ns) resource (rest resource-table))]
|
||||||
[handle (path-add-extension (if x
|
[handle (path-add-extension (if x
|
||||||
(build-path "publish-test" "source" resource "index")
|
(build-path "publish-test" "source" resource "index")
|
||||||
(build-path "source" resource "index"))
|
(build-path "source" resource "index"))
|
||||||
#".txt")]
|
#".scm")]
|
||||||
[file (open-output-file handle #:exists 'replace)])
|
[file (open-output-file handle #:exists 'replace)])
|
||||||
(if (port-try-file-lock? file 'exclusive)
|
(if (port-try-file-lock? file 'exclusive)
|
||||||
(begin
|
(begin
|
||||||
|
@ -184,17 +176,6 @@
|
||||||
(close-output-port file))
|
(close-output-port file))
|
||||||
(error "couldn't obtain file lock on ~a" file))))
|
(error "couldn't obtain file lock on ~a" file))))
|
||||||
|
|
||||||
;; takes a parsed table as a list of lists and formats for writing as a .csv file
|
|
||||||
(define (list->csv l)
|
|
||||||
(foldl (lambda (i res)
|
|
||||||
(string-append res i))
|
|
||||||
""
|
|
||||||
(flatten
|
|
||||||
(add-between (map (lambda (row)
|
|
||||||
(add-between row ","))
|
|
||||||
l)
|
|
||||||
"\n"))))
|
|
||||||
|
|
||||||
|
|
||||||
(define (write-csv-to-file data handle)
|
(define (write-csv-to-file data handle)
|
||||||
(let ([file (open-output-file handle #:exists 'replace)])
|
(let ([file (open-output-file handle #:exists 'replace)])
|
||||||
|
@ -222,15 +203,6 @@
|
||||||
tag-list)
|
tag-list)
|
||||||
new-tt))))
|
new-tt))))
|
||||||
|
|
||||||
(define (add-atom-entry atom-table new-row)
|
|
||||||
;; take only first 21 rows (or all rows)
|
|
||||||
;; insert new-row after header
|
|
||||||
(let ([out-length (min (+ 1 (length atom-table)) 21)]
|
|
||||||
[header (first atom-table)]
|
|
||||||
[old-content (rest atom-table)])
|
|
||||||
(take (append (list header new-row) old-content)
|
|
||||||
out-length)))
|
|
||||||
|
|
||||||
|
|
||||||
(program
|
(program
|
||||||
(publish)
|
(publish)
|
||||||
|
@ -251,9 +223,7 @@
|
||||||
(build-path "data" r))
|
(build-path "data" r))
|
||||||
#".csv"))))
|
#".csv"))))
|
||||||
|
|
||||||
(define res-id (if (equal? r "root")
|
(define res-id (string-replace l " " "-"))
|
||||||
(string-replace l " " "-")
|
|
||||||
(length res-table)))
|
|
||||||
;; before anything else, open output file
|
;; before anything else, open output file
|
||||||
;; doing this means that if a file exists of the intended
|
;; doing this means that if a file exists of the intended
|
||||||
(define out
|
(define out
|
||||||
|
@ -266,6 +236,7 @@
|
||||||
|
|
||||||
|
|
||||||
(define resource (append-post-footer (read (open-input-file i))
|
(define resource (append-post-footer (read (open-input-file i))
|
||||||
|
(source-url r res-id)
|
||||||
t
|
t
|
||||||
(list publish-time)))
|
(list publish-time)))
|
||||||
|
|
||||||
|
@ -280,6 +251,7 @@
|
||||||
|
|
||||||
|
|
||||||
;; update tag table
|
;; update tag table
|
||||||
|
(displayln "updating tag table")
|
||||||
(define tag-table (csv->list (open-input-file
|
(define tag-table (csv->list (open-input-file
|
||||||
(if x "publish-test/data/tagged.csv" "data/tagged.csv"))))
|
(if x "publish-test/data/tagged.csv" "data/tagged.csv"))))
|
||||||
(define new-tag-table (write-new-tag-table tag-table t r res-id))
|
(define new-tag-table (write-new-tag-table tag-table t r res-id))
|
||||||
|
@ -289,11 +261,11 @@
|
||||||
(if x
|
(if x
|
||||||
(write-new-tagged/index new-tag-table #:test #t)
|
(write-new-tagged/index new-tag-table #:test #t)
|
||||||
(write-new-tagged/index new-tag-table)))
|
(write-new-tagged/index new-tag-table)))
|
||||||
; (displayln new-tag-table)
|
|
||||||
(write-csv-to-file (list->csv new-tag-table)
|
(write-csv-to-file (list->csv new-tag-table)
|
||||||
(if x "publish-test/data/tagged.csv" "data/tagged.csv"))
|
(if x "publish-test/data/tagged.csv" "data/tagged.csv"))
|
||||||
|
|
||||||
|
(displayln "updating tagged/'tag")
|
||||||
;; update tagged/'tag for each tag
|
;; update tagged/'tag for each tag
|
||||||
(for-each
|
(for-each
|
||||||
(lambda (tt-row)
|
(lambda (tt-row)
|
||||||
|
@ -308,21 +280,23 @@
|
||||||
'())))
|
'())))
|
||||||
new-tag-table)
|
new-tag-table)
|
||||||
|
|
||||||
|
(displayln "writing resource to file")
|
||||||
;; write to file
|
;; write to file
|
||||||
(if (port-try-file-lock? out 'exclusive)
|
(if (port-try-file-lock? out 'exclusive)
|
||||||
(begin
|
(begin
|
||||||
(write resource out)
|
(print resource out)
|
||||||
(port-file-unlock out)
|
(port-file-unlock out)
|
||||||
(close-output-port out))
|
(close-output-port out))
|
||||||
(error "couldn't obtain file lock on ~a" out))
|
(error "couldn't obtain file lock on ~a" out))
|
||||||
|
|
||||||
|
;; update 'resource/index
|
||||||
;; update 'resource/index (unless root)
|
|
||||||
(if (equal? r "root")
|
(if (equal? r "root")
|
||||||
(displayln "skipping write-new-resource/index")
|
(displayln "skipping resource/index")
|
||||||
(write-new-resource/index r new-res-table #:test (if x #t #f)))
|
(begin
|
||||||
|
(displayln "updating resource/index")
|
||||||
|
(write-new-resource/index r new-res-table #:test (if x #t #f))))
|
||||||
|
|
||||||
|
(displayln "updating feed table")
|
||||||
;; update feed table
|
;; update feed table
|
||||||
(define atom-table (csv->list
|
(define atom-table (csv->list
|
||||||
(open-input-file
|
(open-input-file
|
||||||
|
@ -332,29 +306,28 @@
|
||||||
(build-path "data" "atom"))
|
(build-path "data" "atom"))
|
||||||
#".csv"))))
|
#".csv"))))
|
||||||
(define new-atom-table
|
(define new-atom-table
|
||||||
(add-atom-entry atom-table (list l (~a res-link) d publish-time)))
|
(add-atom-entry atom-table (atom-table-entry l (~a res-link) d publish-time)))
|
||||||
(write-csv-to-file (list->csv new-atom-table)
|
(write-csv-to-file (list->csv new-atom-table)
|
||||||
(if x "publish-test/data/atom.csv" "data/atom.csv"))
|
(if x "publish-test/data/atom.csv" "data/atom.csv"))
|
||||||
|
|
||||||
|
|
||||||
;; update feed.atom
|
;; update feed.atom
|
||||||
;; for now, this does not include the html for the post, only a link
|
;; for now, this does not include the html for the post, only a link
|
||||||
(define feed ((eval (read (open-input-file (if x
|
(displayln "updating feed")
|
||||||
"publish-test/data/make-atom.txt"
|
|
||||||
"data/make-atom.txt"))) ns)
|
|
||||||
"https://sorrel.dev/feed.atom"
|
|
||||||
publish-time
|
|
||||||
homepage
|
|
||||||
(rest new-atom-table)))
|
|
||||||
(define feed-out
|
(define feed-out
|
||||||
(open-output-file (if x "publish-test/source/feed.atom"
|
(open-output-file (if x "publish-test/source/feed.atom"
|
||||||
"source/feed.atom")
|
"source/feed.atom")
|
||||||
#:exists 'replace))
|
;; need to remove this and just replace once testing is done
|
||||||
|
#:exists 'replace ))
|
||||||
(if (port-try-file-lock? feed-out 'exclusive)
|
(if (port-try-file-lock? feed-out 'exclusive)
|
||||||
(begin
|
(begin
|
||||||
(display
|
(display
|
||||||
(string-append "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
(make-feed ns (open-input-file
|
||||||
(xexpr->string feed))
|
(if x
|
||||||
|
"publish-test/data/make-atom.scm"
|
||||||
|
"data/make-atom.scm"))
|
||||||
|
new-atom-table
|
||||||
|
publish-time)
|
||||||
feed-out)
|
feed-out)
|
||||||
(port-file-unlock feed-out)
|
(port-file-unlock feed-out)
|
||||||
(close-output-port feed-out))
|
(close-output-port feed-out))
|
||||||
|
|
174
sorrel.dev.rkt
174
sorrel.dev.rkt
|
@ -1,174 +0,0 @@
|
||||||
#lang racket
|
|
||||||
|
|
||||||
(require racket/date
|
|
||||||
(only-in racket/list first second third rest)
|
|
||||||
(only-in racket/string string-prefix? string-replace)
|
|
||||||
net/url
|
|
||||||
xml
|
|
||||||
web-server/web-server
|
|
||||||
web-server/servlet-dispatch
|
|
||||||
web-server/dispatchers/dispatch
|
|
||||||
web-server/dispatch
|
|
||||||
(prefix-in files: web-server/dispatchers/dispatch-files)
|
|
||||||
(prefix-in filter: web-server/dispatchers/dispatch-filter)
|
|
||||||
(prefix-in sequencer: web-server/dispatchers/dispatch-sequencer)
|
|
||||||
racket/runtime-path
|
|
||||||
web-server/dispatchers/filesystem-map
|
|
||||||
web-server/http
|
|
||||||
csv-reading)
|
|
||||||
|
|
||||||
;; namespace needed for evaluating read files
|
|
||||||
(define-namespace-anchor anc)
|
|
||||||
(define ns (namespace-anchor->namespace anc))
|
|
||||||
|
|
||||||
;; it's all html!
|
|
||||||
(define (html-response content)
|
|
||||||
(response/full
|
|
||||||
200
|
|
||||||
#"OK"
|
|
||||||
(current-seconds)
|
|
||||||
TEXT/HTML-MIME-TYPE
|
|
||||||
'()
|
|
||||||
(list content)))
|
|
||||||
|
|
||||||
|
|
||||||
;; takes a resource-type (corresponds to the REST resource and the system path or
|
|
||||||
;; an index resource in the source path)
|
|
||||||
;; and a resource-processor (-> file-handle . http-response)
|
|
||||||
;; and returns a valid html-response irrespective of hx/ type fragment of html or full page
|
|
||||||
(define respond-resource-with-processor
|
|
||||||
(lambda (type resource-processor)
|
|
||||||
;; bound path builders
|
|
||||||
;; extension is always #".txt" because source files are not well-formed racket,
|
|
||||||
;; but must be read and evaluated in this namespace
|
|
||||||
(define (make-res-path-no-param t)
|
|
||||||
(path-add-extension
|
|
||||||
(if (and (non-empty-string? t) (not (eq? t "root")))
|
|
||||||
(build-path "source" t "index")
|
|
||||||
(build-path "source" "index" ))
|
|
||||||
#".txt"))
|
|
||||||
|
|
||||||
(define (make-res-path-id-param t id)
|
|
||||||
(path-add-extension
|
|
||||||
(build-path "source" (if (eq? t "root")
|
|
||||||
(if (eq? id "")
|
|
||||||
;; if "root/" something weird has happened
|
|
||||||
"index"
|
|
||||||
;; allows for loading "/this" and other root resources
|
|
||||||
(~a id))
|
|
||||||
(if
|
|
||||||
;; if url has trailing backslash, id will be an empty string
|
|
||||||
;; and should return index for that type
|
|
||||||
(or (not (string? id))
|
|
||||||
(non-empty-string? id))
|
|
||||||
(build-path t (~a id))
|
|
||||||
(build-path t "index"))))
|
|
||||||
#".txt"))
|
|
||||||
;; this lambda will be called by dispatch-rules
|
|
||||||
;; (req) is the request object
|
|
||||||
(case-lambda
|
|
||||||
[(req) (let ([res-path (make-res-path-no-param type)])
|
|
||||||
(if (file-exists? res-path)
|
|
||||||
(html-response (resource-processor res-path))
|
|
||||||
(html-response (resource-processor "source/not-found.txt"))))]
|
|
||||||
;; (req id) is (request object . url parameter)
|
|
||||||
[(req id) (let ([res-path (make-res-path-id-param type id)])
|
|
||||||
(if (file-exists? res-path)
|
|
||||||
(html-response (resource-processor res-path))
|
|
||||||
(html-response (resource-processor "source/not-found.txt"))))])))
|
|
||||||
|
|
||||||
;;; httpx
|
|
||||||
;; sends only the requested resource
|
|
||||||
(define (xexpr-file->xml file)
|
|
||||||
(string->bytes/utf-8
|
|
||||||
(xexpr->string (read (open-input-file file)))))
|
|
||||||
|
|
||||||
|
|
||||||
(define (404-hx request)
|
|
||||||
(html-response (xexpr-file->xml "source/not-found.txt")))
|
|
||||||
|
|
||||||
|
|
||||||
(define-values (httpx-app reverse-httpx-uri)
|
|
||||||
(dispatch-rules
|
|
||||||
[("hx" "home") (respond-resource-with-processor "root" xexpr-file->xml)]
|
|
||||||
[("hx" "settled") (respond-resource-with-processor "settled" xexpr-file->xml)]
|
|
||||||
[("hx" "settled" (integer-arg)) (respond-resource-with-processor "settled" xexpr-file->xml)]
|
|
||||||
[("hx" "unsettled") (respond-resource-with-processor "unsettled" xexpr-file->xml)]
|
|
||||||
[("hx" "unsettled" (integer-arg)) (respond-resource-with-processor "unsettled" xexpr-file->xml)]
|
|
||||||
[("hx" "tagged") (respond-resource-with-processor "tagged" xexpr-file->xml)]
|
|
||||||
[("hx" "tagged" (string-arg)) (respond-resource-with-processor "tagged" xexpr-file->xml)]
|
|
||||||
[("hx" (string-arg)) (respond-resource-with-processor "root" xexpr-file->xml)]
|
|
||||||
[else 404-hx]))
|
|
||||||
|
|
||||||
;;; page-app
|
|
||||||
;; constructs entire page for each response
|
|
||||||
(define (make-page resource)
|
|
||||||
(string->bytes/utf-8
|
|
||||||
(xexpr->string
|
|
||||||
`(html ((lang "en"))
|
|
||||||
,(read (open-input-file "source/head.txt"))
|
|
||||||
(body
|
|
||||||
,(read (open-input-file "source/header.txt"))
|
|
||||||
(main ,(read (open-input-file resource))))))))
|
|
||||||
|
|
||||||
(define-values (page-app reverse-page-uri)
|
|
||||||
(dispatch-rules
|
|
||||||
[("") (respond-resource-with-processor "" make-page)]
|
|
||||||
[("home") (respond-resource-with-processor "" make-page)]
|
|
||||||
[("settled") (respond-resource-with-processor "settled" make-page)]
|
|
||||||
[("settled" (integer-arg)) (respond-resource-with-processor "settled" make-page)]
|
|
||||||
[("unsettled") (respond-resource-with-processor "unsettled" make-page)]
|
|
||||||
[("unsettled" (integer-arg)) (respond-resource-with-processor "unsettled" make-page)]
|
|
||||||
[("tagged") (respond-resource-with-processor "tagged" make-page)]
|
|
||||||
[("tagged" (string-arg)) (respond-resource-with-processor "tagged" make-page)]
|
|
||||||
[((string-arg)) (respond-resource-with-processor "root" make-page)]
|
|
||||||
[else not-found]))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;; from /static
|
|
||||||
(define url->path/static (make-url->path "static"))
|
|
||||||
|
|
||||||
(define static-dispatcher
|
|
||||||
(files:make #:url->path (lambda (u)
|
|
||||||
(url->path/static
|
|
||||||
(struct-copy url u [path (cdr (url-path u))])))))
|
|
||||||
|
|
||||||
;; rss feed
|
|
||||||
(define (xml-response content)
|
|
||||||
(response/full
|
|
||||||
200
|
|
||||||
#"OK"
|
|
||||||
(current-seconds)
|
|
||||||
#"application/atom+xml; charset=utf-8"
|
|
||||||
'()
|
|
||||||
(list content)))
|
|
||||||
|
|
||||||
|
|
||||||
(define (rss-feed request)
|
|
||||||
(xml-response
|
|
||||||
(string->bytes/utf-8 (file->string "source/feed.atom"))))
|
|
||||||
|
|
||||||
|
|
||||||
;;; 404
|
|
||||||
(define (not-found request)
|
|
||||||
(html-response (make-page "source/not-found.txt")))
|
|
||||||
|
|
||||||
|
|
||||||
;;; server
|
|
||||||
(define stop
|
|
||||||
(serve
|
|
||||||
#:dispatch (sequencer:make
|
|
||||||
(filter:make #rx"^/static/" static-dispatcher)
|
|
||||||
(dispatch/servlet #:regexp #rx"^/hx/" httpx-app)
|
|
||||||
(dispatch/servlet #:regexp #rx"^/feed.atom" rss-feed)
|
|
||||||
(dispatch/servlet page-app)
|
|
||||||
(dispatch/servlet not-found)
|
|
||||||
)
|
|
||||||
#:listen-ip "127.0.0.1"
|
|
||||||
#:port 8000))
|
|
||||||
|
|
||||||
(with-handlers ([exn:break? (lambda (e)
|
|
||||||
(stop))])
|
|
||||||
(sync/enable-break never-evt))
|
|
||||||
|
|
1
source/about.scm
Normal file
1
source/about.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(body (section (h2 "a λ.functional λ.gay") (p "i'm a gay lil nerd who's learning everyday about community, and ecology,\n and computer; and trying hard to be good for the world with my gay lil\n friends") (p "i was named after " (a ((href "https://plants.usda.gov/home/plantProfile?symbol=OXOR")) "a plant called sorrel") " and i live in the mountains of southern appalachia on " (span ((lang "chr")) "ᏣᎳᎩ") " (tsalagi/cherokee) land") (p "i have never identified with the term 'hacker' but i have learned, in the\n past few years, that i do like to orchestrate computer machines and i do\n that with some cute friends at " (a ((href "https://bunk.computer")) "bunk computer club")) (p "some random things i believe/ i like/ i am/etc (in no particular order") (ul (li (p "i like linguistics a whole lot. " (span ((class "hx-target")) (a ((href "/tagged/conlang") (hx-get "/hx/tagged/conlang") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "i make languages (the human kind) for fun.")) " there's a whole bunch of people who do this! " (a ((href "https://conlang.org/")) "the language creation society") " i'm even working on a " (span ((class "hx-target")) (a ((href "/tagged/latl") (hx-get "/hx/tagged/latl") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "language (computer) to make languages (human)")))) (li (p "mmt, but make it anarchist " (small "-- get rid of all that \"sovereignty\" stuff, ew"))) (li (p "make everything a library and everyone a librarian")) (li (p "do things that aren't computer. compute more with regular computer ppl\n and less with tech-brained ppl. most ppl know how to compute, and don't\n need to know what is an abstract factory factory")) (li (p "got a spicy brained, trans lady-fied experience.\n i have feelings about these things that inevitably weave thru\n my projects and art and all that")) (li (p "i used to make a lot more visual art than i do these days. some\n sort of smth'll wind up here at some point")))) (footer (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/source/about.scm")) "view source") (hr) (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2024-01-18T21:56:45modified: 2024-03-23T16:29:13\n")) (p ((class "license-info")) (small (a ((href "static/license/license.txt")) "license")))))
|
|
@ -1 +0,0 @@
|
||||||
(body (section (h2 "a λ.functional λ.gay") (p "i'm a gay lil nerd who's learning everyday about community, and ecology,\n and computer; and trying hard to be good for the world with my gay lil\n friends") (p "i was named after " (a ((href "https://plants.usda.gov/home/plantProfile?symbol=OXOR")) "a plant called sorrel") " and i live in the mountains of southern appalachia on " (span ((lang "chr")) "ᏣᎳᎩ") " (tsalagi/cherokee) land. i live with some cats and a whole mess of plants\n (most of them food) and a cordswain and i have sweet neighbors") (p "i have never identified with the term 'hacker' but i have learned, in the\n past few years, that i do like to orchestrate computer machines and i do\n that with some cute friends at " (a ((href "https://bunk.computer")) "bunk computer club")) (p "some random things i believe/ i like/ i am/etc (in no particular order") (ul (li (p "i like linguistics a whole lot. " (span ((class "hx-target")) (a ((href "/tagged/conlang") (hx-get "/hx/tagged/conlang") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "i make languages (the human kind) for fun.")) " there's a whole bunch of people who do this! " (a ((href "https://conlang.org/")) "the language creation society") " i'm even working on a " (span ((class "hx-target")) (a ((href "/tagged/latl") (hx-get "/hx/tagged/latl") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "language (computer) to make languages (human)")))) (li (p "mmt, but make it anarchist " (small "and get rid of all that \"sovereignty\" stuff, ew"))) (li (p "got a spicy brained, trans lady-fied experience. \n i have feelings about these things that inevitably weave thru\n my projects and art and all that")) (li (p "i used to make a lot more visual art than i do these days. some\n sort of smth'll wind up here at some point")))) (footer (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2023-12-24T19:15:34")) (p ((class "license-info")) (small (a ((href "/license")) "license")))))
|
|
|
@ -1,25 +0,0 @@
|
||||||
(lambda (feed-ref update-time homepage)
|
|
||||||
`(feed
|
|
||||||
((xmlns "http://www.w3.org/2005/Atom"))
|
|
||||||
(title "λ.sorrel.dev")
|
|
||||||
(link ((rel "self")
|
|
||||||
(href ,feed-ref)))
|
|
||||||
(updated ,update-time)
|
|
||||||
(author
|
|
||||||
(name "sorrel"))
|
|
||||||
(id ,homepage)
|
|
||||||
|
|
||||||
; ,(map
|
|
||||||
; (lambda (item)
|
|
||||||
; `(entry
|
|
||||||
; (title ,(title item))
|
|
||||||
; (link ((href ,(href item))))
|
|
||||||
; (id ,(href item))
|
|
||||||
; (type ,(type item)) ; usually html
|
|
||||||
; ,(map (lambda (category)
|
|
||||||
; `(category ((term ,(term category))
|
|
||||||
; (scheme ,(scheme category)))))
|
|
||||||
; (categories item))
|
|
||||||
; (updated ,(updated item)))
|
|
||||||
; items))
|
|
||||||
))
|
|
48
source/cat.scm
Normal file
48
source/cat.scm
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
(article
|
||||||
|
((id "cat"))
|
||||||
|
(h1 "cat care")
|
||||||
|
(p "hi! thank you so much for being part of caring for my dear feline! here is a trove of altogether too much information. please read what feels necessary and the rest will be here if you ever need it <3")
|
||||||
|
(section
|
||||||
|
((id "contacts"))
|
||||||
|
(h2 "contacts")
|
||||||
|
(p "if anything happens and you can't reach me, vet numbers to know are:")
|
||||||
|
(ul
|
||||||
|
((id "vets"))
|
||||||
|
(li
|
||||||
|
(p "primary vet is Ann Schneider, DVM at Open Door Veterinary Care")
|
||||||
|
(ul (li "phone: 828 417 7768")
|
||||||
|
(li "address: 1419 patton ave")
|
||||||
|
(li (a ((href "https://opendoorveterinarycare.com"))
|
||||||
|
"website"))))
|
||||||
|
(li
|
||||||
|
(p "emergency vet is medvet. (she's never needed to go, but i've gone there with other cats")
|
||||||
|
(ul (li "phone: 828 665 4399")
|
||||||
|
(li "address: 677 brevard rd")
|
||||||
|
(li (a ((href "https://www.medvet.com/location/asheville"))
|
||||||
|
"website"))))))
|
||||||
|
(section
|
||||||
|
((id "food-and-water"))
|
||||||
|
(hgroup
|
||||||
|
(h2 "food and water")
|
||||||
|
(p (em "the most necessary of the necessary stuff")))
|
||||||
|
(p "she currently takes a heaping 1/4 cup of kibble at 11am and 11pm daily. you can adjust the exact times to your life, as long as there about 12 hrs apart. feeding her closer to your bedtime will mean that she doesn't get fussy in the morning and demand an early breakfast")
|
||||||
|
(p "the food she's been getting now is a blend of fancy orijen 6 fish adult cat food and purina cat chow complete. if yr starting to run out i can order some to be delivered or you can pick up more of the purina at petsmart")
|
||||||
|
(p "if the water fountain is too annoying to deal with, you can use a bowl - please empty and refresh it during one of her meals")
|
||||||
|
(p "if the water fountain is not too annoying: the water level should be between just above and just below the 'snout' window. i've had to take it apart and rinse all the pieces at least once a week with three cats sharing it, you'll probably not have to do that as much. the filter should be changed mid month ~15th. the manual is in the box or you can ask me if it's being weird"))
|
||||||
|
(section
|
||||||
|
((id "medicine"))
|
||||||
|
(h2 "medicine")
|
||||||
|
(p "the thing she definitely needs is selamectin applied on the last day of the month. the applicator is a little weird--you twist the tip to break the internal seal and squeeze to apply--there's no cap on it. apply a full applicator to the base of her neck near the collar line while spreading her fur out of the way. wash yr hands and try not to touch her for a few hours after applying")
|
||||||
|
(p "you shouldn't need to deal with this, but *if* she starts scratching her ears incessantly, you can apply some of the ear drops daily for a few days. it works best if you can get them in to her inner ear and massage the base of her ear for a few seconds. she doesn't like this and will try to splash the stuff out of her ear and onto you so watch out! (she hasn't had ear problems in a few years, so you can probably just ignore this)"))
|
||||||
|
(section
|
||||||
|
((id "fun-stuff"))
|
||||||
|
(h2 "fun stuff")
|
||||||
|
(p "brushing! she's got dense fur, so it helps to brush (altho she's never had hairballs so it's not like medically necessary.) she's a typical cat in that she enjoys being brushed until she gets overstimulated and starts attacking the comb")
|
||||||
|
(p "toys! she loves a cat dancer, this is the best way to get her energy out if she's being annoying. she also loves the yellow woven toy and the taco and she might make mournful yowls at you from across the house to let you know she wants to share her favorite toys with you. if you're feeling up to it, you can periodically hide some of her toys to keep her from getting bored with the ones she has")
|
||||||
|
(p "treats! churu's a favorite, but you can also use some of the solid treats to work on her tricks if you like!")
|
||||||
|
(p "tricks! (she's not been doing them a lot lately so she'll probably get really excited and meow and walk in circles for a moment before she settles down and does the things)")
|
||||||
|
(ul (li "'sit': hand signal is fist pointed up, slightly above her ✊")
|
||||||
|
(li "'speak': hand signa is pointing to your mouth")
|
||||||
|
(li "'loaf' (it means lie down): hand signal is a pinching shape pointed down in front of her" (span ((style "rotate: -90deg;")) "🤏"))
|
||||||
|
(li "'touch' (it's basically a headbutt): hand signal is a fist pointed toward her 🤛")))
|
||||||
|
(p "that's all i can think of right now! but of course call me if you've got any questions and if i think of anything i'll let you know and add it here as well. thanks again for taking care of her! please send me lots of pictures!"))
|
1
source/contact.scm
Normal file
1
source/contact.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(body (section (h2 "contact") (p (code "email [at] [this domain]") " to send me a good ol' fashioned email") (p "i have avoided 'online' for a long time, but i'm getting hip to it. i'm\n on the mastodon.social server @oxaliq")) (footer (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/source/contact.scm")) "view source") (hr) (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2024-01-18T22:21:26")) (p ((class "license-info")) (small (a ((href "static/license/license.txt")) "license")))))
|
|
@ -1 +0,0 @@
|
||||||
(body (section (h2 "contact") (p "e-m-" (span "a-i") (span "-l [ at ") (span "] s-o-") (span "r-r-e-l [ d o") (span "t ] d-e") (span "-v is a good place to do the email")) (p "i have avoided 'online' for a long time, but i'm getting hip to it. i'm\n on the big mastodon server @oxaliq")) (footer (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2023-12-24T19:45:11")) (p ((class "license-info")) (small (a ((href "/license")) "license")))))
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,9 @@
|
||||||
(head
|
(head
|
||||||
(meta ((http-equiv "Content-Type")
|
(meta ((http-equiv "Content-Type")
|
||||||
(content "text/html; charset=utf-8")))
|
(content "text/html; charset=utf-8")))
|
||||||
|
(meta ((name "ROBOTS")
|
||||||
|
(content "NOINDEX, NOFOLLOW")))
|
||||||
|
(title "oxaliq.net - learning and making")
|
||||||
(meta ((name "author")
|
(meta ((name "author")
|
||||||
(content "sorrel")))
|
(content "sorrel")))
|
||||||
(meta ((name "description")
|
(meta ((name "description")
|
|
@ -1,4 +1,11 @@
|
||||||
(header
|
(header
|
||||||
|
;; rel="me" verification links
|
||||||
|
(a ((href "https://git.bunk.computer/oxaliq")
|
||||||
|
(rel "me")))
|
||||||
|
(a ((href "https://mastodon.social/@oxaliq")
|
||||||
|
(rel "me")))
|
||||||
|
(a ((href "https://github.com/sorrelbri")
|
||||||
|
(rel "me")))
|
||||||
(div
|
(div
|
||||||
((class "banner")
|
((class "banner")
|
||||||
(hx-get "/hx/home")
|
(hx-get "/hx/home")
|
78
source/index.scm
Normal file
78
source/index.scm
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
(article
|
||||||
|
((id "oxaliq-dot-net-slash-index"))
|
||||||
|
(h1 "oxaliq [dot] net [slash] index")
|
||||||
|
(noscript
|
||||||
|
(div
|
||||||
|
((class "noscript"))
|
||||||
|
(p "hey! yr not letting yr browser execute javascript served by my page.")
|
||||||
|
(p "that's cool!")
|
||||||
|
(p "browser (by google?) as arbitrary code execution platform is one of the
|
||||||
|
weird, regrettable (at least as it is currently implemented)
|
||||||
|
consequences of our political economy.")
|
||||||
|
(p "anyway, feel free to browse! yr experience won't be much different,
|
||||||
|
you'll just get bigger html blob.")
|
||||||
|
(p "the only js i deliver is "
|
||||||
|
(a ((href "https://htmx.org"))
|
||||||
|
"this little REST tool called htmx")
|
||||||
|
" if you want to see what that's about.")
|
||||||
|
(p "o! and if you want to hear/read "
|
||||||
|
(a ((href "/tagged/javascript"))
|
||||||
|
"what i have to say about javascript")
|
||||||
|
" you could do that maybe")
|
||||||
|
(p "/noscript")))
|
||||||
|
(p "hey! i'm sorrel.")
|
||||||
|
(p "(called like the plant up there)")
|
||||||
|
(p "this is my new-fangled website computer page on the world wide web. i had
|
||||||
|
a nice time building this little thing ")
|
||||||
|
(p " i hope you have a nice time looking at things here")
|
||||||
|
(hr)
|
||||||
|
(div ((class "hx-target"))
|
||||||
|
(p
|
||||||
|
(a ((href "/this")
|
||||||
|
(hx-get "/hx/this")
|
||||||
|
(hx-target "closest div.hx-target")
|
||||||
|
(hx-swap "innerHTML"))
|
||||||
|
"(how i build this little page)")))
|
||||||
|
(div ((class "hx-target"))
|
||||||
|
(p
|
||||||
|
(a ((href "/now")
|
||||||
|
(hx-get "/hx/now")
|
||||||
|
(hx-target "closest div.hx-target")
|
||||||
|
(hx-swap "innerHTML"))
|
||||||
|
"(what i'm doing)")))
|
||||||
|
(div ((class "hx-target"))
|
||||||
|
(p
|
||||||
|
(a ((href "/about")
|
||||||
|
(hx-get "/hx/about")
|
||||||
|
(hx-target "closest div.hx-target")
|
||||||
|
(hx-swap "innerHTML"))
|
||||||
|
"(who i am)")))
|
||||||
|
(div ((class "hx-target"))
|
||||||
|
(p
|
||||||
|
(a ((href "/contact")
|
||||||
|
(hx-get "/hx/contact")
|
||||||
|
(hx-target "closest div.hx-target")
|
||||||
|
(hx-swap "innerHTML"))
|
||||||
|
"(how to say hi to me)")))
|
||||||
|
(div ((class "hx-target"))
|
||||||
|
(p
|
||||||
|
(a ((href "/very-earnest-disclaimer")
|
||||||
|
(hx-get "/hx/very-earnest-disclaimer")
|
||||||
|
(hx-target "closest div.hx-target")
|
||||||
|
(hx-swap "innerHTML"))
|
||||||
|
"(a very earnest disclaimer)")))
|
||||||
|
; (div ((class "hx-target"))
|
||||||
|
; (p
|
||||||
|
; (a ((href "/links")
|
||||||
|
; (hx-get "/hx/links")
|
||||||
|
; (hx-target "closest div.hx-target")
|
||||||
|
; (hx-swap "innerHTML"))
|
||||||
|
; "(some things i think are neat)")))
|
||||||
|
(p (a ((href "static/license/license.txt"))
|
||||||
|
"license"))
|
||||||
|
(p (a ((href "/tagged"))
|
||||||
|
"all of the kinds of things on here so far"))
|
||||||
|
|
||||||
|
(p ((class "ascii but-normal-size"))
|
||||||
|
"︿︿
|
||||||
|
〰"))
|
|
@ -1,68 +0,0 @@
|
||||||
(main
|
|
||||||
(noscript
|
|
||||||
(span
|
|
||||||
((class "noscript"))
|
|
||||||
(p "hey! yr not letting yr browser execute javascript served by my page.")
|
|
||||||
(p "that's cool!")
|
|
||||||
(p "browser (by google?) as arbitrary code execution platform is one of the
|
|
||||||
weird, regrettable (at least as it is currently implemented)
|
|
||||||
consequences of our political economy.")
|
|
||||||
(p "anyway, feel free to browse! yr experience won't be much different,
|
|
||||||
you'll just get bigger html blob.")
|
|
||||||
(p "the only js i deliver is "
|
|
||||||
(a ((href "https://htmx.org"))
|
|
||||||
"this little REST tool called htmx")
|
|
||||||
" if you want to see what that's about.")
|
|
||||||
(p "o! and if you want to hear/read "
|
|
||||||
(a ((href "/tagged/javascript"))
|
|
||||||
"what i have to say about javascript")
|
|
||||||
" you could do that maybe")
|
|
||||||
(p "/noscript")))
|
|
||||||
(p "hey! i'm sorrel.")
|
|
||||||
(p "(called like the plant up there)")
|
|
||||||
(p "this is my new-fangled website computer page on the world wide web. i had
|
|
||||||
a nice time building this little thing ")
|
|
||||||
(p " i hope you have a nice time looking at things here")
|
|
||||||
(hr)
|
|
||||||
(p (span ((class "hx-target"))
|
|
||||||
(a ((href "/this")
|
|
||||||
(hx-get "/hx/this")
|
|
||||||
(hx-target "closest span")
|
|
||||||
(hx-swap "innerHTML"))
|
|
||||||
"(how i build this little page)")))
|
|
||||||
(p (span ((class "hx-target"))
|
|
||||||
(a ((href "/now")
|
|
||||||
(hx-get "/hx/now")
|
|
||||||
(hx-target "closest span")
|
|
||||||
(hx-swap "innerHTML"))
|
|
||||||
"(what i'm doing)")))
|
|
||||||
(p (span ((class "hx-target"))
|
|
||||||
(a ((href "/about")
|
|
||||||
(hx-get "/hx/about")
|
|
||||||
(hx-target "closest span")
|
|
||||||
(hx-swap "innerHTML"))
|
|
||||||
"(who i am)")))
|
|
||||||
(p (span ((class "hx-target"))
|
|
||||||
(a ((href "/contact")
|
|
||||||
(hx-get "/hx/contact")
|
|
||||||
(hx-target "closest span")
|
|
||||||
(hx-swap "innerHTML"))
|
|
||||||
"(how to say hi to me)")))
|
|
||||||
(p (span ((class "hx-target"))
|
|
||||||
(a ((href "/very-earnest-disclaimer")
|
|
||||||
(hx-get "/hx/very-earnest-disclaimer")
|
|
||||||
(hx-target "closest span")
|
|
||||||
(hx-swap "innerHTML"))
|
|
||||||
"(a very earnest disclaimer)")))
|
|
||||||
; (p (span ((class "hx-target"))
|
|
||||||
; (a ((href "/links")
|
|
||||||
; (hx-get "/hx/links")
|
|
||||||
; (hx-target "closest span")
|
|
||||||
; (hx-swap "innerHTML"))
|
|
||||||
; "(some things i think are neat)")))
|
|
||||||
(p (a ((href "/tagged"))
|
|
||||||
"-> all of the kinds of things on here so far"))
|
|
||||||
|
|
||||||
(p ((class "ascii but-normal-size"))
|
|
||||||
"︿︿
|
|
||||||
〰"))
|
|
|
@ -1,2 +0,0 @@
|
||||||
(article
|
|
||||||
(p "no licensing info yet. this is a real big question."))
|
|
|
@ -14,8 +14,8 @@
|
||||||
(p (em "a categorical mess for your perusal")))]
|
(p (em "a categorical mess for your perusal")))]
|
||||||
[(string-prefix? res "tagged/")
|
[(string-prefix? res "tagged/")
|
||||||
(let ([tag (string-replace res "tagged/" "#")])
|
(let ([tag (string-replace res "tagged/" "#")])
|
||||||
`(hgroup (h1 ,(~a "stuff what's tagged like " tag))
|
`(hgroup (h1 "stuff what's tagged like " (em ,tag))
|
||||||
(p (em (~a "everything (or maybe just some things) i've ever said about \"" tag "\"")))))]
|
(p (em "everything (or maybe just some things) i've ever said about " (strong ,tag)))))]
|
||||||
[else
|
[else
|
||||||
'(hgroup (h1 "i'm lost")
|
'(hgroup (h1 "i'm lost")
|
||||||
(p (em "you weren't meant to be here")))])
|
(p (em "you weren't meant to be here")))])
|
1
source/now.scm
Normal file
1
source/now.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(body (section (hgroup (h2 "now") (p "a snapshot of the (mostly) non-computer things of import")) (section (hgroup (h3 "read") (p "stuff i'm taking in")) (ul (li "palo alto, malcolm harris") (li "paul takes the form of a mortal girl, andrea lawlor") (li "annihilation, jeff vandermeer") (li "let the right one in, tomas alfredson") (li "the limits of control, jim jarmusch") (li "the matrices, wachowskis"))) (section (hgroup (h3 "eval") (p "stuff i'm crunching on")) (ul (li "starting a community maker space") (li "mostly just spending all my time moving") (li "skating again"))) (section (hgroup (h3 "print") (p "stuff i'm putting out")) (ul (li "doing more sewing") (li "baby's first letterpress"))) (section (hgroup (h3 "loop") (p "stuff what's on the horizon")) (ul (li "putting my labor on the market")))) (footer (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/source/now.scm")) "view source") (hr) (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2024-01-18T22:22:03modified: 2024-03-23T16:29:58\n")) (p ((class "license-info")) (small (a ((href "static/license/license.txt")) "license")))))
|
|
@ -1 +0,0 @@
|
||||||
(body (section (hgroup (h2 "now") (p "a snapshot of the (mostly) non-computer things of import")) (section (hgroup (h3 "read") (p "stuff i'm taking in")) (ul (li "the paying guests, sarah waters") (li "females, andrea long chu") (li "palo alto, malcolm harris") (li "high pitched and moist, tami t") (li "desolation's flower, ragana") (li "salesforce, lauren bousfield") (li "el mal querer, rosalía") (li "guacamelee, drinkbox"))) (section (hgroup (h3 "eval") (p "stuff i'm crunching on")) (ul (li "playing more go") (li "winter garden chores") (li "starting a community maker space") (li "going on more hikes") (li "body stuff"))) (section (hgroup (h3 "print") (p "stuff i'm putting out")) (ul (li "fun leatherwork") (li "fun woodwork") (li "relearning how to draw"))) (section (hgroup (h3 "loop") (p "stuff what's on the horizon")) (ul (li "being in the northeastern us") (li "putting my labor on the market") (li "maybe making some music again?")))) (footer (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2023-12-24T19:45:57")) (p ((class "license-info")) (small (a ((href "/license")) "license")))))
|
|
|
@ -1,6 +1,9 @@
|
||||||
(lambda (tag-list history-list)
|
(lambda (source-url tag-list history-list)
|
||||||
(let ([class-sec `(ul ((class "tag-list")))])
|
(let ([class-sec `(ul ((class "tag-list")))])
|
||||||
`(footer
|
`(footer
|
||||||
|
(a ((href ,source-url))
|
||||||
|
"view source")
|
||||||
|
(hr)
|
||||||
(section
|
(section
|
||||||
(h5 "tagged")
|
(h5 "tagged")
|
||||||
,(begin
|
,(begin
|
||||||
|
@ -35,5 +38,5 @@
|
||||||
((class "license-info"))
|
((class "license-info"))
|
||||||
(small
|
(small
|
||||||
(a
|
(a
|
||||||
((href "/license"))
|
((href "static/license/license.txt"))
|
||||||
"license"))))))
|
"license"))))))
|
|
@ -1,34 +0,0 @@
|
||||||
(article
|
|
||||||
(noscript
|
|
||||||
(span
|
|
||||||
((class "noscript"))
|
|
||||||
(p "hey! yr not letting yr browser execute javascript served by my page.")
|
|
||||||
(p "that's cool!")
|
|
||||||
(p "browser (by google?) as arbitrary code execution platform is one of the
|
|
||||||
weird, regrettable (at least as it is currently implemented)
|
|
||||||
consequences of our political economy.")
|
|
||||||
(p "anyway, feel free to browse! yr experience won't be much different,
|
|
||||||
you'll just get bigger html blob.")
|
|
||||||
(p "the only js i deliver is "
|
|
||||||
(a ((href "https://htmx.org"))
|
|
||||||
"this little REST tool called htmx")
|
|
||||||
" if you want to see what that's about.")
|
|
||||||
(p "o! and if you want to hear/read "
|
|
||||||
(a ((href "/tagged/javascript"))
|
|
||||||
"what i have to say about javascript")
|
|
||||||
" you could do that maybe")
|
|
||||||
(p "/noscript")))
|
|
||||||
(p "hey! i'm sorrel.")
|
|
||||||
(p "(called like the plant up there)")
|
|
||||||
(p "this is my new-fangled website computer page on the world wide web. i had
|
|
||||||
a nice time building this little thing "
|
|
||||||
(span ((class "hx-target"))
|
|
||||||
(a ((href "/this")
|
|
||||||
(hx-get "/hx/this")
|
|
||||||
(hx-target "closest span")
|
|
||||||
(hx-swap "innerHTML"))
|
|
||||||
"(how i build this little page.)")))
|
|
||||||
(p " i hope you have a nice time looking at things here.")
|
|
||||||
(p ((class "ascii but-normal-size"))
|
|
||||||
"︿︿
|
|
||||||
〰"))
|
|
|
@ -1,3 +0,0 @@
|
||||||
(section
|
|
||||||
(h1 "404")
|
|
||||||
(p "hey, i couldn't find that. could ya try something else maybe?"))
|
|
1
source/settled/1.scm
Normal file
1
source/settled/1.scm
Normal file
File diff suppressed because one or more lines are too long
1
source/settled/index.scm
Normal file
1
source/settled/index.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "settled* thoughts") (p (em "*-ish, something like a portfolio of projects"))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "feature-change-applier") (p "a first attempt at a conlanging tool") (a ((href "/settled/1")) "go! to feature-change-applier page")))
|
|
@ -1 +0,0 @@
|
||||||
'(article (hgroup (h1 "settled* thoughts") (p (em "*-ish, something like a portfolio of projects"))) (h3 "the thoughts") (p "there's nothing here yet"))
|
|
1
source/tagged/about.scm
Normal file
1
source/tagged/about.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#about")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#about")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "now") (p "what the author of this site is up to (not computer things)") (a ((href "/now")) "go! to now page")) (div ((class "post-preview")) (h4 "contact") (p "how to talk to me") (a ((href "/contact")) "go! to contact page")) (div ((class "post-preview")) (h4 "very earnest disclaimer") (p "being earnest in the streets") (a ((href "/very-earnest-disclaimer")) "go! to very earnest disclaimer page")) (div ((class "post-preview")) (h4 "this") (p "the site this bitch made") (a ((href "/this")) "go! to this page")) (div ((class "post-preview")) (h4 "about") (p "about the bitch who made this site") (a ((href "/about")) "go! to about page")))
|
|
@ -1 +0,0 @@
|
||||||
'(article (hgroup (h1 "stuff what's tagged like #about") (p (em "everything (or maybe just some things) i've ever said about \"about\""))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "now") (p "what the author of this site is up to") (a ((href "/now")) "go! to now page")) (div ((class "post-preview")) (h4 "contact") (p "how to talk to sorrel") (a ((href "/contact")) "go! to contact page")) (div ((class "post-preview")) (h4 "disclaimer") (p "a very earnest disclaimer") (a ((href "/very-earnest-disclaimer")) "go! to disclaimer page")) (div ((class "post-preview")) (h4 "this") (p "the site this bitch made") (a ((href "/this")) "go! to this page")) (div ((class "post-preview")) (h4 "about") (p "the bitch who made this site") (a ((href "/about")) "go! to about page")))
|
|
1
source/tagged/conlang.scm
Normal file
1
source/tagged/conlang.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#conlang")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#conlang")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "latl-primitives") (p "designing the primitives to be provided by latl") (a ((href "/unsettled/latl-primitives")) "go! to latl-primitives page")) (div ((class "post-preview")) (h4 "feature-change-applier") (p "a first attempt at a conlanging tool") (a ((href "/settled/1")) "go! to feature-change-applier page")) (div ((class "post-preview")) (h4 "beginning latl") (p "beginning the process of thinking through an environment for conlanging and other language shenanigans") (a ((href "/unsettled/1")) "go! to beginning latl page")))
|
1
source/tagged/diary.scm
Normal file
1
source/tagged/diary.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#diary")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#diary")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "notes from rc") (p "dispatches from the edge of my abilities") (a ((href "/unsettled/notes-from-rc")) "go! to notes from rc page")))
|
1
source/tagged/index.scm
Normal file
1
source/tagged/index.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "all the tags") (p (em "a categorical mess for your perusal"))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "about") (p "posts about about") (a ((href "/tagged/about")) "go! to about page")) (div ((class "post-preview")) (h4 "latl") (p "posts about latl") (a ((href "/tagged/latl")) "go! to latl page")) (div ((class "post-preview")) (h4 "conlang") (p "posts about conlang") (a ((href "/tagged/conlang")) "go! to conlang page")) (div ((class "post-preview")) (h4 "programming-language") (p "posts about programming-language") (a ((href "/tagged/programming-language")) "go! to programming-language page")) (div ((class "post-preview")) (h4 "tool") (p "posts about tool") (a ((href "/tagged/tool")) "go! to tool page")) (div ((class "post-preview")) (h4 "linguistics") (p "posts about linguistics") (a ((href "/tagged/linguistics")) "go! to linguistics page")) (div ((class "post-preview")) (h4 "rc") (p "posts about rc") (a ((href "/tagged/rc")) "go! to rc page")) (div ((class "post-preview")) (h4 "uf-library") (p "posts about uf-library") (a ((href "/tagged/uf-library")) "go! to uf-library page")) (div ((class "post-preview")) (h4 "diary") (p "posts about diary") (a ((href "/tagged/diary")) "go! to diary page")) (div ((class "post-preview")) (h4 "library") (p "posts about library") (a ((href "/tagged/library")) "go! to library page")))
|
|
@ -1 +0,0 @@
|
||||||
'(article (hgroup (h1 "all the tags") (p (em "a categorical mess for your perusal"))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "about") (p "posts about about") (a ((href "/tagged/about")) "go! to about page")))
|
|
1
source/tagged/latl.scm
Normal file
1
source/tagged/latl.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#latl")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#latl")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "latl-primitives_what-is-language") (p "thinking about language from the perspective of latl") (a ((href "/unsettled/latl-primitives_what-is-language")) "go! to latl-primitives_what-is-language page")) (div ((class "post-preview")) (h4 "latl-primitives") (p "designing the primitives to be provided by latl") (a ((href "/unsettled/latl-primitives")) "go! to latl-primitives page")) (div ((class "post-preview")) (h4 "beginning latl") (p "beginning the process of thinking through an environment for conlanging and other language shenanigans") (a ((href "/unsettled/1")) "go! to beginning latl page")))
|
1
source/tagged/library.scm
Normal file
1
source/tagged/library.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#library")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#library")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "pre-introducing uf-library") (p "what if you were a library?") (a ((href "/unsettled/pre-introducing-uf-library")) "go! to pre-introducing uf-library page")))
|
1
source/tagged/linguistics.scm
Normal file
1
source/tagged/linguistics.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#linguistics")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#linguistics")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "latl-primitives_what-is-language") (p "thinking about language from the perspective of latl") (a ((href "/unsettled/latl-primitives_what-is-language")) "go! to latl-primitives_what-is-language page")))
|
1
source/tagged/programming-language.scm
Normal file
1
source/tagged/programming-language.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#programming-language")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#programming-language")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "latl-primitives") (p "designing the primitives to be provided by latl") (a ((href "/unsettled/latl-primitives")) "go! to latl-primitives page")) (div ((class "post-preview")) (h4 "beginning latl") (p "beginning the process of thinking through an environment for conlanging and other language shenanigans") (a ((href "/unsettled/1")) "go! to beginning latl page")))
|
1
source/tagged/rc.scm
Normal file
1
source/tagged/rc.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#rc")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#rc")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "pre-introducing uf-library") (p "what if you were a library?") (a ((href "/unsettled/pre-introducing-uf-library")) "go! to pre-introducing uf-library page")) (div ((class "post-preview")) (h4 "notes from rc") (p "dispatches from the edge of my abilities") (a ((href "/unsettled/notes-from-rc")) "go! to notes from rc page")))
|
1
source/tagged/tool.scm
Normal file
1
source/tagged/tool.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#tool")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#tool")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "feature-change-applier") (p "a first attempt at a conlanging tool") (a ((href "/settled/1")) "go! to feature-change-applier page")))
|
1
source/tagged/uf-library.scm
Normal file
1
source/tagged/uf-library.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "stuff what's tagged like " (em "#uf-library")) (p (em "everything (or maybe just some things) i've ever said about " (strong "#uf-library")))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "pre-introducing uf-library") (p "what if you were a library?") (a ((href "/unsettled/pre-introducing-uf-library")) "go! to pre-introducing uf-library page")) (div ((class "post-preview")) (h4 "notes from rc") (p "dispatches from the edge of my abilities") (a ((href "/unsettled/notes-from-rc")) "go! to notes from rc page")))
|
1
source/this.scm
Normal file
1
source/this.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(body (section (hgroup (h2 "how this site") (p "some kind of colophon")) (p "all of the code for the website is hosted and deployed from tree, " (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net")) "bunk computer club's git forge") "i do almost everything in the main branch, cause it's just me and that way\n i can add links below to the in-progress stuff real easy") (p "first, this website doesn't do anything to know who you are or anything.\n this website is a ~20MB binary and some static resources. it is built\n primarily with " (a ((href "https://docs.racket-lang.org/web-server/")) "racket web-server")) (p "this website serves ~46kB of javascript in the form of " (a ((href "https://htmx.org/")) "the htmx library (minified.)") " i don't love serving minified code. forking the library and removing\n features that are of no use to me is on the agenda for 2024") (p "everything here is hosted on turtle, " (a ((href "https://wiki.bunk.computer/hypha/servers")) "bunk computer club's shared application server")) (p "there's some racket scripts i use for tooling that were made with " (a ((href "https://docs.racket-lang.org/cli/")) "#lang cli")) (p (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/.dev-log")) "you can read about development here")) (p (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/in-progress/.idea-log")) "you can read about my vague plans here")) (p (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/in-progress/in-progress")) "or read works in progress here")) (p "the image in the header is a crop of the work " (em "'Oxalis acetosella', Otto Wilhelm Thomé (1885)") " run through a generation tool on " (a ((href "https://www.asciiart.eu/")) "this art archive"))) (footer (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/source/this.scm")) "view source") (hr) (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2024-01-18T22:19:43")) (p ((class "license-info")) (small (a ((href "static/license/license.txt")) "license")))))
|
|
@ -1 +0,0 @@
|
||||||
(body (section (hgroup (h2 "how this site") (p "some kind of colophon")) (p "all of the code for the website is hosted and deployed from tree, " (a ((href "https://git.bunk.computer/oxaliq/sorrel.dev")) "bunk computer club's git forge") "i do almost everything in the main branch, cause it's just me and that way\n i can add links below to the in-progress stuff real easy") (p "first, this website doesn't do anything to know who you are or anything.\n this website is a ~20MB binary and some static resources. it is built\n primarily with " (a ((href "https://docs.racket-lang.org/web-server/")) "racket web-server")) (p "this website serves ~46kB of javascript in the form of " (a ((href "https://htmx.org/")) "the htmx library (minified.)") " i don't love serving minified code. forking the library and removing\n features that are of no use to me is on the agenda for 2024") (p "everything here is hosted on turtle, " (a ((href "https://wiki.bunk.computer/hypha/servers")) "bunk computer club's shared application server")) (p "there's some racket scripts i use for tooling that were made with " (a ((href "https://docs.racket-lang.org/cli/")) "#lang cli")) (p (a ((href "https://git.bunk.computer/oxaliq/sorrel.dev/src/branch/main/.dev-log")) "you can read about development here")) (p (a ((href "https://git.bunk.computer/oxaliq/sorrel.dev/src/branch/main/.idea-log")) "you can read about my vague plans here")) (p (a ((href "https://git.bunk.computer/oxaliq/sorrel.dev/src/branch/main/in-progress")) "or read works in progress here")) (p "the image in the header is a crop of the work " (em "'Oxalis acetosella', Otto Wilhelm Thomé (1885)") " run through a generation tool on " (a ((href "https://www.asciiart.eu/")) "this ascii art archive"))) (footer (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2023-12-24T19:41:47")) (p ((class "license-info")) (small (a ((href "/license")) "license")))))
|
|
1
source/unsettled/1.scm
Normal file
1
source/unsettled/1.scm
Normal file
File diff suppressed because one or more lines are too long
1
source/unsettled/index.scm
Normal file
1
source/unsettled/index.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(article (hgroup (h1 "unsettled thoughts") (p (em "just doing some thinking aloud"))) (h3 "the thoughts") (div ((class "post-preview")) (h4 "pre-introducing uf-library") (p "what if you were a library?") (a ((href "/unsettled/pre-introducing-uf-library")) "go! to pre-introducing uf-library page")) (div ((class "post-preview")) (h4 "notes from rc") (p "dispatches from the edge of my abilities") (a ((href "/unsettled/notes-from-rc")) "go! to notes from rc page")) (div ((class "post-preview")) (h4 "latl-primitives_what-is-language") (p "thinking about language from the perspective of latl") (a ((href "/unsettled/latl-primitives_what-is-language")) "go! to latl-primitives_what-is-language page")) (div ((class "post-preview")) (h4 "latl-primitives") (p "designing the primitives to be provided by latl") (a ((href "/unsettled/latl-primitives")) "go! to latl-primitives page")) (div ((class "post-preview")) (h4 "beginning latl") (p "beginning the process of thinking through an environment for conlanging and other language shenanigans") (a ((href "/unsettled/1")) "go! to beginning latl page")))
|
|
@ -1 +0,0 @@
|
||||||
'(article (hgroup (h1 "unsettled thoughts") (p (em "just doing some thinking aloud"))) (h3 "the thoughts") (p "there's nothing here yet"))
|
|
1
source/unsettled/latl-primitives.scm
Normal file
1
source/unsettled/latl-primitives.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(body '(article ((id "latl-primitives") (class "composed-article")) (section ((id "intro")) (hgroup (h1 "what must be true of latl primitives") (p (em "what will latl need to " (u "do") " out of the box?"))) (p "i've talked a little about " (a ((href "/unsettled/1")) "conlanging and latl") " previously here. the short version is this: making languages (for theoretical conscious beings) is fun! it's been a consistent hobby and artistic pursuit for me for much of my life. i've had different approaches from making extremely regular languages, to simulating the evolution of a family of spoken languages, to a family of synthesizer languages for a fractured machine society. every language project requires keeping track of a dictionary and a grammar (even if they never become more than quick sketches) and any sufficiently involved project can benefit from tools for generating new words that fit a language's 'phonotactics', generating derived words based on grammatical rules, simulating language change over time. conlanging is a hobby with enough overlap with computation, that some conlangers have created tools for some of these tasks. my own projects have become too ambitious to have my work live in spreadsheets over here and latex files over there and text files with the defintions i provide to web-based tools somewhere else entirely. i want to build on the work of those came before and create a substrate upon which any tool a conlanger needs could be built and in which i can define the entirety of a language in one system.") (p "at it's base latl will be a tool for operating on languages, invented (or otherwise... maybe.) it helps then to think of the sorts of things that encompass language. spoken and signed languages will be the assumed base case, as those are the things real human beings usually use to communicate with each other. the modality of a language needn't be important to the primitives used, but it's always a good practice to state assumptions")) (section ((id "contents")) (ul (li (a ((href "#what-is-language")) "go to what-is-language")) (li (a ((href "#what-conlangers-do")) "go to what-conlangers-do")) (li (a ((href "#proposed-latl-primitives")) "go to proposed-latl-primitives")) (li (a ((href "#signoff")) "go to signoff")))) (section ((id "what-is-language")) (hgroup (h2 "thinking about what language is for a moment")) (a ((href "/unsettled/latl-primitives_what-is-language") (hx-get "/hx/unsettled/latl-primitives_what-is-language") (hx-target "#what-is-language") (hx-swap "outerHTML")) "what-is-language")) (section ((id "what-conlangers-do")) (hgroup (h2 "what conlangers do") (p (em "moving from a pile of language stuff to a pile of problems to solve"))) (p "coming soon")) (section ((id "proposed-latl-primitives")) (hgroup (h2 "introducing the primitives") (p (em "things that definitely need to be present in latl"))) (p "coming soon")) (section ((id "signoff")) (hgroup (h2 "signing off") (p (em "what's next for latl thinking?"))) "coming soon")) (footer (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/source/unsettledlatl-primitives.scm")) "view source") (hr) (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/latl") (hx-get "/hx/tagged/latl") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "latl"))) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/conlang") (hx-get "/hx/tagged/conlang") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "conlang"))) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/programming-language") (hx-get "/hx/tagged/programming-language") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "programming-language"))))) (hr) (p ((class "doc-history")) (small "published: 2024-02-25T21:33:06")) (p ((class "license-info")) (small (a ((href "static/license/license.txt")) "license")))))
|
1
source/unsettled/latl-primitives_what-is-language.scm
Normal file
1
source/unsettled/latl-primitives_what-is-language.scm
Normal file
File diff suppressed because one or more lines are too long
1
source/unsettled/notes-from-rc.scm
Normal file
1
source/unsettled/notes-from-rc.scm
Normal file
File diff suppressed because one or more lines are too long
1
source/unsettled/pre-introducing-uf-library.scm
Normal file
1
source/unsettled/pre-introducing-uf-library.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(body (article ((id "pre-introducing-uf-library")) (hgroup (h1 "pre-introducing uf-library") (p (em "what if you were a library?"))) (section ((id "quick-story")) (h2 "part 1: a quick story") (p "i volunteer at a tool library. it's a scrappy project that technically fits the non-profit designation, but has managed to cultivate a do-it-together ethos. there are numerous working groups devoted to tool maintenance, educational workshops, community outreach, developing an on-site print shop, and much more. and we do it all on a pretty slim budget with almost entirely unpaid labor") (p "i also love physical media. i recently had to pack most of my posessions into storage for a short time and was struck by the high percentage of my belongings that are physical media. (yet, i always feel like i'm not looking hard enough for new stuff to read or listen to!) floating out amongst my friends are probably a dozen books -- some of which i've maybe forgotten the location of -- but i've been increasingly feeling that more of them should be circulating. what if i made my little media collection a library for my friends?")) (section ((id "software")) (h2 "part 2: software") (p "there's some foss library software out there :" (a ((href "https://koha-community.org/")) "koha ils") ", " (a ((href "https://evergreen-ils.org/")) "evergreen ils") ", " (a ((href "https://openbiblio.de/")) "openbiblio") " (and more.) the only tool or 'thing' oriented software i know of are the foss (unfinished) " (a ((href "https://github.com/chicago-tool-library/circulate")) "circulate") " by the chicago tool library and the closed-source " (a ((href "https://myturn.com/")) "myturn") ". i'm not interested in critiquing existing software here, except to say that none of the things i've seen support the kind of library i want to become") (p "i want to be a library amongst libraries. i want my friends and communities to add their collections to the library network and to lend and borrow and restore and maintain more than they ever could as individuals lending and borrowing amongst friends. and i don't care about the distinction between traditional media-library *and* library-of-things/tool-library models. i want library as community platform. i want applied library sciences") (p "wait that wasn't about software. that was about human networking. but the software to represent this kind of social technology doesn't yet exist. and i think it should. and i think it should be as lean and easy to deploy and administer as possible") (p "i don't have the capacity to build this vision at this moment, but i think i can build some of it and build the capacity to build more.\n i'm participating in " (a ((href "https://recurse.com")) "recurse center hacking retreat") " and " (a ((href "/tagged/rc")) "i'm writing about my rc experience") ". that'll be more focused on the 'building my capacity' piece. a lot of that will be about thinking through stuff that doesn't wind up being ultimately implemented. i'll write more " (a ((href "/tagged/uf-library")) "about building library") " separately. (of course there's going to be a lot of interleaving)") (p "the thing to do before hacking next week is to look at the protocols available. (the working-name 'uf-library' is a contraction of 'usufruct', a social-good-oriented property model (can't be giving things latin names tho), but it could also be 'ur-favorite' or 'user-friendly' (what's friendlier than being engaged in community?))")) (section ((id "dreaming")) (h2 "part 3: dreaming") (p "this is an experiment. and kind of a long-shot one at that. i hope that it inspires similar experiments, regardless of the success of this iteration. (there might even already be a project out there that hit on the same idea, however it appears to be abandoned (and a dao))") (p "if this is interesting to you " (a ((href "/contact")) "let's talk about it!") " otherwise, wish me luck :)"))) (footer (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/source/unsettledpre-introducing-uf-library.scm")) "view source") (hr) (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/uf-library") (hx-get "/hx/tagged/uf-library") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "uf-library"))) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/library") (hx-get "/hx/tagged/library") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "library"))) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/rc") (hx-get "/hx/tagged/rc") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "rc"))))) (hr) (p ((class "doc-history")) (small "published: 2024-04-01T13:04:37")) (p ((class "license-info")) (small (a ((href "static/license/license.txt")) "license")))))
|
1
source/very-earnest-disclaimer.scm
Normal file
1
source/very-earnest-disclaimer.scm
Normal file
|
@ -0,0 +1 @@
|
||||||
|
'(body (section (h2 "a very earnest disclaimer") (p "i like to talk about computation with ppl! but it is important for me that\n you know: i am new to all this! i did not think computers or software were\n ^for me^ and then i had to get good at spreadsheets at my first email-factory\n job and then i got curious about webdev and now i have reached terminal\n velocity down a very λ.particular.rabbit[hole]") (p "i think computation is both fascinating on its own terms and as a substrate\n for pro-social infrastructure. i am motivated to work on projects that\n engage with this possiblity") (p "i'm not very good at many things. i don't even have a math education or a\n degree in anything. have you ever met someone who *is* good at _all_ ^this^\n ~stuff~ ???") (p "i like thinking in public, but please be patient! with me and with\n everyone else you talk about things you care about with") (p "let's hold our strong opinions loosely!") (p "and first assume good faith from each other!") (br) (br) (p ((class "ascii but-normal-size")) " ⃔‥̺⃝⃕") (br)) (footer (a ((href "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/source/very-earnest-disclaimer.scm")) "view source") (hr) (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2024-01-18T22:20:50")) (p ((class "license-info")) (small (a ((href "static/license/license.txt")) "license")))))
|
|
@ -1 +0,0 @@
|
||||||
(body (section (h2 "a very earnest disclaimer") (p "i like to talk about computation with ppl! but it is important for me that\n you know: i am new to all this! i did not think computers or software were\n ^for me^ and then i had to get good at spreadsheets at my first email-factory\n job and then i got curious about webdev and now i have reached terminal\n velocity down a very λ.particular.rabbit[hole]") (p "i think computation is both fascinating on its own terms and as a substrate\n for pro-social infrastructure. i am motivated to work on projects that\n engage with this possiblity") (p "i'm not very good at many things. i don't even have a math education or a\n degree in anything. have you ever met someone who *is* good at _all_ ^this^\n ~stuff~ ???") (p "i like thinking in public, but please be patient! with me and with\n everyone else you talk about things you care about with") (p "let's hold our strong opinions loosely!") (p "and first assume good faith from each other!") (br) (br) (p ((class "ascii but-normal-size")) " ⃔‥̺⃝⃕") (br)) (footer (section (h5 "tagged") (ul ((class "tag-list")) (li ((class "tag-item")) (span ((class "hx-target")) (a ((href "/tagged/about") (hx-get "/hx/tagged/about") (hx-target "closest span.hx-target") (hx-swap "innerHTML")) "about"))))) (hr) (p ((class "doc-history")) (small "published: 2023-12-24T19:43:23")) (p ((class "license-info")) (small (a ((href "/license")) "license")))))
|
|
|
@ -1 +0,0 @@
|
||||||
<section><h1>404</h1><p>hey, i couldn't find that. could ya try something else maybe?</p></section>
|
|
BIN
static/img/settled/1/fca.jpg
Normal file
BIN
static/img/settled/1/fca.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
428
static/license/license.txt
Normal file
428
static/license/license.txt
Normal file
|
@ -0,0 +1,428 @@
|
||||||
|
Attribution-ShareAlike 4.0 International
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||||
|
does not provide legal services or legal advice. Distribution of
|
||||||
|
Creative Commons public licenses does not create a lawyer-client or
|
||||||
|
other relationship. Creative Commons makes its licenses and related
|
||||||
|
information available on an "as-is" basis. Creative Commons gives no
|
||||||
|
warranties regarding its licenses, any material licensed under their
|
||||||
|
terms and conditions, or any related information. Creative Commons
|
||||||
|
disclaims all liability for damages resulting from their use to the
|
||||||
|
fullest extent possible.
|
||||||
|
|
||||||
|
Using Creative Commons Public Licenses
|
||||||
|
|
||||||
|
Creative Commons public licenses provide a standard set of terms and
|
||||||
|
conditions that creators and other rights holders may use to share
|
||||||
|
original works of authorship and other material subject to copyright
|
||||||
|
and certain other rights specified in the public license below. The
|
||||||
|
following considerations are for informational purposes only, are not
|
||||||
|
exhaustive, and do not form part of our licenses.
|
||||||
|
|
||||||
|
Considerations for licensors: Our public licenses are
|
||||||
|
intended for use by those authorized to give the public
|
||||||
|
permission to use material in ways otherwise restricted by
|
||||||
|
copyright and certain other rights. Our licenses are
|
||||||
|
irrevocable. Licensors should read and understand the terms
|
||||||
|
and conditions of the license they choose before applying it.
|
||||||
|
Licensors should also secure all rights necessary before
|
||||||
|
applying our licenses so that the public can reuse the
|
||||||
|
material as expected. Licensors should clearly mark any
|
||||||
|
material not subject to the license. This includes other CC-
|
||||||
|
licensed material, or material used under an exception or
|
||||||
|
limitation to copyright. More considerations for licensors:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensors
|
||||||
|
|
||||||
|
Considerations for the public: By using one of our public
|
||||||
|
licenses, a licensor grants the public permission to use the
|
||||||
|
licensed material under specified terms and conditions. If
|
||||||
|
the licensor's permission is not necessary for any reason--for
|
||||||
|
example, because of any applicable exception or limitation to
|
||||||
|
copyright--then that use is not regulated by the license. Our
|
||||||
|
licenses grant only permissions under copyright and certain
|
||||||
|
other rights that a licensor has authority to grant. Use of
|
||||||
|
the licensed material may still be restricted for other
|
||||||
|
reasons, including because others have copyright or other
|
||||||
|
rights in the material. A licensor may make special requests,
|
||||||
|
such as asking that all changes be marked or described.
|
||||||
|
Although not required by our licenses, you are encouraged to
|
||||||
|
respect those requests where reasonable. More considerations
|
||||||
|
for the public:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensees
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Attribution-ShareAlike 4.0 International Public
|
||||||
|
License
|
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree
|
||||||
|
to be bound by the terms and conditions of this Creative Commons
|
||||||
|
Attribution-ShareAlike 4.0 International Public License ("Public
|
||||||
|
License"). To the extent this Public License may be interpreted as a
|
||||||
|
contract, You are granted the Licensed Rights in consideration of Your
|
||||||
|
acceptance of these terms and conditions, and the Licensor grants You
|
||||||
|
such rights in consideration of benefits the Licensor receives from
|
||||||
|
making the Licensed Material available under these terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
|
||||||
|
Section 1 -- Definitions.
|
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar
|
||||||
|
Rights that is derived from or based upon the Licensed Material
|
||||||
|
and in which the Licensed Material is translated, altered,
|
||||||
|
arranged, transformed, or otherwise modified in a manner requiring
|
||||||
|
permission under the Copyright and Similar Rights held by the
|
||||||
|
Licensor. For purposes of this Public License, where the Licensed
|
||||||
|
Material is a musical work, performance, or sound recording,
|
||||||
|
Adapted Material is always produced where the Licensed Material is
|
||||||
|
synched in timed relation with a moving image.
|
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright
|
||||||
|
and Similar Rights in Your contributions to Adapted Material in
|
||||||
|
accordance with the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
c. BY-SA Compatible License means a license listed at
|
||||||
|
creativecommons.org/compatiblelicenses, approved by Creative
|
||||||
|
Commons as essentially the equivalent of this Public License.
|
||||||
|
|
||||||
|
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||||
|
closely related to copyright including, without limitation,
|
||||||
|
performance, broadcast, sound recording, and Sui Generis Database
|
||||||
|
Rights, without regard to how the rights are labeled or
|
||||||
|
categorized. For purposes of this Public License, the rights
|
||||||
|
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||||
|
Rights.
|
||||||
|
|
||||||
|
e. Effective Technological Measures means those measures that, in the
|
||||||
|
absence of proper authority, may not be circumvented under laws
|
||||||
|
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||||
|
Treaty adopted on December 20, 1996, and/or similar international
|
||||||
|
agreements.
|
||||||
|
|
||||||
|
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||||
|
any other exception or limitation to Copyright and Similar Rights
|
||||||
|
that applies to Your use of the Licensed Material.
|
||||||
|
|
||||||
|
g. License Elements means the license attributes listed in the name
|
||||||
|
of a Creative Commons Public License. The License Elements of this
|
||||||
|
Public License are Attribution and ShareAlike.
|
||||||
|
|
||||||
|
h. Licensed Material means the artistic or literary work, database,
|
||||||
|
or other material to which the Licensor applied this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
i. Licensed Rights means the rights granted to You subject to the
|
||||||
|
terms and conditions of this Public License, which are limited to
|
||||||
|
all Copyright and Similar Rights that apply to Your use of the
|
||||||
|
Licensed Material and that the Licensor has authority to license.
|
||||||
|
|
||||||
|
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||||
|
under this Public License.
|
||||||
|
|
||||||
|
k. Share means to provide material to the public by any means or
|
||||||
|
process that requires permission under the Licensed Rights, such
|
||||||
|
as reproduction, public display, public performance, distribution,
|
||||||
|
dissemination, communication, or importation, and to make material
|
||||||
|
available to the public including in ways that members of the
|
||||||
|
public may access the material from a place and at a time
|
||||||
|
individually chosen by them.
|
||||||
|
|
||||||
|
l. Sui Generis Database Rights means rights other than copyright
|
||||||
|
resulting from Directive 96/9/EC of the European Parliament and of
|
||||||
|
the Council of 11 March 1996 on the legal protection of databases,
|
||||||
|
as amended and/or succeeded, as well as other essentially
|
||||||
|
equivalent rights anywhere in the world.
|
||||||
|
|
||||||
|
m. You means the individual or entity exercising the Licensed Rights
|
||||||
|
under this Public License. Your has a corresponding meaning.
|
||||||
|
|
||||||
|
|
||||||
|
Section 2 -- Scope.
|
||||||
|
|
||||||
|
a. License grant.
|
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License,
|
||||||
|
the Licensor hereby grants You a worldwide, royalty-free,
|
||||||
|
non-sublicensable, non-exclusive, irrevocable license to
|
||||||
|
exercise the Licensed Rights in the Licensed Material to:
|
||||||
|
|
||||||
|
a. reproduce and Share the Licensed Material, in whole or
|
||||||
|
in part; and
|
||||||
|
|
||||||
|
b. produce, reproduce, and Share Adapted Material.
|
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||||
|
Exceptions and Limitations apply to Your use, this Public
|
||||||
|
License does not apply, and You do not need to comply with
|
||||||
|
its terms and conditions.
|
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section
|
||||||
|
6(a).
|
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The
|
||||||
|
Licensor authorizes You to exercise the Licensed Rights in
|
||||||
|
all media and formats whether now known or hereafter created,
|
||||||
|
and to make technical modifications necessary to do so. The
|
||||||
|
Licensor waives and/or agrees not to assert any right or
|
||||||
|
authority to forbid You from making technical modifications
|
||||||
|
necessary to exercise the Licensed Rights, including
|
||||||
|
technical modifications necessary to circumvent Effective
|
||||||
|
Technological Measures. For purposes of this Public License,
|
||||||
|
simply making modifications authorized by this Section 2(a)
|
||||||
|
(4) never produces Adapted Material.
|
||||||
|
|
||||||
|
5. Downstream recipients.
|
||||||
|
|
||||||
|
a. Offer from the Licensor -- Licensed Material. Every
|
||||||
|
recipient of the Licensed Material automatically
|
||||||
|
receives an offer from the Licensor to exercise the
|
||||||
|
Licensed Rights under the terms and conditions of this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
b. Additional offer from the Licensor -- Adapted Material.
|
||||||
|
Every recipient of Adapted Material from You
|
||||||
|
automatically receives an offer from the Licensor to
|
||||||
|
exercise the Licensed Rights in the Adapted Material
|
||||||
|
under the conditions of the Adapter's License You apply.
|
||||||
|
|
||||||
|
c. No downstream restrictions. You may not offer or impose
|
||||||
|
any additional or different terms or conditions on, or
|
||||||
|
apply any Effective Technological Measures to, the
|
||||||
|
Licensed Material if doing so restricts exercise of the
|
||||||
|
Licensed Rights by any recipient of the Licensed
|
||||||
|
Material.
|
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or
|
||||||
|
may be construed as permission to assert or imply that You
|
||||||
|
are, or that Your use of the Licensed Material is, connected
|
||||||
|
with, or sponsored, endorsed, or granted official status by,
|
||||||
|
the Licensor or others designated to receive attribution as
|
||||||
|
provided in Section 3(a)(1)(A)(i).
|
||||||
|
|
||||||
|
b. Other rights.
|
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not
|
||||||
|
licensed under this Public License, nor are publicity,
|
||||||
|
privacy, and/or other similar personality rights; however, to
|
||||||
|
the extent possible, the Licensor waives and/or agrees not to
|
||||||
|
assert any such rights held by the Licensor to the limited
|
||||||
|
extent necessary to allow You to exercise the Licensed
|
||||||
|
Rights, but not otherwise.
|
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to
|
||||||
|
collect royalties from You for the exercise of the Licensed
|
||||||
|
Rights, whether directly or through a collecting society
|
||||||
|
under any voluntary or waivable statutory or compulsory
|
||||||
|
licensing scheme. In all other cases the Licensor expressly
|
||||||
|
reserves any right to collect such royalties.
|
||||||
|
|
||||||
|
|
||||||
|
Section 3 -- License Conditions.
|
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the
|
||||||
|
following conditions.
|
||||||
|
|
||||||
|
a. Attribution.
|
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified
|
||||||
|
form), You must:
|
||||||
|
|
||||||
|
a. retain the following if it is supplied by the Licensor
|
||||||
|
with the Licensed Material:
|
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed
|
||||||
|
Material and any others designated to receive
|
||||||
|
attribution, in any reasonable manner requested by
|
||||||
|
the Licensor (including by pseudonym if
|
||||||
|
designated);
|
||||||
|
|
||||||
|
ii. a copyright notice;
|
||||||
|
|
||||||
|
iii. a notice that refers to this Public License;
|
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of
|
||||||
|
warranties;
|
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the
|
||||||
|
extent reasonably practicable;
|
||||||
|
|
||||||
|
b. indicate if You modified the Licensed Material and
|
||||||
|
retain an indication of any previous modifications; and
|
||||||
|
|
||||||
|
c. indicate the Licensed Material is licensed under this
|
||||||
|
Public License, and include the text of, or the URI or
|
||||||
|
hyperlink to, this Public License.
|
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||||
|
reasonable manner based on the medium, means, and context in
|
||||||
|
which You Share the Licensed Material. For example, it may be
|
||||||
|
reasonable to satisfy the conditions by providing a URI or
|
||||||
|
hyperlink to a resource that includes the required
|
||||||
|
information.
|
||||||
|
|
||||||
|
3. If requested by the Licensor, You must remove any of the
|
||||||
|
information required by Section 3(a)(1)(A) to the extent
|
||||||
|
reasonably practicable.
|
||||||
|
|
||||||
|
b. ShareAlike.
|
||||||
|
|
||||||
|
In addition to the conditions in Section 3(a), if You Share
|
||||||
|
Adapted Material You produce, the following conditions also apply.
|
||||||
|
|
||||||
|
1. The Adapter's License You apply must be a Creative Commons
|
||||||
|
license with the same License Elements, this version or
|
||||||
|
later, or a BY-SA Compatible License.
|
||||||
|
|
||||||
|
2. You must include the text of, or the URI or hyperlink to, the
|
||||||
|
Adapter's License You apply. You may satisfy this condition
|
||||||
|
in any reasonable manner based on the medium, means, and
|
||||||
|
context in which You Share Adapted Material.
|
||||||
|
|
||||||
|
3. You may not offer or impose any additional or different terms
|
||||||
|
or conditions on, or apply any Effective Technological
|
||||||
|
Measures to, Adapted Material that restrict exercise of the
|
||||||
|
rights granted under the Adapter's License You apply.
|
||||||
|
|
||||||
|
|
||||||
|
Section 4 -- Sui Generis Database Rights.
|
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that
|
||||||
|
apply to Your use of the Licensed Material:
|
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||||
|
to extract, reuse, reproduce, and Share all or a substantial
|
||||||
|
portion of the contents of the database;
|
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database
|
||||||
|
contents in a database in which You have Sui Generis Database
|
||||||
|
Rights, then the database in which You have Sui Generis Database
|
||||||
|
Rights (but not its individual contents) is Adapted Material,
|
||||||
|
including for purposes of Section 3(b); and
|
||||||
|
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share
|
||||||
|
all or a substantial portion of the contents of the database.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not
|
||||||
|
replace Your obligations under this Public License where the Licensed
|
||||||
|
Rights include other Copyright and Similar Rights.
|
||||||
|
|
||||||
|
|
||||||
|
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||||
|
|
||||||
|
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||||
|
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||||
|
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||||
|
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||||
|
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||||
|
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||||
|
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||||
|
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||||
|
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||||
|
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||||
|
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||||
|
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||||
|
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||||
|
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||||
|
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||||
|
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided
|
||||||
|
above shall be interpreted in a manner that, to the extent
|
||||||
|
possible, most closely approximates an absolute disclaimer and
|
||||||
|
waiver of all liability.
|
||||||
|
|
||||||
|
|
||||||
|
Section 6 -- Term and Termination.
|
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and
|
||||||
|
Similar Rights licensed here. However, if You fail to comply with
|
||||||
|
this Public License, then Your rights under this Public License
|
||||||
|
terminate automatically.
|
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under
|
||||||
|
Section 6(a), it reinstates:
|
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided
|
||||||
|
it is cured within 30 days of Your discovery of the
|
||||||
|
violation; or
|
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||||
|
right the Licensor may have to seek remedies for Your violations
|
||||||
|
of this Public License.
|
||||||
|
|
||||||
|
c. For the avoidance of doubt, the Licensor may also offer the
|
||||||
|
Licensed Material under separate terms or conditions or stop
|
||||||
|
distributing the Licensed Material at any time; however, doing so
|
||||||
|
will not terminate this Public License.
|
||||||
|
|
||||||
|
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 7 -- Other Terms and Conditions.
|
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different
|
||||||
|
terms or conditions communicated by You unless expressly agreed.
|
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the
|
||||||
|
Licensed Material not stated herein are separate from and
|
||||||
|
independent of the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 8 -- Interpretation.
|
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and
|
||||||
|
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||||
|
conditions on any use of the Licensed Material that could lawfully
|
||||||
|
be made without permission under this Public License.
|
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is
|
||||||
|
deemed unenforceable, it shall be automatically reformed to the
|
||||||
|
minimum extent necessary to make it enforceable. If the provision
|
||||||
|
cannot be reformed, it shall be severed from this Public License
|
||||||
|
without affecting the enforceability of the remaining terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no
|
||||||
|
failure to comply consented to unless expressly agreed to by the
|
||||||
|
Licensor.
|
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted
|
||||||
|
as a limitation upon, or waiver of, any privileges and immunities
|
||||||
|
that apply to the Licensor or You, including from the legal
|
||||||
|
processes of any jurisdiction or authority.
|
||||||
|
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons is not a party to its public licenses.
|
||||||
|
Notwithstanding, Creative Commons may elect to apply one of its public
|
||||||
|
licenses to material it publishes and in those instances will be
|
||||||
|
considered the “Licensor.” The text of the Creative Commons public
|
||||||
|
licenses is dedicated to the public domain under the CC0 Public Domain
|
||||||
|
Dedication. Except for the limited purpose of indicating that material
|
||||||
|
is shared under a Creative Commons public license or as otherwise
|
||||||
|
permitted by the Creative Commons policies published at
|
||||||
|
creativecommons.org/policies, Creative Commons does not authorize the
|
||||||
|
use of the trademark "Creative Commons" or any other trademark or logo
|
||||||
|
of Creative Commons without its prior written consent including,
|
||||||
|
without limitation, in connection with any unauthorized modifications
|
||||||
|
to any of its public licenses or any other arrangements,
|
||||||
|
understandings, or agreements concerning use of licensed material. For
|
||||||
|
the avoidance of doubt, this paragraph does not form part of the public
|
||||||
|
licenses.
|
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org.
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta name="ROBOTS" content="NOINDEX, NOFOLLOW"/><title>learning and making things</title><meta name="author" content="sorrel"/><meta name="description" content="yr place for sorrel on the world wide web"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="ascii-art-description" content="it's a crop of the work 'Oxalis acetosella', Otto Wilhelm Thomé
|
|
||||||
(1885) run through the ascii-art generation tool on https://www.asciiart.eu/"/><link rel="stylesheet" href="/static/style/styles.css"/><style>
|
|
||||||
p.ascii {
|
|
||||||
font-family: 'Courier New', Courier, monospace;
|
|
||||||
font-size: 8px;
|
|
||||||
white-space: pre;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
p.ascii.but-normal-size {
|
|
||||||
font-size: medium;
|
|
||||||
}</style><script src="/static/script/htmx.min.js" defer=""></script></head><body><header><div class="banner" hx-get="/hx/home" hx-target="main" hx-swap="innerHTML"><p class="ascii">▒▓░ <a href="/">home</a> ░░▒ ▒▒▓█▒ ░▒
|
|
||||||
░▒▒░▓▓ ▒▒▒▒▒▒▓█ ▒▓
|
|
||||||
▒▒▓▓░▒▓ ▓█▓▓ ░▓
|
|
||||||
▓▒▒ ▒▒ ░
|
|
||||||
▒ ▒▓▒▓▒ ▒░ ▒░
|
|
||||||
░░░░░░▒▒▒▓▒▓░ ░▒ ▒
|
|
||||||
▓░▒▒▒░▒▒▒▒▒▓▓▓▓▓ ░░ ░
|
|
||||||
▒▒░▒▒▒▒▒▒▒▒▓▓▓▓▓▓█ ░░ ░▒
|
|
||||||
▓▒▒▒▒▒▓▒▓▓▓▒▓▓▓▓▓▓ ░▒░░░░░░▒░ ▓▓ ▒
|
|
||||||
▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓█▒▒░░▒░▒░░░░░▒░▒ ▒ ▒▒
|
|
||||||
░▒▒▒▒▒▓▒▓ ▒▓▓▓▓▓▓▓▓▓▓▓█▓░▒▒▒▒░░░░░░░░░░░▒ ▓▒ ░
|
|
||||||
▒░░▒▓▓▒▒▓▓▓▓▒▒▒ ▓▓▓▓▓▓▓▓▓█▓░▒▒▒▒▒░░▒░▒░░░░░░▒▓ █ ░ ▓▓
|
|
||||||
░ ░░▓▒▒ ░ ▓░░░▒▓▒▓▒▓▓▓▓▓▓▓▓▒ ▓▓▒▓▓▓█▓▒▒▒▒░▒░░░░▒░▒░░░░▒░░▒░ ▓ ▓ ▓▒░░░░░▒
|
|
||||||
░ ░▒▓▓ ▓ ▒ ▓░░▒▒▒▓▒▓▓▓▒▓▓▓▓▓▓▓▒ ▓▓▓▓█▓▒▒░▒▒▒▒░▒▒▒░░░░░░░░░░▒▒ ▓ ▒▒▒▒░▒░░▒░▓
|
|
||||||
▒▒▒▓▓▒ ▒░░ ▒▒▒▒▒▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▓▓▓█▒▓▒▒▒▒▒▒░▒▒▒░░▒░▒░░░░█▒ ▒▒▓▒ ▒▒▒▒▒▒░░░▒░░
|
|
||||||
▒▒▓▓░ ░ ▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▒ ▓▓▒▒▒▓▒▒▒▒▒░▒░░░░░░░ ▓▓▒░ ░█▓ ▒▒▒▒▒▒░░░░░░
|
|
||||||
░▓ ▒░▒ ▓▒▓▓▒▓▓▓▓▓▓▓▒▓▓▓▓█▓████▓▒▒▒▒▓▓▓▓▓▓▓▒▒▒▒▒▒▓░ ▓▒ ▓▒▒ █▓▓▓▒▒▒▒░░░░░
|
|
||||||
▒░ ▒▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓█▓█▓▒▒▒▒▓▒▒▒▒ ▓░ ▒▒ ▒▓▓▓▓▓▒▒▒░░░▒
|
|
||||||
▓ ▓ ▓▓▓▓▓▒▓▒▓▓▓▓▓▓▒▒▒▒▒▒▒▓▓ ░▓▓█▓▓▓▓▓▓▓▓▓▒▒▒▓ ░░ ▒█ ░▒▒▒▓▓▓▓▓▒▒▒▒▒
|
|
||||||
░ ▒▓▓▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▓ ▒██▒██▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░ ▓░ ▒▓▓▓▓▒▓▓▒▒▒▒░
|
|
||||||
▒▒▒▒░▒▓ ▒ ▒▓▓▒▒▒▒▒▒▒░▒░░░▒▒▒▒▓ ▒███▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▓▒ ░▒▒▒░▒▓▓▓▓▒▓▒▒▒
|
|
||||||
▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒░▒░░░░░░░░░░░░ ▒██▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▓▒ ░░░░▒░░▒▒▒▒▒▒▒▒▒▒▓
|
|
||||||
▒▒▒▒▒▒▒▒▓▒▓▒░░▒░░░▒░ ▒▒▒▒░░▒░░░░░░░░░▒ ▒▓██▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▒▒ ▓▒▒▒░▒░░▒▒▒▓▓▓▒▒▒▒▓
|
|
||||||
▒▒▒▒▒▒▓▒▓▓▒▒▒▒▒▒▒▒▒▒▒░▓ ▒░░░░░▒░░░░░░░▒▒ ▒▒█▓██▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▒░ ▒▒▒▒▒▒░░▒▒▒▒▓▓▒▓▒ ▒
|
|
||||||
▒▒▒▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ ░░░░░░░░░░░░░░░ ▒▓█▓█▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▒▒░ ▒░░░▒▒▒▒▒▒▒▓▓▒▒▓ ▒░▒
|
|
||||||
▒▒▓▒▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ ░░░░░░░░▒▒░░░ ▒██▓▓▓▓▓█▓▒▓▓▓▓▓▓▒▒▒▒▒▓▒ ░░▒ ▓▒░▒▒▒▒▒▒▒▓▒▒▒ ▒ ▒▒▒
|
|
||||||
▒▒▒▓▓█▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▓▒▒▒ ▓▒░░░░░░░░░▒ ▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒ ▒▒ ▒▒▒▒▒▒▒▓▓▓▒▒░░░░▓▓██
|
|
||||||
▒▓▓▓█▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒ ▓░░░░░▒░▒ ▓▓█▓▓▓▓▓▓▓██▓▓▓▓▓▓▒▒▒▓ ░▒ ▓▓▒▒▓▒▓▒▒░ ▓▓▓▓▓▓█▓
|
|
||||||
▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓ ░▓▓▒ ░░ ▓▓█▓▓▓▓▓▓▓▓██▒▓▒▒▒▒▓▓ ░▒ ▒▓▓ ░██▓▓▓▓▓▓▓▓▓▓
|
|
||||||
▓▓▓█▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▓ ▒ ░░ ▓▓█▓▓▓▓▓▓▓▓▓▓▒▒ ▒ ░▓ ░ ▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
|
||||||
▓▓▓▒▓▒▒▒▒▓▒▒▒▒▓ ▒▒░ ▒▓▓▓▓▓▓▓▓▓█▓ ▓▒ ░ ░ ░▒ ░░ ▒ █▓▓▓▓▓▓▓▓▓▓▓▓▓
|
|
||||||
███▒▒▒▒▒▓░ ▒▓░░ ▒▓▓▓▓▓▓▓▓ ▓▒░ ▒░ ░▒ ░ ▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
|
||||||
█▒▓▓ ▒▒▓▓▓▓▓▓▓▒ ▒░▓ ▒▒▓▓▓▓▓▒ ▒▒░ ▒ ▒▒ ▒ ░▓▓▓▓▓▓▓▓▓▓
|
|
||||||
░▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▓ ▓░ ░▓▒ ░▒░▒ ▓▒ ▓ ▒ ▓▓▓▓░
|
|
||||||
░▓▒▓▓▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▓▒▓ ░░▓ ▒▒░ ▒ ▓░ ▒
|
|
||||||
▓▒░ ▓▒▒▒█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒ ▒░ ▓▒▓ ▒▒ ▒ ░
|
|
||||||
░▒▓ ▓▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▓▒▒▒ ▒░▓ ░▒░▒ ░░
|
|
||||||
▒▓ ░▒▒▒▒▒▓▒▒▓▒▒▒▒▒▒▒▒▒▒▓▒▓▓▓▒▒ ▓░ ░▒ ░▓ </p></div><nav><a href="/about" hx-get="/hx/about" hx-target="main" hx-swap="innerHTML">about sorrel (the bitch who made this)</a><a href="/unsettled" hx-get="/hx/unsettled" hx-target="main" hx-swap="innerHTML">unsettled thoughts (something like a blog)</a><a href="/settled" hx-get="/hx/settled" hx-target="main" hx-swap="innerHTML">"settled" thoughts (projects built/in progress)</a><a href="/feed.atom">þͤ olde rss</a></nav></header><main aria-live="polite"><article><noscript><span class="noscript"><p>hey! yr not letting yr browser execute javascript served by my page.</p><p>that's cool!</p><p>browser (by google?) as arbitrary code execution platform is one of the
|
|
||||||
weird, regrettable (at least as it is currently implemented)
|
|
||||||
consequences of our political economy.</p><p>anyway, feel free to browse! yr experience won't be much different,
|
|
||||||
you'll just get bigger html blob.</p><p>the only js i deliver is <a href="https://htmx.org">this little REST tool called htmx</a> if you want to see what that's about.</p><p>o! and if you want to hear/read <a href="/tagged/javascript">what i have to say about javascript</a> you could do that maybe</p><p>/noscript</p></span></noscript><p>hey! i'm sorrel.</p><p>(called like the plant up there)</p><p>this is my new-fangled website computer page on the world wide web. i had
|
|
||||||
a nice time building this little thing <span class="hx-target"><a href="/this" hx-get="/hx/this" hx-target="closest span" hx-swap="innerHTML">(how i build this little page.)</a></span></p><p> i hope you have a nice time looking at things here.</p><p class="ascii but-normal-size">︿︿
|
|
||||||
〰</p></article></main></body></html>
|
|
|
@ -1,48 +0,0 @@
|
||||||
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta name="ROBOTS" content="NOINDEX, NOFOLLOW"/><title>learning and making things</title><meta name="author" content="sorrel"/><meta name="description" content="yr place for sorrel on the world wide web"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="ascii-art-description" content="it's a crop of the work 'Oxalis acetosella', Otto Wilhelm Thomé
|
|
||||||
(1885) run through the ascii-art generation tool on https://www.asciiart.eu/"/><link rel="stylesheet" href="/static/style/styles.css"/><style>
|
|
||||||
p.ascii {
|
|
||||||
font-family: 'Courier New', Courier, monospace;
|
|
||||||
font-size: 8px;
|
|
||||||
white-space: pre;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
p.ascii.but-normal-size {
|
|
||||||
font-size: medium;
|
|
||||||
}</style><script src="/static/script/htmx.min.js" defer=""></script></head><body><header><div class="banner" hx-get="/hx/home" hx-target="main" hx-swap="innerHTML"><p class="ascii">▒▓░ <a href="/">home</a> ░░▒ ▒▒▓█▒ ░▒
|
|
||||||
░▒▒░▓▓ ▒▒▒▒▒▒▓█ ▒▓
|
|
||||||
▒▒▓▓░▒▓ ▓█▓▓ ░▓
|
|
||||||
▓▒▒ ▒▒ ░
|
|
||||||
▒ ▒▓▒▓▒ ▒░ ▒░
|
|
||||||
░░░░░░▒▒▒▓▒▓░ ░▒ ▒
|
|
||||||
▓░▒▒▒░▒▒▒▒▒▓▓▓▓▓ ░░ ░
|
|
||||||
▒▒░▒▒▒▒▒▒▒▒▓▓▓▓▓▓█ ░░ ░▒
|
|
||||||
▓▒▒▒▒▒▓▒▓▓▓▒▓▓▓▓▓▓ ░▒░░░░░░▒░ ▓▓ ▒
|
|
||||||
▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓█▒▒░░▒░▒░░░░░▒░▒ ▒ ▒▒
|
|
||||||
░▒▒▒▒▒▓▒▓ ▒▓▓▓▓▓▓▓▓▓▓▓█▓░▒▒▒▒░░░░░░░░░░░▒ ▓▒ ░
|
|
||||||
▒░░▒▓▓▒▒▓▓▓▓▒▒▒ ▓▓▓▓▓▓▓▓▓█▓░▒▒▒▒▒░░▒░▒░░░░░░▒▓ █ ░ ▓▓
|
|
||||||
░ ░░▓▒▒ ░ ▓░░░▒▓▒▓▒▓▓▓▓▓▓▓▓▒ ▓▓▒▓▓▓█▓▒▒▒▒░▒░░░░▒░▒░░░░▒░░▒░ ▓ ▓ ▓▒░░░░░▒
|
|
||||||
░ ░▒▓▓ ▓ ▒ ▓░░▒▒▒▓▒▓▓▓▒▓▓▓▓▓▓▓▒ ▓▓▓▓█▓▒▒░▒▒▒▒░▒▒▒░░░░░░░░░░▒▒ ▓ ▒▒▒▒░▒░░▒░▓
|
|
||||||
▒▒▒▓▓▒ ▒░░ ▒▒▒▒▒▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▓▓▓█▒▓▒▒▒▒▒▒░▒▒▒░░▒░▒░░░░█▒ ▒▒▓▒ ▒▒▒▒▒▒░░░▒░░
|
|
||||||
▒▒▓▓░ ░ ▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▒ ▓▓▒▒▒▓▒▒▒▒▒░▒░░░░░░░ ▓▓▒░ ░█▓ ▒▒▒▒▒▒░░░░░░
|
|
||||||
░▓ ▒░▒ ▓▒▓▓▒▓▓▓▓▓▓▓▒▓▓▓▓█▓████▓▒▒▒▒▓▓▓▓▓▓▓▒▒▒▒▒▒▓░ ▓▒ ▓▒▒ █▓▓▓▒▒▒▒░░░░░
|
|
||||||
▒░ ▒▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓█▓█▓▒▒▒▒▓▒▒▒▒ ▓░ ▒▒ ▒▓▓▓▓▓▒▒▒░░░▒
|
|
||||||
▓ ▓ ▓▓▓▓▓▒▓▒▓▓▓▓▓▓▒▒▒▒▒▒▒▓▓ ░▓▓█▓▓▓▓▓▓▓▓▓▒▒▒▓ ░░ ▒█ ░▒▒▒▓▓▓▓▓▒▒▒▒▒
|
|
||||||
░ ▒▓▓▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▓ ▒██▒██▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░ ▓░ ▒▓▓▓▓▒▓▓▒▒▒▒░
|
|
||||||
▒▒▒▒░▒▓ ▒ ▒▓▓▒▒▒▒▒▒▒░▒░░░▒▒▒▒▓ ▒███▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▓▒ ░▒▒▒░▒▓▓▓▓▒▓▒▒▒
|
|
||||||
▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒░▒░░░░░░░░░░░░ ▒██▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▓▒ ░░░░▒░░▒▒▒▒▒▒▒▒▒▒▓
|
|
||||||
▒▒▒▒▒▒▒▒▓▒▓▒░░▒░░░▒░ ▒▒▒▒░░▒░░░░░░░░░▒ ▒▓██▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▒▒ ▓▒▒▒░▒░░▒▒▒▓▓▓▒▒▒▒▓
|
|
||||||
▒▒▒▒▒▒▓▒▓▓▒▒▒▒▒▒▒▒▒▒▒░▓ ▒░░░░░▒░░░░░░░▒▒ ▒▒█▓██▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▒░ ▒▒▒▒▒▒░░▒▒▒▒▓▓▒▓▒ ▒
|
|
||||||
▒▒▒▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ ░░░░░░░░░░░░░░░ ▒▓█▓█▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▒▒░ ▒░░░▒▒▒▒▒▒▒▓▓▒▒▓ ▒░▒
|
|
||||||
▒▒▓▒▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ ░░░░░░░░▒▒░░░ ▒██▓▓▓▓▓█▓▒▓▓▓▓▓▓▒▒▒▒▒▓▒ ░░▒ ▓▒░▒▒▒▒▒▒▒▓▒▒▒ ▒ ▒▒▒
|
|
||||||
▒▒▒▓▓█▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▓▒▒▒ ▓▒░░░░░░░░░▒ ▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒ ▒▒ ▒▒▒▒▒▒▒▓▓▓▒▒░░░░▓▓██
|
|
||||||
▒▓▓▓█▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒ ▓░░░░░▒░▒ ▓▓█▓▓▓▓▓▓▓██▓▓▓▓▓▓▒▒▒▓ ░▒ ▓▓▒▒▓▒▓▒▒░ ▓▓▓▓▓▓█▓
|
|
||||||
▒▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓ ░▓▓▒ ░░ ▓▓█▓▓▓▓▓▓▓▓██▒▓▒▒▒▒▓▓ ░▒ ▒▓▓ ░██▓▓▓▓▓▓▓▓▓▓
|
|
||||||
▓▓▓█▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▓ ▒ ░░ ▓▓█▓▓▓▓▓▓▓▓▓▓▒▒ ▒ ░▓ ░ ▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
|
||||||
▓▓▓▒▓▒▒▒▒▓▒▒▒▒▓ ▒▒░ ▒▓▓▓▓▓▓▓▓▓█▓ ▓▒ ░ ░ ░▒ ░░ ▒ █▓▓▓▓▓▓▓▓▓▓▓▓▓
|
|
||||||
███▒▒▒▒▒▓░ ▒▓░░ ▒▓▓▓▓▓▓▓▓ ▓▒░ ▒░ ░▒ ░ ▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓
|
|
||||||
█▒▓▓ ▒▒▓▓▓▓▓▓▓▒ ▒░▓ ▒▒▓▓▓▓▓▒ ▒▒░ ▒ ▒▒ ▒ ░▓▓▓▓▓▓▓▓▓▓
|
|
||||||
░▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▓ ▓░ ░▓▒ ░▒░▒ ▓▒ ▓ ▒ ▓▓▓▓░
|
|
||||||
░▓▒▓▓▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▓▒▓ ░░▓ ▒▒░ ▒ ▓░ ▒
|
|
||||||
▓▒░ ▓▒▒▒█▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒ ▒░ ▓▒▓ ▒▒ ▒ ░
|
|
||||||
░▒▓ ▓▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▓▒▒▒ ▒░▓ ░▒░▒ ░░
|
|
||||||
▒▓ ░▒▒▒▒▒▓▒▒▓▒▒▒▒▒▒▒▒▒▒▓▒▓▓▓▒▒ ▓░ ░▒ ░▓ </p></div><nav><a href="/about" hx-get="/hx/about" hx-target="main" hx-swap="innerHTML">about sorrel (the bitch who made this)</a><a href="/unsettled" hx-get="/hx/unsettled" hx-target="main" hx-swap="innerHTML">unsettled thoughts (something like a blog)</a><a href="/settled" hx-get="/hx/settled" hx-target="main" hx-swap="innerHTML">"settled" thoughts (projects built/in progress)</a><a href="/feed.atom">þͤ olde rss</a></nav></header><main aria-live="polite"><section><h1>404</h1><p>hey, i couldn't find that. could ya try something else maybe?</p></section></main></body></html>
|
|
|
@ -9,21 +9,24 @@
|
||||||
--link-color: lab(80 40 100);
|
--link-color: lab(80 40 100);
|
||||||
--visited-link-color: lab(70 10 15);
|
--visited-link-color: lab(70 10 15);
|
||||||
--banner-ascii-color: lab(90 -40 20 / 0.8);
|
--banner-ascii-color: lab(90 -40 20 / 0.8);
|
||||||
|
--banner-background-color: lab(0 5 1 / 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (prefers-color-scheme: light) {
|
@media screen and (prefers-color-scheme: light) {
|
||||||
html {
|
html {
|
||||||
--foreground-color: lab(10 50 -80);
|
--foreground-color: lab(10 90 -90);
|
||||||
--background-color: lab(90 50 -30);
|
--background-color: lab(90 50 -30);
|
||||||
--link-color: lab(20 40 100);
|
--link-color: lab(20 30 -20);
|
||||||
--visited-link-color: lab(20 10 15);
|
--visited-link-color: lab(20 90 -90);
|
||||||
--banner-ascii-color: lab(10 -40 20 / 0.8);
|
--banner-ascii-color: lab(10 -40 20 / 0.8);
|
||||||
|
--banner-background-color: lab(90 -15 20 / 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
|
overflow-wrap: break-word;
|
||||||
color: var(--foreground-color);
|
color: var(--foreground-color);
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
}
|
}
|
||||||
|
@ -32,33 +35,47 @@ h1, h2, h3, h4, h5 {
|
||||||
font-family: 'Courier New', Courier, monospace;
|
font-family: 'Courier New', Courier, monospace;
|
||||||
color: var(--background-color);
|
color: var(--background-color);
|
||||||
background-color: var(--visited-link-color);
|
background-color: var(--visited-link-color);
|
||||||
padding: 2 10;
|
padding: 2px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h5 {
|
h5 {
|
||||||
margin: 2 0;
|
margin: 2px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.noscript p {
|
div.noscript p {
|
||||||
font-family: 'Courier New', Courier, monospace;
|
font-family: 'Courier New', Courier, monospace;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.hx-target section {
|
div.hx-target section {
|
||||||
border: solid 1px var(--link-color);
|
border: solid 1px var(--link-color);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 0 10;
|
padding: 5px 10px;
|
||||||
margin: 3;
|
margin: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.hx-target footer {
|
div.hx-target footer {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
article.composed-article footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
margin-top: 1em;
|
||||||
|
border-color: var(--visited-link-color);
|
||||||
|
border-top-width: 6px;
|
||||||
|
border-top-style: double;
|
||||||
|
padding-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
font-family: 'Courier New', Courier, monospace;
|
font-family: 'Courier New', Courier, monospace;
|
||||||
font-size: small;
|
font-size: small;
|
||||||
color: var(--link-color);
|
color: var(--link-color);
|
||||||
|
position: relative;
|
||||||
|
top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:visited {
|
a:visited {
|
||||||
|
@ -66,8 +83,27 @@ a:visited {
|
||||||
text-decoration-color: var(--link-color);
|
text-decoration-color: var(--link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:not(.ascii a):not(a[hx-get*="hx"]):not(a[href*="#"])::before {
|
||||||
|
content: ". -> .";
|
||||||
|
font-weight: 900;
|
||||||
|
display: inline-block;
|
||||||
|
padding-right: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[href*="#"] {
|
||||||
|
content: "↓";
|
||||||
|
font-weight: 900;
|
||||||
|
font-size: larger;
|
||||||
|
display: inline-block;
|
||||||
|
padding-right: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[rel="me"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
max-width: 600;
|
max-width: 600px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
font-size: medium;
|
font-size: medium;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
@ -97,9 +133,9 @@ header{
|
||||||
}
|
}
|
||||||
|
|
||||||
div.banner {
|
div.banner {
|
||||||
background-color: lab(0 5 1 / 0.8);
|
|
||||||
width: max-content;
|
width: max-content;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
background-color: var(--banner-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.banner p.ascii {
|
div.banner p.ascii {
|
||||||
|
@ -117,19 +153,29 @@ nav a {
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 12 0;
|
margin: 12px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.tag-list {
|
ul.tag-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
margin: 6 0;
|
flex-wrap: wrap;
|
||||||
padding: 0;
|
margin: 6px 0px;
|
||||||
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.tag-item {
|
li.tag-item {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
flex-basis: fit-content;
|
flex-basis: fit-content;
|
||||||
margin: 0 6;
|
margin: 0px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 96%;
|
||||||
|
margin: 2%;
|
||||||
|
border-color: var(--foreground-color);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 2px;
|
||||||
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
67
utils.rkt
Normal file
67
utils.rkt
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#lang racket
|
||||||
|
(provide (all-defined-out))
|
||||||
|
|
||||||
|
(require (only-in racket/list flatten add-between)
|
||||||
|
(only-in xml xexpr->string))
|
||||||
|
|
||||||
|
|
||||||
|
(define homepage "https://oxaliq.net")
|
||||||
|
(define git-forge "https://git.bunk.computer/oxaliq/oxaliq.net/src/branch/main/")
|
||||||
|
|
||||||
|
(define (source-url resource-type resource-id)
|
||||||
|
(~a git-forge
|
||||||
|
(if (equal? resource-type "root")
|
||||||
|
"source/"
|
||||||
|
(~a "source/" resource-type))
|
||||||
|
resource-id ".scm"))
|
||||||
|
|
||||||
|
;; takes a parsed table as a list of lists and formats for writing as a .csv file
|
||||||
|
(define (list->csv l)
|
||||||
|
(foldl (lambda (i res)
|
||||||
|
(string-append res i))
|
||||||
|
""
|
||||||
|
(flatten
|
||||||
|
(add-between (map (lambda (row)
|
||||||
|
(add-between row ","))
|
||||||
|
l)
|
||||||
|
"\n"))))
|
||||||
|
|
||||||
|
;; construct resource-link for use in atom feed
|
||||||
|
(define (resource-link resource-type resource-id #:homepage (hp homepage))
|
||||||
|
(if (equal? resource-type "root")
|
||||||
|
(build-path hp (~a resource-id))
|
||||||
|
(build-path hp resource-type (~a resource-id))))
|
||||||
|
|
||||||
|
(define (archive-file input-file test #:modify-mode (exists-ok #f))
|
||||||
|
(if test
|
||||||
|
(copy-file input-file (string-replace input-file "in-progress" "publish-test/archive") #t)
|
||||||
|
(rename-file-or-directory input-file (string-replace input-file "in-progress" "archive") exists-ok)))
|
||||||
|
|
||||||
|
|
||||||
|
;; atom-table utils
|
||||||
|
;; ----------------
|
||||||
|
;; atom-table-entry constructs new row to pass to add-atom-entry
|
||||||
|
(define (atom-table-entry headline resource-link desc publish-time #:update-time (update-time ""))
|
||||||
|
(list headline (~a resource-link) desc publish-time update-time))
|
||||||
|
|
||||||
|
;; add-atom-entry takes old atom table and new row, constructing new
|
||||||
|
;; atom table with only first 21 rows (or all rows)
|
||||||
|
(define (add-atom-entry atom-table new-row)
|
||||||
|
;; insert new-row after header
|
||||||
|
(let ([out-length (min (+ 1 (length atom-table)) 21)]
|
||||||
|
[header (first atom-table)]
|
||||||
|
[old-content (rest atom-table)])
|
||||||
|
(take (append (list header new-row) old-content)
|
||||||
|
out-length)))
|
||||||
|
;; ----------------
|
||||||
|
|
||||||
|
;; atom-feed utils
|
||||||
|
;; ---------------
|
||||||
|
(define (make-feed ns make-atom-input-port atom-table publish-time #:homepage (hp homepage))
|
||||||
|
(string-append "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||||
|
(xexpr->string ((eval (read make-atom-input-port) ns)
|
||||||
|
"https://oxaliq.net/feed.atom"
|
||||||
|
publish-time
|
||||||
|
hp
|
||||||
|
(rest atom-table)))))
|
||||||
|
;; ---------------
|
Loading…
Reference in a new issue