Compare commits

..

2 commits

92 changed files with 653 additions and 2726 deletions

View file

@ -1,87 +1,22 @@
2024/01/21
- .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)
24/12/2023
- published about sections
TODO:
- refactor publish script for atomic, idempotent execution (follow
rollback thunk + compose accumulator pattern in modify script)
- modify publish script to ensure rollback on failure
- create update script to publish updates to existing posts
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
21/12/2023
- broke "about" into smaller sections and linked from "/"
- removed "about" from header - now just [settled | unsettled | feed]
- added "now" and "this" sections and linked from "/"
2023/12/10
10/12/2023
- added resource/index builder to publish script
2023/12/04
4/12/2023
- 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
2023/11/30
30/11/2023
- added function to build an index source xexpr file for tagged/
- have not tested to see if it builds tagged/ properly yet

3
.gitignore vendored
View file

@ -3,6 +3,5 @@
sorrel/**
deploy-dir/**
tool/**
static/**/**.html
publish-test/**
todo.txt
compiled/**

View file

@ -1,43 +1,12 @@
IDEAS in progress
----- - - - - - -
- root/links
- unsettled/latl-primitives
24/12/2023
- posted:
- this
- now
- about
- contact
- very-earnest-disclaimer
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
21/12/2023
- beginning latl effectively finished and ready for post once ci is fixed
- projects to write about
- input-messenger

View file

@ -1,32 +0,0 @@
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

View file

@ -1,48 +0,0 @@
#!/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

9
Dockerfile Normal file
View file

@ -0,0 +1,9 @@
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
View file

@ -1,662 +0,0 @@
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
View file

@ -1,6 +1,6 @@
--------------
| λ oxaliq.net |\
| λ sorrel.dev |\
\--------------\ \
\______________\|
@ -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
(snippets of html), and plain `/` (for rendering full pages.) handlers build the
content from the little sexpr .scm files (they're not valid racket on they're own,
content from the little sexpr .txt 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
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.
@ -105,33 +105,5 @@ there's a couple things this'll do.
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

View file

@ -8,7 +8,8 @@
"a plant called sorrel")
" and i live in the mountains of southern appalachia on "
(span ((lang "chr")) "ᏣᎳᎩ")
" (tsalagi/cherokee) land")
" (tsalagi/cherokee) land. i live with some cats and a whole mess of plants
(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
past few years, that i do like to orchestrate computer machines and i do
@ -41,13 +42,7 @@
"language (computer) to make languages (human)"))))
;; mmt bullet
(li (p "mmt, but make it anarchist "
(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"))
(small "and get rid of all that \"sovereignty\" stuff, ew")))
;; neuroqueer bullet
(li (p "got a spicy brained, trans lady-fied experience.
i have feelings about these things that inevitably weave thru

View file

@ -1,6 +0,0 @@
(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"))

12
archive/contact.txt Normal file
View file

@ -0,0 +1,12 @@
(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"))

View file

@ -1,100 +0,0 @@
(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!")))

View file

@ -1,55 +0,0 @@
'(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"))

View file

@ -1,60 +0,0 @@
(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 ""))

View file

@ -1,44 +0,0 @@
(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
)

View file

@ -1,34 +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 "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"))))

39
archive/now.txt Normal file
View file

@ -0,0 +1,39 @@
(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?"))))

View file

@ -1,35 +0,0 @@
(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 :)")))

View file

@ -4,7 +4,7 @@
(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"))
(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
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 "
(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"))
(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/oxaliq.net/src/branch/in-progress/.idea-log"))
(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/oxaliq.net/src/branch/in-progress/in-progress"))
(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 art archive")))
"this ascii art archive")))

13
build.sh Executable file
View file

@ -0,0 +1,13 @@
#!/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

View file

@ -1,15 +1,8 @@
title,link,summary,published,updated
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
pre-introducing uf-library,https://oxaliq.net/unsettled/pre-introducing-uf-library,what if you were a library?,2024-04-01T13:04:37,
notes from rc,https://oxaliq.net/unsettled/notes-from-rc,dispatches from the edge of my abilities,2024-04-01T13:02:09,
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://oxaliq.net/about,about the bitch who made this site,2024-01-18T21:56:45,2024-03-23T16:29:13
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,
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,
now,https://sorrel.dev/now,what the author of this site is up to,2023-12-24T19:45:57
contact,https://sorrel.dev/contact,how to talk to sorrel,2023-12-24T19:45:11
disclaimer,https://sorrel.dev/very-earnest-disclaimer,a very earnest disclaimer,2023-12-24T19:43:23
this,https://sorrel.dev/this,the site this bitch made,2023-12-24T19:41:47
about,https://sorrel.dev/about,the bitch who made this site,2023-12-24T19:15:34
about,https://sorrel.dev/about,the bitch who made this site,2023-12-24T19:11:35
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

1 title title,link,summary,published,updated link summary published updated
2 notes from rc now,https://sorrel.dev/now,what the author of this site is up to,2023-12-24T19:45:57 https://oxaliq.net/unsettled/notes-from-rc dispatches from the edge of my abilities 2024-04-01T13:02:09 2024-04-05T13:48:39
3 pre-introducing uf-library contact,https://sorrel.dev/contact,how to talk to sorrel,2023-12-24T19:45:11 https://oxaliq.net/unsettled/pre-introducing-uf-library what if you were a library? 2024-04-01T13:04:37
4 notes from rc disclaimer,https://sorrel.dev/very-earnest-disclaimer,a very earnest disclaimer,2023-12-24T19:43:23 https://oxaliq.net/unsettled/notes-from-rc dispatches from the edge of my abilities 2024-04-01T13:02:09
5 now this,https://sorrel.dev/this,the site this bitch made,2023-12-24T19:41:47 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
6 about about,https://sorrel.dev/about,the bitch who made this site,2023-12-24T19:15:34 https://oxaliq.net/about about the bitch who made this site 2024-01-18T21:56:45 2024-03-23T16:29:13
7 latl-primitives_what-is-language about,https://sorrel.dev/about,the bitch who made this site,2023-12-24T19:11:35 https://oxaliq.net/unsettled/latl-primitives_what-is-language thinking about language from the perspective of latl 2024-02-25T21:36:03
8 latl-primitives 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 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

View file

@ -2,7 +2,7 @@
(let ([feed
`(feed
((xmlns "http://www.w3.org/2005/Atom"))
(title "λ.oxaliq.net")
(title "λ.sorrel.dev")
(link ((rel "self")
(href ,feed-ref)))
(updated ,update-time)

View file

@ -1,6 +1,6 @@
id,headline,description,history->
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 me,2024-01-18T22:21:26
very-earnest-disclaimer,very earnest disclaimer,being earnest in the streets,2024-01-18T22:20:50
this,this,the site this bitch made,2024-01-18T22:19:43
about,about,about the bitch who made this site,2024-03-23T16:29:13,2024-01-18T21:56:45
now,now,what the author of this site is up to,2023-12-24T19:45:57
contact,contact,how to talk to sorrel,2023-12-24T19:45:11
very-earnest-disclaimer,disclaimer,a very earnest disclaimer,2023-12-24T19:43:23
this,this,the site this bitch made,2023-12-24T19:41:47
about,about,the bitch who made this site,2023-12-24T19:15:34

1 id,headline,description,history-> id headline description history->
2 now,now,what the author of this site is up to (not computer things),2024-03-23T16:29:58,2024-01-18T22:22:03 now now what the author of this site is up to 2023-12-24T19:45:57
3 contact,contact,how to talk to me,2024-01-18T22:21:26 contact contact how to talk to sorrel 2023-12-24T19:45:11
4 very-earnest-disclaimer,very earnest disclaimer,being earnest in the streets,2024-01-18T22:20:50 very-earnest-disclaimer disclaimer a very earnest disclaimer 2023-12-24T19:43:23
5 this,this,the site this bitch made,2024-01-18T22:19:43 this this the site this bitch made 2023-12-24T19:41:47
6 about,about,about the bitch who made this site,2024-03-23T16:29:13,2024-01-18T21:56:45 about about the bitch who made this site 2023-12-24T19:15:34

View file

@ -1,2 +1 @@
id,headline,description,history->
1,feature-change-applier,a first attempt at a conlanging tool,2024-01-25T16:26:10
1 id headline description history->
1 feature-change-applier a first attempt at a conlanging tool 2024-01-25T16:26:10

View file

@ -1,11 +1,2 @@
tags,->
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 tags,->
2 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

View file

@ -1,6 +1,2 @@
id,headline,description,history->
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
1,Beginning LATL,beginning the process of thinking through an environment for conlanging and other language shenanigans,2023-12-04T15:20:53
1 id,headline,description,history-> id headline description history->
2 pre-introducing-uf-library,pre-introducing uf-library,what if you were a library?,2024-04-01T13:04:37 1 Beginning LATL beginning the process of thinking through an environment for conlanging and other language shenanigans 2023-12-04T15:20:53
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 Executable file
View file

@ -0,0 +1,17 @@
#!/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

View file

@ -65,7 +65,7 @@
for a multi-purpose conlanging tool that was beginning to take shape in my head")
(p "i tried anyway")
(p "and i made "
(a ((href "/settled/1"))
(a ((href "settled/1"))
"a bad first draft of a sound change tool"))
(p
"there's an e-bnf grammar in that project somewhere! the hubris i
@ -123,14 +123,14 @@
(hr))
(p
"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, to build
toy versions of before it gets time for larger prototyping and
building a workable tool. so, here's the very start of the
thinking-in-public. each of these little thoughts is going to get
at least it's own writeup (if not several) and i'll update with
additional sections and links to the writeups as i go. a note: it
would be impossible for me (and probably most ppl) to create the
full vision in the time i'll be working on it fulltime")
to read up on, to explore, to think and talk through, before it
gets time to prototyping and to building a workable tool. so,
here's the very start of the thinking-in-public. each of these
little thoughts is going to get at least it's own writeup (if not
several) and i'll update with additional sections and links to
the writeups as i go. a note: it would be impossible for me (and
probably most ppl) to create the full vision in the time i'll be
working on it fulltime")
(section
(h3 "notes on the goals")
(p

View file

@ -1,12 +0,0 @@
(section
((id "proposed-latl-primitives"))
(hgroup
(h2 "")
(p (em "")))
(p "")
(section
((id ""))
(hgroup
(h3 "")
(p (em "")))
(p "")))

View file

@ -1,11 +0,0 @@
(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")))
""))

View file

@ -1,397 +0,0 @@
#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)

View file

@ -1,256 +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)))
;; 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))

View file

@ -5,12 +5,13 @@
(only-in racket/format ~a)
(only-in racket/list append* first second third fourth fifth rest flatten add-between take)
(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)
(define-namespace-anchor anc)
(define ns (namespace-anchor->namespace anc))
(define homepage "https://sorrel.dev")
;; publish needs to:
@ -20,15 +21,15 @@
;; - update a read-table for resource type
;; - update the atom feed
;; - update the atom.txt feed
;; - move the original input file
;; example
;; publish -input-file in-progress/beginning-latl..scm --resource-type unsettled --tags latl,conlang \
;; publish -input-file in-progress/beginning-latl.txt --resource-type unsettled --tags latl,conlang \
;; --headline "Beginning LATL" --description "beginning the process of thinking through an environment \
;; for conlanging and other language shenanigans"
;; publish -i in-progress/beginning-latl.scm -r unsettled -t latl,conlang -l "Beginning LATL" \
;; publish -i in-progress/beginning-latl.txt -r unsettled -t latl,conlang -l "Beginning LATL" \
;; -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."))
@ -73,37 +74,44 @@
(let ([l (eval (read (open-input-file "tag-lookup.rkt")))])
(print l)))
(define (append-post-footer post-xexpr s-url tag-list history-list)
(define (append-post-footer post-xexpr tag-list history-list)
(let ([post-footer
(read (open-input-file "source/post-footer.scm"))])
(read (open-input-file "source/post-footer.txt"))])
`(body
,post-xexpr
,((eval post-footer ns) s-url tag-list history-list))))
,((eval post-footer ns) tag-list history-list))))
(define (make-output-file-handle x-test r-type #:headline [l-headline ""] #:res-id [r-id 0])
(define (make-root-file-handle x l)
(if (non-empty-string? l)
(path->string (path-add-extension (build-path (if x "publish-test/source" "source")
(string-replace l " " "-"))
".scm"))
".txt"))
(error "'root resource requires headline")))
(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))
".scm")))
".txt"))
(error "~a resource requires r-id" r)))
(if (equal? r-type "root")
(make-root-file-handle x-test l-headline)
(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])
(displayln "write-new-tagged/index")
(let* ([tags (rest (map (lambda (row) (first row))
tag-table))]
[make-index (read (open-input-file "source/make-index.scm"))]
[make-index (read (open-input-file "source/make-index.txt"))]
[new-index ((eval make-index ns) "tagged" tags)]
[handle (path-add-extension (if x
(build-path "publish-test" "source" "tagged" "index")
(build-path "source" "tagged" "index"))
".scm")]
".txt")]
[file (open-output-file handle #:exists 'replace)])
(if (port-try-file-lock? file 'exclusive)
(begin
@ -142,15 +150,15 @@
[resources (make-weak-hash)]
[posts (map (lambda (lookup/id)
(if (hash-has-key? post-lookup lookup/id)
(append (list lookup/id) (rest (hash-ref post-lookup lookup/id)))
(append (list lookup/id) (rest (get-post-data lookup/id resources post-lookup x)))))
(hash-ref post-lookup lookup/id)
(get-post-data lookup/id resources post-lookup x)))
(filter non-empty-string? (rest tag-table-row)))]
[make-index (read (open-input-file "source/make-index.scm"))]
[make-index (read (open-input-file "source/make-index.txt"))]
[new-index ((eval make-index ns) (~a "tagged/" tag) posts)]
[handle (path-add-extension (if x
(build-path "publish-test" "source" "tagged" (first tag-table-row))
(build-path "source" "tagged" tag))
#".scm")]
#".txt")]
[file (open-output-file handle #:exists 'replace)])
(if (port-try-file-lock? file 'exclusive)
(begin
@ -162,12 +170,12 @@
(define (write-new-resource/index resource resource-table #:test [x #f])
(displayln "write-new-resource/index")
(let* ([make-index (read (open-input-file "source/make-index.scm"))]
(let* ([make-index (read (open-input-file "source/make-index.txt"))]
[new-index ((eval make-index ns) resource (rest resource-table))]
[handle (path-add-extension (if x
(build-path "publish-test" "source" resource "index")
(build-path "source" resource "index"))
#".scm")]
#".txt")]
[file (open-output-file handle #:exists 'replace)])
(if (port-try-file-lock? file 'exclusive)
(begin
@ -176,6 +184,17 @@
(close-output-port 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)
(let ([file (open-output-file handle #:exists 'replace)])
@ -203,6 +222,15 @@
tag-list)
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
(publish)
@ -223,7 +251,9 @@
(build-path "data" r))
#".csv"))))
(define res-id (string-replace l " " "-"))
(define res-id (if (equal? r "root")
(string-replace l " " "-")
(length res-table)))
;; before anything else, open output file
;; doing this means that if a file exists of the intended
(define out
@ -236,7 +266,6 @@
(define resource (append-post-footer (read (open-input-file i))
(source-url r res-id)
t
(list publish-time)))
@ -251,7 +280,6 @@
;; update tag table
(displayln "updating tag table")
(define tag-table (csv->list (open-input-file
(if x "publish-test/data/tagged.csv" "data/tagged.csv"))))
(define new-tag-table (write-new-tag-table tag-table t r res-id))
@ -261,11 +289,11 @@
(if x
(write-new-tagged/index new-tag-table #:test #t)
(write-new-tagged/index new-tag-table)))
; (displayln new-tag-table)
(write-csv-to-file (list->csv new-tag-table)
(if x "publish-test/data/tagged.csv" "data/tagged.csv"))
(displayln "updating tagged/'tag")
;; update tagged/'tag for each tag
(for-each
(lambda (tt-row)
@ -280,23 +308,21 @@
'())))
new-tag-table)
(displayln "writing resource to file")
;; write to file
(if (port-try-file-lock? out 'exclusive)
(begin
(print resource out)
(write resource out)
(port-file-unlock out)
(close-output-port out))
(error "couldn't obtain file lock on ~a" out))
;; update 'resource/index
(if (equal? r "root")
(displayln "skipping resource/index")
(begin
(displayln "updating resource/index")
(write-new-resource/index r new-res-table #:test (if x #t #f))))
(displayln "updating feed table")
;; update 'resource/index (unless root)
(if (equal? r "root")
(displayln "skipping write-new-resource/index")
(write-new-resource/index r new-res-table #:test (if x #t #f)))
;; update feed table
(define atom-table (csv->list
(open-input-file
@ -306,28 +332,29 @@
(build-path "data" "atom"))
#".csv"))))
(define new-atom-table
(add-atom-entry atom-table (atom-table-entry l (~a res-link) d publish-time)))
(add-atom-entry atom-table (list l (~a res-link) d publish-time)))
(write-csv-to-file (list->csv new-atom-table)
(if x "publish-test/data/atom.csv" "data/atom.csv"))
;; update feed.atom
;; for now, this does not include the html for the post, only a link
(displayln "updating feed")
(define feed ((eval (read (open-input-file (if x
"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
(open-output-file (if x "publish-test/source/feed.atom"
"source/feed.atom")
;; need to remove this and just replace once testing is done
#:exists 'replace ))
#:exists 'replace))
(if (port-try-file-lock? feed-out 'exclusive)
(begin
(display
(make-feed ns (open-input-file
(if x
"publish-test/data/make-atom.scm"
"data/make-atom.scm"))
new-atom-table
publish-time)
(string-append "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
(xexpr->string feed))
feed-out)
(port-file-unlock feed-out)
(close-output-port feed-out))

174
sorrel.dev.rkt Normal file
View file

@ -0,0 +1,174 @@
#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))

View file

@ -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") (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
source/about.txt Normal file
View 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. 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")))))

25
source/atom.txt Normal file
View file

@ -0,0 +1,25 @@
(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))
))

View file

@ -1,48 +0,0 @@
(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!"))

View file

@ -1 +0,0 @@
'(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
source/contact.txt Normal file
View file

@ -0,0 +1 @@
(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

View file

@ -1,9 +1,6 @@
(head
(meta ((http-equiv "Content-Type")
(content "text/html; charset=utf-8")))
(meta ((name "ROBOTS")
(content "NOINDEX, NOFOLLOW")))
(title "oxaliq.net - learning and making")
(meta ((name "author")
(content "sorrel")))
(meta ((name "description")

View file

@ -1,11 +1,4 @@
(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
((class "banner")
(hx-get "/hx/home")

View file

@ -1,78 +0,0 @@
(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"))
"︿︿
"))

68
source/index.txt Normal file
View file

@ -0,0 +1,68 @@
(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"))
"︿︿
〰"))

2
source/license.txt Normal file
View file

@ -0,0 +1,2 @@
(article
(p "no licensing info yet. this is a real big question."))

View file

@ -14,8 +14,8 @@
(p (em "a categorical mess for your perusal")))]
[(string-prefix? res "tagged/")
(let ([tag (string-replace res "tagged/" "#")])
`(hgroup (h1 "stuff what's tagged like " (em ,tag))
(p (em "everything (or maybe just some things) i've ever said about " (strong ,tag)))))]
`(hgroup (h1 ,(~a "stuff what's tagged like " tag))
(p (em (~a "everything (or maybe just some things) i've ever said about \"" tag "\"")))))]
[else
'(hgroup (h1 "i'm lost")
(p (em "you weren't meant to be here")))])

View file

@ -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 "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
source/now.txt Normal file
View 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 "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")))))

View file

@ -1,9 +1,6 @@
(lambda (source-url tag-list history-list)
(lambda (tag-list history-list)
(let ([class-sec `(ul ((class "tag-list")))])
`(footer
(a ((href ,source-url))
"view source")
(hr)
(section
(h5 "tagged")
,(begin
@ -38,5 +35,5 @@
((class "license-info"))
(small
(a
((href "static/license/license.txt"))
((href "/license"))
"license"))))))

34
source/root/index.txt Normal file
View file

@ -0,0 +1,34 @@
(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"))
"︿︿
〰"))

View file

@ -0,0 +1,3 @@
(section
(h1 "404")
(p "hey, i couldn't find that. could ya try something else maybe?"))

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
'(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
source/settled/index.txt Normal file
View file

@ -0,0 +1 @@
'(article (hgroup (h1 "settled* thoughts") (p (em "*-ish, something like a portfolio of projects"))) (h3 "the thoughts") (p "there's nothing here yet"))

View file

@ -1 +0,0 @@
'(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
source/tagged/about.txt Normal file
View file

@ -0,0 +1 @@
'(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")))

View file

@ -1 +0,0 @@
'(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")))

View file

@ -1 +0,0 @@
'(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")))

View file

@ -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")) (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
source/tagged/index.txt Normal file
View 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")))

View file

@ -1 +0,0 @@
'(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")))

View file

@ -1 +0,0 @@
'(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")))

View file

@ -1 +0,0 @@
'(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")))

View file

@ -1 +0,0 @@
'(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")))

View file

@ -1 +0,0 @@
'(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")))

View file

@ -1 +0,0 @@
'(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")))

View file

@ -1 +0,0 @@
'(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")))

View file

@ -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/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
source/this.txt Normal file
View 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/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")))))

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
'(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")))

View file

@ -0,0 +1 @@
'(article (hgroup (h1 "unsettled thoughts") (p (em "just doing some thinking aloud"))) (h3 "the thoughts") (p "there's nothing here yet"))

View file

@ -1 +0,0 @@
'(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")))))

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
'(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")))))

View file

@ -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 (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")))))

View 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 (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")))))

View file

@ -0,0 +1 @@
<section><h1>404</h1><p>hey, i couldn't find that. could ya try something else maybe?</p></section>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View file

@ -1,428 +0,0 @@
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.

View file

@ -0,0 +1,53 @@
<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>

View file

@ -0,0 +1,48 @@
<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>

View file

@ -9,24 +9,21 @@
--link-color: lab(80 40 100);
--visited-link-color: lab(70 10 15);
--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) {
html {
--foreground-color: lab(10 90 -90);
--foreground-color: lab(10 50 -80);
--background-color: lab(90 50 -30);
--link-color: lab(20 30 -20);
--visited-link-color: lab(20 90 -90);
--link-color: lab(20 40 100);
--visited-link-color: lab(20 10 15);
--banner-ascii-color: lab(10 -40 20 / 0.8);
--banner-background-color: lab(90 -15 20 / 0.6);
}
}
html {
padding: 20px;
overflow-wrap: break-word;
color: var(--foreground-color);
background-color: var(--background-color);
}
@ -35,47 +32,33 @@ h1, h2, h3, h4, h5 {
font-family: 'Courier New', Courier, monospace;
color: var(--background-color);
background-color: var(--visited-link-color);
padding: 2px 10px;
padding: 2 10;
}
h5 {
margin: 2px 0px;
margin: 2 0;
}
div.noscript p {
span.noscript p {
font-family: 'Courier New', Courier, monospace;
font-size: small;
}
div.hx-target section {
span.hx-target section {
border: solid 1px var(--link-color);
border-radius: 4px;
padding: 5px 10px;
margin: 3px;
padding: 0 10;
margin: 3;
}
div.hx-target footer {
span.hx-target footer {
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 {
font-family: 'Courier New', Courier, monospace;
font-size: small;
color: var(--link-color);
position: relative;
top: -2px;
}
a:visited {
@ -83,27 +66,8 @@ a:visited {
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 {
max-width: 600px;
max-width: 600;
margin: auto;
font-size: medium;
font-family: sans-serif;
@ -133,9 +97,9 @@ header{
}
div.banner {
background-color: lab(0 5 1 / 0.8);
width: max-content;
margin: auto;
background-color: var(--banner-background-color);
}
div.banner p.ascii {
@ -153,29 +117,19 @@ nav a {
}
p {
margin: 12px 0px;
margin: 12 0;
}
ul.tag-list {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 6px 0px;
padding: 0px;
margin: 6 0;
padding: 0;
}
li.tag-item {
list-style-type: none;
flex-basis: fit-content;
margin: 0px 6px;
}
img {
width: 96%;
margin: 2%;
border-color: var(--foreground-color);
border-style: solid;
border-width: 2px;
border-radius: 2px;
margin: 0 6;
}

View file

@ -1,67 +0,0 @@
#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)))))
;; ---------------