Compare commits
23 Commits
v1.5.3
...
a086565ede
| Author | SHA1 | Date | |
|---|---|---|---|
| a086565ede | |||
| 79bc467bf6 | |||
| 8a5fa202de | |||
| c8df9a3da9 | |||
| b8e6c3afa8 | |||
| 3105c83290 | |||
| 206d9a650d | |||
| 105dce7d40 | |||
| 21dc56aa6d | |||
| 7df5daaa6c | |||
| 4f74dd5fe0 | |||
| 0751849492 | |||
| 009877ae76 | |||
| 69bd5832e7 | |||
| b525a5f1c2 | |||
| 2a03859390 | |||
| b65c4c6665 | |||
| 90d8e25b70 | |||
| 8814c12480 | |||
| 0c0f249226 | |||
| b29a5274e1 | |||
| 00f4bbb5f0 | |||
| 7fe204f9f9 |
14
.gitattributes
vendored
Normal file
14
.gitattributes
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
|
*.sh text eol=lf
|
||||||
|
*.awk text eol=lf
|
||||||
|
*.css text eol=lf
|
||||||
|
*.html text eol=lf
|
||||||
|
*.js text eol=lf
|
||||||
|
*.md text eol=lf
|
||||||
|
*.conf text eol=lf
|
||||||
|
*.json text eol=lf
|
||||||
|
*.xml text eol=lf
|
||||||
|
*.png binary
|
||||||
|
*.gif binary
|
||||||
|
*.svg text eol=lf
|
||||||
|
*.ico binary
|
||||||
43
.gitea/workflows/deploy-website.yml
Normal file
43
.gitea/workflows/deploy-website.yml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
name: Deploy Website
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy-website:
|
||||||
|
runs-on: local
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Ensure deploy tools are available
|
||||||
|
run: |
|
||||||
|
if ! command -v ssh >/dev/null 2>&1 || ! command -v rsync >/dev/null 2>&1 || ! command -v ssh-keyscan >/dev/null 2>&1; then
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y openssh-client rsync
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Build website
|
||||||
|
run: |
|
||||||
|
sh kewt.sh --from site --to out
|
||||||
|
|
||||||
|
- name: Setup SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
printf '%s\n' "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
|
||||||
|
REMOTE_HOST_VAL="${{ secrets.REMOTE_HOST }}"
|
||||||
|
REMOTE_ADDR=$(printf '%s\n' "$REMOTE_HOST_VAL" | awk -F@ '{print $NF}')
|
||||||
|
|
||||||
|
ssh-keyscan -H "$REMOTE_ADDR" >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
- name: Deploy website
|
||||||
|
run: |
|
||||||
|
rsync -rlz --delete --omit-dir-times \
|
||||||
|
--exclude '/logs/' \
|
||||||
|
-e "ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no" \
|
||||||
|
out/ "${{ secrets.REMOTE_HOST }}:/var/www/kewt.krzak.org/"
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
name: Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main, master]
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
shellcheck:
|
|
||||||
runs-on: local
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Install Shellcheck
|
|
||||||
run: sudo apt-get update && sudo apt-get install -y shellcheck
|
|
||||||
- name: Run Shellcheck
|
|
||||||
run: shellcheck -s sh kewt.sh markdown.sh tools/build-standalone.sh || true
|
|
||||||
@@ -16,10 +16,10 @@ jobs:
|
|||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Arch Linux environment
|
- name: Ensure publish tools are available
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y pacman-package-manager curl jq || true
|
sudo apt-get install -y openssh-client git
|
||||||
|
|
||||||
- name: Prepare AUR files
|
- name: Prepare AUR files
|
||||||
run: |
|
run: |
|
||||||
@@ -27,12 +27,23 @@ jobs:
|
|||||||
cp packaging/AUR/PKGBUILD.git aur-work/PKGBUILD
|
cp packaging/AUR/PKGBUILD.git aur-work/PKGBUILD
|
||||||
cp packaging/AUR/.SRCINFO.git aur-work/.SRCINFO
|
cp packaging/AUR/.SRCINFO.git aur-work/.SRCINFO
|
||||||
|
|
||||||
|
- name: Setup SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
printf '%s\n' "${{ secrets.AUR_SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan -H aur.archlinux.org >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
- name: Publish to AUR
|
- name: Publish to AUR
|
||||||
uses: KSXGitHub/github-actions-deploy-aur@v3.0.1
|
run: |
|
||||||
with:
|
rm -rf aur-repo
|
||||||
pkgname: kewt-git
|
git clone "ssh://aur@aur.archlinux.org/kewt-git.git" aur-repo
|
||||||
pkgbuild: ./aur-work/PKGBUILD
|
cp aur-work/PKGBUILD aur-repo/PKGBUILD
|
||||||
commit_username: ${{ github.actor }}
|
cp aur-work/.SRCINFO aur-repo/.SRCINFO
|
||||||
commit_email: ${{ github.actor }}@users.noreply.github.com
|
|
||||||
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
cd aur-repo
|
||||||
commit_message: "Update kewt-git to ${{ github.sha }}"
|
git config user.name "${{ github.actor }}"
|
||||||
|
git config user.email "${{ github.actor }}@users.noreply.github.com"
|
||||||
|
git add PKGBUILD .SRCINFO
|
||||||
|
git commit -m "Update kewt-git to ${GITHUB_SHA}" || exit 0
|
||||||
|
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes" git push origin HEAD:master
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ jobs:
|
|||||||
- name: Setup Arch Linux environment
|
- name: Setup Arch Linux environment
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y pacman-package-manager curl jq || true
|
sudo apt-get install -y openssh-client curl jq
|
||||||
|
|
||||||
- name: Render PKGBUILD and SRCINFO
|
- name: Render PKGBUILD and SRCINFO
|
||||||
run: |
|
run: |
|
||||||
@@ -95,15 +95,26 @@ jobs:
|
|||||||
-e "s/SHA256SUM_PLACEHOLDER/${CHECKSUM}/g" \
|
-e "s/SHA256SUM_PLACEHOLDER/${CHECKSUM}/g" \
|
||||||
packaging/AUR/.SRCINFO.template > aur-work/.SRCINFO
|
packaging/AUR/.SRCINFO.template > aur-work/.SRCINFO
|
||||||
|
|
||||||
|
- name: Setup AUR SSH
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
printf '%s\n' "${{ secrets.AUR_SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan -H aur.archlinux.org >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
- name: Publish to AUR
|
- name: Publish to AUR
|
||||||
uses: KSXGitHub/github-actions-deploy-aur@v3.0.1
|
run: |
|
||||||
with:
|
rm -rf aur-repo
|
||||||
pkgname: kewt-bin
|
git clone "ssh://aur@aur.archlinux.org/kewt-bin.git" aur-repo
|
||||||
pkgbuild: ./aur-work/PKGBUILD
|
cp aur-work/PKGBUILD aur-repo/PKGBUILD
|
||||||
commit_username: ${{ github.actor }}
|
cp aur-work/.SRCINFO aur-repo/.SRCINFO
|
||||||
commit_email: ${{ github.actor }}@users.noreply.github.com
|
|
||||||
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
|
cd aur-repo
|
||||||
commit_message: "Update kewt-bin to ${{ github.ref_name }}"
|
git config user.name "${{ github.actor }}"
|
||||||
|
git config user.email "${{ github.actor }}@users.noreply.github.com"
|
||||||
|
git add PKGBUILD .SRCINFO
|
||||||
|
git commit -m "Update kewt-bin to ${GITHUB_REF_NAME}" || exit 0
|
||||||
|
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes" git push origin HEAD:master
|
||||||
|
|
||||||
publish-homebrew:
|
publish-homebrew:
|
||||||
runs-on: local
|
runs-on: local
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -1,5 +1,6 @@
|
|||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
BINDIR = $(PREFIX)/bin
|
BINDIR = $(PREFIX)/bin
|
||||||
|
ZSHCOMPDIR ?= $(PREFIX)/share/zsh/site-functions
|
||||||
|
|
||||||
all: kewt
|
all: kewt
|
||||||
|
|
||||||
@@ -9,9 +10,12 @@ kewt:
|
|||||||
install: kewt
|
install: kewt
|
||||||
install -d $(DESTDIR)$(BINDIR)
|
install -d $(DESTDIR)$(BINDIR)
|
||||||
install -m 755 kewt $(DESTDIR)$(BINDIR)/kewt
|
install -m 755 kewt $(DESTDIR)$(BINDIR)/kewt
|
||||||
|
install -d $(DESTDIR)$(ZSHCOMPDIR)
|
||||||
|
install -m 644 packaging/zsh/_kewt $(DESTDIR)$(ZSHCOMPDIR)/_kewt
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(DESTDIR)$(BINDIR)/kewt
|
rm -f $(DESTDIR)$(BINDIR)/kewt
|
||||||
|
rm -f $(DESTDIR)$(ZSHCOMPDIR)/_kewt
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f kewt
|
rm -f kewt
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ BEGIN {
|
|||||||
if ($0 ~ /^<pre>/) {
|
if ($0 ~ /^<pre>/) {
|
||||||
if (!in_pre) in_pre = 1
|
if (!in_pre) in_pre = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_pre && $0 ~ /^:[ \t]+[^ \t]/) {
|
if (!in_pre && $0 ~ /^:[ \t]+[^ \t]/) {
|
||||||
if (!in_dl) {
|
if (!in_dl) {
|
||||||
in_dl = 1
|
in_dl = 1
|
||||||
@@ -24,7 +24,7 @@ BEGIN {
|
|||||||
def_text = $0
|
def_text = $0
|
||||||
sub(/^:[ \t]+/, "", def_text)
|
sub(/^:[ \t]+/, "", def_text)
|
||||||
print "<dd>" def_text "</dd>"
|
print "<dd>" def_text "</dd>"
|
||||||
|
|
||||||
if ($0 ~ /<\/pre>/) {
|
if ($0 ~ /<\/pre>/) {
|
||||||
if (in_pre) in_pre = 0
|
if (in_pre) in_pre = 0
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ BEGIN {
|
|||||||
prev_line = $0
|
prev_line = $0
|
||||||
has_prev = 1
|
has_prev = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($0 ~ /<\/pre>/) {
|
if ($0 ~ /<\/pre>/) {
|
||||||
if (in_pre) in_pre = 0
|
if (in_pre) in_pre = 0
|
||||||
}
|
}
|
||||||
|
|||||||
854
awk/emoji.awk
854
awk/emoji.awk
@@ -1,831 +1,15 @@
|
|||||||
BEGIN {
|
BEGIN {
|
||||||
map[":+1:"] = "👍"
|
if (emoji_file == "") {
|
||||||
map[":100:"] = "💯"
|
emoji_file = "emoji.tsv"
|
||||||
map[":1234:"] = "🔢"
|
}
|
||||||
map[":8ball:"] = "🎱"
|
|
||||||
map[":a:"] = "🅰️"
|
while ((getline line < emoji_file) > 0) {
|
||||||
map[":ab:"] = "🆎"
|
split(line, parts, "\t")
|
||||||
map[":abc:"] = "🔤"
|
if (length(parts[1]) > 0) {
|
||||||
map[":abcd:"] = "🔡"
|
map[parts[1]] = parts[2]
|
||||||
map[":accept:"] = "🉑"
|
}
|
||||||
map[":aerial_tramway:"] = "🚡"
|
}
|
||||||
map[":airplane:"] = "✈️"
|
close(emoji_file)
|
||||||
map[":alarm_clock:"] = "⏰"
|
|
||||||
map[":alien:"] = "👽"
|
|
||||||
map[":ambulance:"] = "🚑"
|
|
||||||
map[":anchor:"] = "⚓"
|
|
||||||
map[":angel:"] = "👼"
|
|
||||||
map[":anger:"] = "💢"
|
|
||||||
map[":angry:"] = "😠"
|
|
||||||
map[":anguished:"] = "😧"
|
|
||||||
map[":ant:"] = "🐜"
|
|
||||||
map[":apple:"] = "🍎"
|
|
||||||
map[":aquarius:"] = "♒"
|
|
||||||
map[":aries:"] = "♈"
|
|
||||||
map[":arrow_backward:"] = "◀️"
|
|
||||||
map[":arrow_double_down:"] = "⏬"
|
|
||||||
map[":arrow_double_up:"] = "⏫"
|
|
||||||
map[":arrow_down:"] = "⬇️"
|
|
||||||
map[":arrow_down_small:"] = "🔽"
|
|
||||||
map[":arrow_forward:"] = "▶️"
|
|
||||||
map[":arrow_heading_down:"] = "⤵️"
|
|
||||||
map[":arrow_heading_up:"] = "⤴️"
|
|
||||||
map[":arrow_left:"] = "⬅️"
|
|
||||||
map[":arrow_lower_left:"] = "↙️"
|
|
||||||
map[":arrow_lower_right:"] = "↘️"
|
|
||||||
map[":arrow_right:"] = "➡️"
|
|
||||||
map[":arrow_right_hook:"] = "↪️"
|
|
||||||
map[":arrow_up:"] = "⬆️"
|
|
||||||
map[":arrow_up_down:"] = "↕️"
|
|
||||||
map[":arrow_up_small:"] = "🔼"
|
|
||||||
map[":arrow_upper_left:"] = "↖️"
|
|
||||||
map[":arrow_upper_right:"] = "↗️"
|
|
||||||
map[":arrows_clockwise:"] = "🔃"
|
|
||||||
map[":arrows_counterclockwise:"] = "🔄"
|
|
||||||
map[":art:"] = "🎨"
|
|
||||||
map[":articulated_lorry:"] = "🚛"
|
|
||||||
map[":astonished:"] = "😲"
|
|
||||||
map[":atm:"] = "🏧"
|
|
||||||
map[":b:"] = "🅱️"
|
|
||||||
map[":baby:"] = "👶"
|
|
||||||
map[":baby_bottle:"] = "🍼"
|
|
||||||
map[":baby_chick:"] = "🐤"
|
|
||||||
map[":baby_symbol:"] = "🚼"
|
|
||||||
map[":baggage_claim:"] = "🛄"
|
|
||||||
map[":balloon:"] = "🎈"
|
|
||||||
map[":ballot_box_with_check:"] = "☑️"
|
|
||||||
map[":bamboo:"] = "🎍"
|
|
||||||
map[":banana:"] = "🍌"
|
|
||||||
map[":bangbang:"] = "‼️"
|
|
||||||
map[":bank:"] = "🏦"
|
|
||||||
map[":bar_chart:"] = "📊"
|
|
||||||
map[":barber:"] = "💈"
|
|
||||||
map[":baseball:"] = "⚾"
|
|
||||||
map[":basketball:"] = "🏀"
|
|
||||||
map[":bath:"] = "🛀"
|
|
||||||
map[":bathtub:"] = "🛁"
|
|
||||||
map[":battery:"] = "🔋"
|
|
||||||
map[":bear:"] = "🐻"
|
|
||||||
map[":beer:"] = "🍺"
|
|
||||||
map[":beers:"] = "🍻"
|
|
||||||
map[":beetle:"] = "🪲"
|
|
||||||
map[":beginner:"] = "🔰"
|
|
||||||
map[":bell:"] = "🔔"
|
|
||||||
map[":bento:"] = "🍱"
|
|
||||||
map[":bicyclist:"] = "🚴"
|
|
||||||
map[":bike:"] = "🚲"
|
|
||||||
map[":bikini:"] = "👙"
|
|
||||||
map[":bird:"] = "🐦"
|
|
||||||
map[":birthday:"] = "🎂"
|
|
||||||
map[":black_circle:"] = "⚫"
|
|
||||||
map[":black_joker:"] = "🃏"
|
|
||||||
map[":black_nib:"] = "✒️"
|
|
||||||
map[":black_square_button:"] = "🔲"
|
|
||||||
map[":blossom:"] = "🌼"
|
|
||||||
map[":blowfish:"] = "🐡"
|
|
||||||
map[":blue_book:"] = "📘"
|
|
||||||
map[":blue_car:"] = "🚙"
|
|
||||||
map[":blue_heart:"] = "💙"
|
|
||||||
map[":blush:"] = "😊"
|
|
||||||
map[":boar:"] = "🐗"
|
|
||||||
map[":boat:"] = "⛵"
|
|
||||||
map[":bomb:"] = "💣"
|
|
||||||
map[":book:"] = "📖"
|
|
||||||
map[":bookmark:"] = "🔖"
|
|
||||||
map[":bookmark_tabs:"] = "📑"
|
|
||||||
map[":books:"] = "📚"
|
|
||||||
map[":boom:"] = "💥"
|
|
||||||
map[":boot:"] = "👢"
|
|
||||||
map[":bouquet:"] = "💐"
|
|
||||||
map[":bow:"] = "🙇"
|
|
||||||
map[":bowling:"] = "🎳"
|
|
||||||
map[":boy:"] = "👦"
|
|
||||||
map[":bread:"] = "🍞"
|
|
||||||
map[":bride_with_veil:"] = "👰♀️"
|
|
||||||
map[":bridge_at_night:"] = "🌉"
|
|
||||||
map[":briefcase:"] = "💼"
|
|
||||||
map[":broken_heart:"] = "💔"
|
|
||||||
map[":bug:"] = "🐛"
|
|
||||||
map[":bulb:"] = "💡"
|
|
||||||
map[":bullettrain_front:"] = "🚅"
|
|
||||||
map[":bullettrain_side:"] = "🚄"
|
|
||||||
map[":bus:"] = "🚌"
|
|
||||||
map[":busstop:"] = "🚏"
|
|
||||||
map[":bust_in_silhouette:"] = "👤"
|
|
||||||
map[":busts_in_silhouette:"] = "👥"
|
|
||||||
map[":cactus:"] = "🌵"
|
|
||||||
map[":cake:"] = "🍰"
|
|
||||||
map[":calendar:"] = "📆"
|
|
||||||
map[":calling:"] = "📲"
|
|
||||||
map[":camel:"] = "🐫"
|
|
||||||
map[":camera:"] = "📷"
|
|
||||||
map[":cancer:"] = "♋"
|
|
||||||
map[":candy:"] = "🍬"
|
|
||||||
map[":capital_abcd:"] = "🔠"
|
|
||||||
map[":capricorn:"] = "♑"
|
|
||||||
map[":car:"] = "🚗"
|
|
||||||
map[":card_index:"] = "📇"
|
|
||||||
map[":carousel_horse:"] = "🎠"
|
|
||||||
map[":cat2:"] = "🐈"
|
|
||||||
map[":cat:"] = "🐱"
|
|
||||||
map[":cd:"] = "💿"
|
|
||||||
map[":chart:"] = "💹"
|
|
||||||
map[":chart_with_downwards_trend:"] = "📉"
|
|
||||||
map[":chart_with_upwards_trend:"] = "📈"
|
|
||||||
map[":checkered_flag:"] = "🏁"
|
|
||||||
map[":cherries:"] = "🍒"
|
|
||||||
map[":cherry_blossom:"] = "🌸"
|
|
||||||
map[":chestnut:"] = "🌰"
|
|
||||||
map[":chicken:"] = "🐔"
|
|
||||||
map[":children_crossing:"] = "🚸"
|
|
||||||
map[":chocolate_bar:"] = "🍫"
|
|
||||||
map[":christmas_tree:"] = "🎄"
|
|
||||||
map[":church:"] = "⛪"
|
|
||||||
map[":cinema:"] = "🎦"
|
|
||||||
map[":circus_tent:"] = "🎪"
|
|
||||||
map[":city_sunrise:"] = "🌇"
|
|
||||||
map[":city_sunset:"] = "🌆"
|
|
||||||
map[":cl:"] = "🆑"
|
|
||||||
map[":clap:"] = "👏"
|
|
||||||
map[":clapper:"] = "🎬"
|
|
||||||
map[":clipboard:"] = "📋"
|
|
||||||
map[":clock1030:"] = "🕥"
|
|
||||||
map[":clock10:"] = "🕙"
|
|
||||||
map[":clock1130:"] = "🕦"
|
|
||||||
map[":clock11:"] = "🕚"
|
|
||||||
map[":clock1230:"] = "🕧"
|
|
||||||
map[":clock12:"] = "🕛"
|
|
||||||
map[":clock130:"] = "🕜"
|
|
||||||
map[":clock1:"] = "🕐"
|
|
||||||
map[":clock230:"] = "🕝"
|
|
||||||
map[":clock2:"] = "🕑"
|
|
||||||
map[":clock330:"] = "🕞"
|
|
||||||
map[":clock3:"] = "🕒"
|
|
||||||
map[":clock430:"] = "🕟"
|
|
||||||
map[":clock4:"] = "🕓"
|
|
||||||
map[":clock530:"] = "🕠"
|
|
||||||
map[":clock5:"] = "🕔"
|
|
||||||
map[":clock630:"] = "🕡"
|
|
||||||
map[":clock6:"] = "🕕"
|
|
||||||
map[":clock730:"] = "🕢"
|
|
||||||
map[":clock7:"] = "🕖"
|
|
||||||
map[":clock830:"] = "🕣"
|
|
||||||
map[":clock8:"] = "🕗"
|
|
||||||
map[":clock930:"] = "🕤"
|
|
||||||
map[":clock9:"] = "🕘"
|
|
||||||
map[":closed_book:"] = "📕"
|
|
||||||
map[":closed_lock_with_key:"] = "🔐"
|
|
||||||
map[":closed_umbrella:"] = "🌂"
|
|
||||||
map[":cloud:"] = "☁️"
|
|
||||||
map[":clubs:"] = "♣️"
|
|
||||||
map[":cn:"] = "🇨🇳"
|
|
||||||
map[":cocktail:"] = "🍸"
|
|
||||||
map[":coffee:"] = "☕"
|
|
||||||
map[":cold_sweat:"] = "😰"
|
|
||||||
map[":computer:"] = "💻"
|
|
||||||
map[":confetti_ball:"] = "🎊"
|
|
||||||
map[":confounded:"] = "😖"
|
|
||||||
map[":confused:"] = "😕"
|
|
||||||
map[":congratulations:"] = "㊗️"
|
|
||||||
map[":construction:"] = "🚧"
|
|
||||||
map[":construction_worker:"] = "👷"
|
|
||||||
map[":convenience_store:"] = "🏪"
|
|
||||||
map[":cookie:"] = "🍪"
|
|
||||||
map[":cool:"] = "🆒"
|
|
||||||
map[":cop:"] = "👮"
|
|
||||||
map[":copyright:"] = "©️"
|
|
||||||
map[":corn:"] = "🌽"
|
|
||||||
map[":couple:"] = "👫"
|
|
||||||
map[":couple_with_heart:"] = "💑"
|
|
||||||
map[":couplekiss:"] = "💏"
|
|
||||||
map[":cow2:"] = "🐄"
|
|
||||||
map[":cow:"] = "🐮"
|
|
||||||
map[":credit_card:"] = "💳"
|
|
||||||
map[":crocodile:"] = "🐊"
|
|
||||||
map[":crossed_flags:"] = "🎌"
|
|
||||||
map[":crown:"] = "👑"
|
|
||||||
map[":cry:"] = "😢"
|
|
||||||
map[":crying_cat_face:"] = "😿"
|
|
||||||
map[":crystal_ball:"] = "🔮"
|
|
||||||
map[":cupid:"] = "💘"
|
|
||||||
map[":curly_loop:"] = "➰"
|
|
||||||
map[":currency_exchange:"] = "💱"
|
|
||||||
map[":curry:"] = "🍛"
|
|
||||||
map[":custard:"] = "🍮"
|
|
||||||
map[":customs:"] = "🛃"
|
|
||||||
map[":cyclone:"] = "🌀"
|
|
||||||
map[":dancer:"] = "💃"
|
|
||||||
map[":dancers:"] = "👯"
|
|
||||||
map[":dango:"] = "🍡"
|
|
||||||
map[":dart:"] = "🎯"
|
|
||||||
map[":dash:"] = "💨"
|
|
||||||
map[":date:"] = "📅"
|
|
||||||
map[":de:"] = "🇩🇪"
|
|
||||||
map[":deciduous_tree:"] = "🌳"
|
|
||||||
map[":department_store:"] = "🏬"
|
|
||||||
map[":diamond_shape_with_a_dot_inside:"] = "💠"
|
|
||||||
map[":diamonds:"] = "♦️"
|
|
||||||
map[":disappointed:"] = "😞"
|
|
||||||
map[":disappointed_relieved:"] = "😥"
|
|
||||||
map[":dizzy:"] = "💫"
|
|
||||||
map[":dizzy_face:"] = "😵"
|
|
||||||
map[":do_not_litter:"] = "🚯"
|
|
||||||
map[":dog2:"] = "🐕"
|
|
||||||
map[":dog:"] = "🐶"
|
|
||||||
map[":dollar:"] = "💵"
|
|
||||||
map[":dolls:"] = "🎎"
|
|
||||||
map[":dolphin:"] = "🐬"
|
|
||||||
map[":door:"] = "🚪"
|
|
||||||
map[":doughnut:"] = "🍩"
|
|
||||||
map[":dragon:"] = "🐉"
|
|
||||||
map[":dragon_face:"] = "🐲"
|
|
||||||
map[":dress:"] = "👗"
|
|
||||||
map[":dromedary_camel:"] = "🐪"
|
|
||||||
map[":droplet:"] = "💧"
|
|
||||||
map[":dvd:"] = "📀"
|
|
||||||
map[":ear:"] = "👂"
|
|
||||||
map[":ear_of_rice:"] = "🌾"
|
|
||||||
map[":earth_africa:"] = "🌍"
|
|
||||||
map[":earth_americas:"] = "🌎"
|
|
||||||
map[":earth_asia:"] = "🌏"
|
|
||||||
map[":egg:"] = "🥚"
|
|
||||||
map[":eggplant:"] = "🍆"
|
|
||||||
map[":eight:"] = "8️⃣"
|
|
||||||
map[":eight_pointed_black_star:"] = "✴️"
|
|
||||||
map[":eight_spoked_asterisk:"] = "✳️"
|
|
||||||
map[":electric_plug:"] = "🔌"
|
|
||||||
map[":elephant:"] = "🐘"
|
|
||||||
map[":email:"] = "📧"
|
|
||||||
map[":end:"] = "🔚"
|
|
||||||
map[":envelope:"] = "✉️"
|
|
||||||
map[":es:"] = "🇪🇸"
|
|
||||||
map[":euro:"] = "💶"
|
|
||||||
map[":european_castle:"] = "🏰"
|
|
||||||
map[":european_post_office:"] = "🏤"
|
|
||||||
map[":evergreen_tree:"] = "🌲"
|
|
||||||
map[":exclamation:"] = "❗"
|
|
||||||
map[":expressionless:"] = "😑"
|
|
||||||
map[":eyeglasses:"] = "👓"
|
|
||||||
map[":eyes:"] = "👀"
|
|
||||||
map[":factory:"] = "🏭"
|
|
||||||
map[":fallen_leaf:"] = "🍂"
|
|
||||||
map[":family:"] = "👪"
|
|
||||||
map[":fast_forward:"] = "⏩"
|
|
||||||
map[":fax:"] = "📠"
|
|
||||||
map[":fearful:"] = "😨"
|
|
||||||
map[":feet:"] = "🐾"
|
|
||||||
map[":ferris_wheel:"] = "🎡"
|
|
||||||
map[":file_folder:"] = "📁"
|
|
||||||
map[":fire:"] = "🔥"
|
|
||||||
map[":fire_engine:"] = "🚒"
|
|
||||||
map[":fireworks:"] = "🎆"
|
|
||||||
map[":first_quarter_moon:"] = "🌓"
|
|
||||||
map[":first_quarter_moon_with_face:"] = "🌛"
|
|
||||||
map[":fish:"] = "🐟"
|
|
||||||
map[":fish_cake:"] = "🍥"
|
|
||||||
map[":fishing_pole_and_fish:"] = "🎣"
|
|
||||||
map[":fist:"] = "✊"
|
|
||||||
map[":five:"] = "5️⃣"
|
|
||||||
map[":flags:"] = "🎏"
|
|
||||||
map[":flashlight:"] = "🔦"
|
|
||||||
map[":floppy_disk:"] = "💾"
|
|
||||||
map[":flower_playing_cards:"] = "🎴"
|
|
||||||
map[":flushed:"] = "😳"
|
|
||||||
map[":foggy:"] = "🌁"
|
|
||||||
map[":football:"] = "🏈"
|
|
||||||
map[":fork_and_knife:"] = "🍴"
|
|
||||||
map[":fountain:"] = "⛲"
|
|
||||||
map[":four:"] = "4️⃣"
|
|
||||||
map[":four_leaf_clover:"] = "🍀"
|
|
||||||
map[":fr:"] = "🇫🇷"
|
|
||||||
map[":free:"] = "🆓"
|
|
||||||
map[":fried_shrimp:"] = "🍤"
|
|
||||||
map[":fries:"] = "🍟"
|
|
||||||
map[":frog:"] = "🐸"
|
|
||||||
map[":frowning:"] = "😦"
|
|
||||||
map[":fuelpump:"] = "⛽"
|
|
||||||
map[":full_moon:"] = "🌕"
|
|
||||||
map[":full_moon_with_face:"] = "🌝"
|
|
||||||
map[":game_die:"] = "🎲"
|
|
||||||
map[":gem:"] = "💎"
|
|
||||||
map[":gemini:"] = "♊"
|
|
||||||
map[":ghost:"] = "👻"
|
|
||||||
map[":gift:"] = "🎁"
|
|
||||||
map[":gift_heart:"] = "💝"
|
|
||||||
map[":girl:"] = "👧"
|
|
||||||
map[":globe_with_meridians:"] = "🌐"
|
|
||||||
map[":goat:"] = "🐐"
|
|
||||||
map[":golf:"] = "⛳"
|
|
||||||
map[":grapes:"] = "🍇"
|
|
||||||
map[":green_apple:"] = "🍏"
|
|
||||||
map[":green_book:"] = "📗"
|
|
||||||
map[":green_heart:"] = "💚"
|
|
||||||
map[":grey_exclamation:"] = "❕"
|
|
||||||
map[":grey_question:"] = "❔"
|
|
||||||
map[":grimacing:"] = "😬"
|
|
||||||
map[":grin:"] = "😁"
|
|
||||||
map[":grinning:"] = "😀"
|
|
||||||
map[":guardsman:"] = "💂♂️"
|
|
||||||
map[":guitar:"] = "🎸"
|
|
||||||
map[":gun:"] = "🔫"
|
|
||||||
map[":haircut:"] = "💇"
|
|
||||||
map[":hamburger:"] = "🍔"
|
|
||||||
map[":hammer:"] = "🔨"
|
|
||||||
map[":hamster:"] = "🐹"
|
|
||||||
map[":handbag:"] = "👜"
|
|
||||||
map[":hankey:"] = "💩"
|
|
||||||
map[":hash:"] = "#️⃣"
|
|
||||||
map[":hatched_chick:"] = "🐥"
|
|
||||||
map[":hatching_chick:"] = "🐣"
|
|
||||||
map[":headphones:"] = "🎧"
|
|
||||||
map[":hear_no_evil:"] = "🙉"
|
|
||||||
map[":heart:"] = "❤️"
|
|
||||||
map[":heart_decoration:"] = "💟"
|
|
||||||
map[":heart_eyes:"] = "😍"
|
|
||||||
map[":heart_eyes_cat:"] = "😻"
|
|
||||||
map[":heartbeat:"] = "💓"
|
|
||||||
map[":hearts:"] = "♥️"
|
|
||||||
map[":heavy_check_mark:"] = "✔️"
|
|
||||||
map[":heavy_division_sign:"] = "➗"
|
|
||||||
map[":heavy_dollar_sign:"] = "💲"
|
|
||||||
map[":heavy_minus_sign:"] = "➖"
|
|
||||||
map[":heavy_multiplication_x:"] = "✖️"
|
|
||||||
map[":heavy_plus_sign:"] = "➕"
|
|
||||||
map[":helicopter:"] = "🚁"
|
|
||||||
map[":herb:"] = "🌿"
|
|
||||||
map[":hibiscus:"] = "🌺"
|
|
||||||
map[":high_brightness:"] = "🔆"
|
|
||||||
map[":high_heel:"] = "👠"
|
|
||||||
map[":honey_pot:"] = "🍯"
|
|
||||||
map[":horse:"] = "🐴"
|
|
||||||
map[":horse_racing:"] = "🏇"
|
|
||||||
map[":hospital:"] = "🏥"
|
|
||||||
map[":hotel:"] = "🏨"
|
|
||||||
map[":hotsprings:"] = "♨️"
|
|
||||||
map[":hourglass:"] = "⌛"
|
|
||||||
map[":hourglass_flowing_sand:"] = "⏳"
|
|
||||||
map[":house:"] = "🏠"
|
|
||||||
map[":house_with_garden:"] = "🏡"
|
|
||||||
map[":hushed:"] = "😯"
|
|
||||||
map[":ice_cream:"] = "🍨"
|
|
||||||
map[":icecream:"] = "🍦"
|
|
||||||
map[":id:"] = "🆔"
|
|
||||||
map[":ideograph_advantage:"] = "🉐"
|
|
||||||
map[":imp:"] = "👿"
|
|
||||||
map[":inbox_tray:"] = "📥"
|
|
||||||
map[":incoming_envelope:"] = "📨"
|
|
||||||
map[":information_desk_person:"] = "💁"
|
|
||||||
map[":information_source:"] = "ℹ️"
|
|
||||||
map[":innocent:"] = "😇"
|
|
||||||
map[":interrobang:"] = "⁉️"
|
|
||||||
map[":iphone:"] = "📱"
|
|
||||||
map[":it:"] = "🇮🇹"
|
|
||||||
map[":izakaya_lantern:"] = "🏮"
|
|
||||||
map[":jack_o_lantern:"] = "🎃"
|
|
||||||
map[":japan:"] = "🗾"
|
|
||||||
map[":japanese_castle:"] = "🏯"
|
|
||||||
map[":japanese_goblin:"] = "👺"
|
|
||||||
map[":japanese_ogre:"] = "👹"
|
|
||||||
map[":jeans:"] = "👖"
|
|
||||||
map[":joy:"] = "😂"
|
|
||||||
map[":joy_cat:"] = "😹"
|
|
||||||
map[":jp:"] = "🇯🇵"
|
|
||||||
map[":key:"] = "🔑"
|
|
||||||
map[":keycap_ten:"] = "🔟"
|
|
||||||
map[":kimono:"] = "👘"
|
|
||||||
map[":kiss:"] = "💋"
|
|
||||||
map[":kissing:"] = "😗"
|
|
||||||
map[":kissing_cat:"] = "😽"
|
|
||||||
map[":kissing_closed_eyes:"] = "😚"
|
|
||||||
map[":kissing_heart:"] = "😘"
|
|
||||||
map[":kissing_smiling_eyes:"] = "😙"
|
|
||||||
map[":koala:"] = "🐨"
|
|
||||||
map[":koko:"] = "🈁"
|
|
||||||
map[":kr:"] = "🇰🇷"
|
|
||||||
map[":large_blue_diamond:"] = "🔷"
|
|
||||||
map[":large_orange_diamond:"] = "🔶"
|
|
||||||
map[":last_quarter_moon:"] = "🌗"
|
|
||||||
map[":last_quarter_moon_with_face:"] = "🌜"
|
|
||||||
map[":laughing:"] = "😆"
|
|
||||||
map[":leaves:"] = "🍃"
|
|
||||||
map[":ledger:"] = "📒"
|
|
||||||
map[":left_luggage:"] = "🛅"
|
|
||||||
map[":left_right_arrow:"] = "↔️"
|
|
||||||
map[":leftwards_arrow_with_hook:"] = "↩️"
|
|
||||||
map[":lemon:"] = "🍋"
|
|
||||||
map[":leo:"] = "♌"
|
|
||||||
map[":leopard:"] = "🐆"
|
|
||||||
map[":libra:"] = "♎"
|
|
||||||
map[":light_rail:"] = "🚈"
|
|
||||||
map[":link:"] = "🔗"
|
|
||||||
map[":lips:"] = "👄"
|
|
||||||
map[":lipstick:"] = "💄"
|
|
||||||
map[":lock:"] = "🔒"
|
|
||||||
map[":lock_with_ink_pen:"] = "🔏"
|
|
||||||
map[":lollipop:"] = "🍭"
|
|
||||||
map[":loop:"] = "➿"
|
|
||||||
map[":loudspeaker:"] = "📢"
|
|
||||||
map[":love_hotel:"] = "🏩"
|
|
||||||
map[":love_letter:"] = "💌"
|
|
||||||
map[":low_brightness:"] = "🔅"
|
|
||||||
map[":m:"] = "Ⓜ️"
|
|
||||||
map[":mag:"] = "🔍"
|
|
||||||
map[":mag_right:"] = "🔎"
|
|
||||||
map[":mahjong:"] = "🀄"
|
|
||||||
map[":mailbox:"] = "📫"
|
|
||||||
map[":mailbox_closed:"] = "📪"
|
|
||||||
map[":mailbox_with_mail:"] = "📬"
|
|
||||||
map[":mailbox_with_no_mail:"] = "📭"
|
|
||||||
map[":man:"] = "👨"
|
|
||||||
map[":man_with_gua_pi_mao:"] = "👲"
|
|
||||||
map[":man_with_turban:"] = "👳♂️"
|
|
||||||
map[":mans_shoe:"] = "👞"
|
|
||||||
map[":maple_leaf:"] = "🍁"
|
|
||||||
map[":mask:"] = "😷"
|
|
||||||
map[":massage:"] = "💆"
|
|
||||||
map[":meat_on_bone:"] = "🍖"
|
|
||||||
map[":mega:"] = "📣"
|
|
||||||
map[":melon:"] = "🍈"
|
|
||||||
map[":memo:"] = "📝"
|
|
||||||
map[":mens:"] = "🚹"
|
|
||||||
map[":metal:"] = "🤘"
|
|
||||||
map[":metro:"] = "🚇"
|
|
||||||
map[":microphone:"] = "🎤"
|
|
||||||
map[":microscope:"] = "🔬"
|
|
||||||
map[":milky_way:"] = "🌌"
|
|
||||||
map[":minibus:"] = "🚐"
|
|
||||||
map[":minidisc:"] = "💽"
|
|
||||||
map[":mobile_phone_off:"] = "📴"
|
|
||||||
map[":money_with_wings:"] = "💸"
|
|
||||||
map[":moneybag:"] = "💰"
|
|
||||||
map[":monkey:"] = "🐒"
|
|
||||||
map[":monkey_face:"] = "🐵"
|
|
||||||
map[":monorail:"] = "🚝"
|
|
||||||
map[":mortar_board:"] = "🎓"
|
|
||||||
map[":mount_fuji:"] = "🗻"
|
|
||||||
map[":mountain_bicyclist:"] = "🚵"
|
|
||||||
map[":mountain_cableway:"] = "🚠"
|
|
||||||
map[":mountain_railway:"] = "🚞"
|
|
||||||
map[":mouse2:"] = "🐁"
|
|
||||||
map[":mouse:"] = "🐭"
|
|
||||||
map[":movie_camera:"] = "🎥"
|
|
||||||
map[":moyai:"] = "🗿"
|
|
||||||
map[":muscle:"] = "💪"
|
|
||||||
map[":mushroom:"] = "🍄"
|
|
||||||
map[":musical_keyboard:"] = "🎹"
|
|
||||||
map[":musical_note:"] = "🎵"
|
|
||||||
map[":musical_score:"] = "🎼"
|
|
||||||
map[":mute:"] = "🔇"
|
|
||||||
map[":nail_care:"] = "💅"
|
|
||||||
map[":name_badge:"] = "📛"
|
|
||||||
map[":necktie:"] = "👔"
|
|
||||||
map[":negative_squared_cross_mark:"] = "❎"
|
|
||||||
map[":neutral_face:"] = "😐"
|
|
||||||
map[":new:"] = "🆕"
|
|
||||||
map[":new_moon:"] = "🌑"
|
|
||||||
map[":new_moon_with_face:"] = "🌚"
|
|
||||||
map[":newspaper:"] = "📰"
|
|
||||||
map[":ng:"] = "🆖"
|
|
||||||
map[":nine:"] = "9️⃣"
|
|
||||||
map[":no_bell:"] = "🔕"
|
|
||||||
map[":no_bicycles:"] = "🚳"
|
|
||||||
map[":no_entry:"] = "⛔"
|
|
||||||
map[":no_entry_sign:"] = "🚫"
|
|
||||||
map[":no_good:"] = "🙅"
|
|
||||||
map[":no_mobile_phones:"] = "📵"
|
|
||||||
map[":no_mouth:"] = "😶"
|
|
||||||
map[":no_pedestrians:"] = "🚷"
|
|
||||||
map[":no_smoking:"] = "🚭"
|
|
||||||
map[":nose:"] = "👃"
|
|
||||||
map[":notebook:"] = "📓"
|
|
||||||
map[":notebook_with_decorative_cover:"] = "📔"
|
|
||||||
map[":notes:"] = "🎶"
|
|
||||||
map[":nut_and_bolt:"] = "🔩"
|
|
||||||
map[":o2:"] = "🅾️"
|
|
||||||
map[":o:"] = "⭕"
|
|
||||||
map[":ocean:"] = "🌊"
|
|
||||||
map[":octopus:"] = "🐙"
|
|
||||||
map[":oden:"] = "🍢"
|
|
||||||
map[":office:"] = "🏢"
|
|
||||||
map[":ok:"] = "🆗"
|
|
||||||
map[":ok_hand:"] = "👌"
|
|
||||||
map[":ok_woman:"] = "🙆♀️"
|
|
||||||
map[":older_man:"] = "👴"
|
|
||||||
map[":older_woman:"] = "👵"
|
|
||||||
map[":on:"] = "🔛"
|
|
||||||
map[":oncoming_automobile:"] = "🚘"
|
|
||||||
map[":oncoming_bus:"] = "🚍"
|
|
||||||
map[":oncoming_police_car:"] = "🚔"
|
|
||||||
map[":oncoming_taxi:"] = "🚖"
|
|
||||||
map[":one:"] = "1️⃣"
|
|
||||||
map[":open_file_folder:"] = "📂"
|
|
||||||
map[":open_hands:"] = "👐"
|
|
||||||
map[":open_mouth:"] = "😮"
|
|
||||||
map[":ophiuchus:"] = "⛎"
|
|
||||||
map[":orange_book:"] = "📙"
|
|
||||||
map[":outbox_tray:"] = "📤"
|
|
||||||
map[":ox:"] = "🐂"
|
|
||||||
map[":page_facing_up:"] = "📄"
|
|
||||||
map[":page_with_curl:"] = "📃"
|
|
||||||
map[":pager:"] = "📟"
|
|
||||||
map[":palm_tree:"] = "🌴"
|
|
||||||
map[":panda_face:"] = "🐼"
|
|
||||||
map[":paperclip:"] = "📎"
|
|
||||||
map[":parking:"] = "🅿️"
|
|
||||||
map[":part_alternation_mark:"] = "〽️"
|
|
||||||
map[":partly_sunny:"] = "⛅"
|
|
||||||
map[":passport_control:"] = "🛂"
|
|
||||||
map[":paw_prints:"] = "🐾"
|
|
||||||
map[":peach:"] = "🍑"
|
|
||||||
map[":pear:"] = "🍐"
|
|
||||||
map[":pencil2:"] = "✏️"
|
|
||||||
map[":pencil:"] = "📝"
|
|
||||||
map[":penguin:"] = "🐧"
|
|
||||||
map[":pensive:"] = "😔"
|
|
||||||
map[":performing_arts:"] = "🎭"
|
|
||||||
map[":persevere:"] = "😣"
|
|
||||||
map[":pig2:"] = "🐖"
|
|
||||||
map[":pig:"] = "🐷"
|
|
||||||
map[":pig_nose:"] = "🐽"
|
|
||||||
map[":pill:"] = "💊"
|
|
||||||
map[":pineapple:"] = "🍍"
|
|
||||||
map[":pisces:"] = "♓"
|
|
||||||
map[":pizza:"] = "🍕"
|
|
||||||
map[":point_down:"] = "👇"
|
|
||||||
map[":point_left:"] = "👈"
|
|
||||||
map[":point_right:"] = "👉"
|
|
||||||
map[":point_up:"] = "☝️"
|
|
||||||
map[":point_up_2:"] = "👆"
|
|
||||||
map[":police_car:"] = "🚓"
|
|
||||||
map[":poodle:"] = "🐩"
|
|
||||||
map[":poop:"] = "💩"
|
|
||||||
map[":post_office:"] = "🏣"
|
|
||||||
map[":postal_horn:"] = "📯"
|
|
||||||
map[":postbox:"] = "📮"
|
|
||||||
map[":potable_water:"] = "🚰"
|
|
||||||
map[":pouch:"] = "👝"
|
|
||||||
map[":poultry_leg:"] = "🍗"
|
|
||||||
map[":pound:"] = "💷"
|
|
||||||
map[":pouting_cat:"] = "😾"
|
|
||||||
map[":pray:"] = "🙏"
|
|
||||||
map[":princess:"] = "👸"
|
|
||||||
map[":punch:"] = "👊"
|
|
||||||
map[":purple_heart:"] = "💜"
|
|
||||||
map[":purse:"] = "👛"
|
|
||||||
map[":pushpin:"] = "📌"
|
|
||||||
map[":put_litter_in_its_place:"] = "🚮"
|
|
||||||
map[":question:"] = "❓"
|
|
||||||
map[":rabbit2:"] = "🐇"
|
|
||||||
map[":rabbit:"] = "🐰"
|
|
||||||
map[":racehorse:"] = "🐎"
|
|
||||||
map[":radio:"] = "📻"
|
|
||||||
map[":radio_button:"] = "🔘"
|
|
||||||
map[":rage:"] = "😡"
|
|
||||||
map[":railway_car:"] = "🚃"
|
|
||||||
map[":rainbow:"] = "🌈"
|
|
||||||
map[":raised_hand:"] = "✋"
|
|
||||||
map[":raised_hands:"] = "🙌"
|
|
||||||
map[":raising_hand:"] = "🙋"
|
|
||||||
map[":ram:"] = "🐏"
|
|
||||||
map[":ramen:"] = "🍜"
|
|
||||||
map[":rat:"] = "🐀"
|
|
||||||
map[":recycle:"] = "♻️"
|
|
||||||
map[":red_car:"] = "🚗"
|
|
||||||
map[":red_circle:"] = "🔴"
|
|
||||||
map[":registered:"] = "®️"
|
|
||||||
map[":relaxed:"] = "☺️"
|
|
||||||
map[":relieved:"] = "😌"
|
|
||||||
map[":repeat:"] = "🔁"
|
|
||||||
map[":repeat_one:"] = "🔂"
|
|
||||||
map[":restroom:"] = "🚻"
|
|
||||||
map[":revolving_hearts:"] = "💞"
|
|
||||||
map[":rewind:"] = "⏪"
|
|
||||||
map[":ribbon:"] = "🎀"
|
|
||||||
map[":rice:"] = "🍚"
|
|
||||||
map[":rice_ball:"] = "🍙"
|
|
||||||
map[":rice_cracker:"] = "🍘"
|
|
||||||
map[":rice_scene:"] = "🎑"
|
|
||||||
map[":ring:"] = "💍"
|
|
||||||
map[":rocket:"] = "🚀"
|
|
||||||
map[":roller_coaster:"] = "🎢"
|
|
||||||
map[":rooster:"] = "🐓"
|
|
||||||
map[":rose:"] = "🌹"
|
|
||||||
map[":rotating_light:"] = "🚨"
|
|
||||||
map[":round_pushpin:"] = "📍"
|
|
||||||
map[":rowboat:"] = "🚣"
|
|
||||||
map[":ru:"] = "🇷🇺"
|
|
||||||
map[":rugby_football:"] = "🏉"
|
|
||||||
map[":runner:"] = "🏃"
|
|
||||||
map[":running_shirt_with_sash:"] = "🎽"
|
|
||||||
map[":sa:"] = "🈂️"
|
|
||||||
map[":sagittarius:"] = "♐"
|
|
||||||
map[":sailboat:"] = "⛵"
|
|
||||||
map[":sake:"] = "🍶"
|
|
||||||
map[":sandal:"] = "👡"
|
|
||||||
map[":santa:"] = "🎅"
|
|
||||||
map[":satellite:"] = "📡"
|
|
||||||
map[":satisfied:"] = "😆"
|
|
||||||
map[":saxophone:"] = "🎷"
|
|
||||||
map[":school:"] = "🏫"
|
|
||||||
map[":school_satchel:"] = "🎒"
|
|
||||||
map[":scissors:"] = "✂️"
|
|
||||||
map[":scorpius:"] = "♏"
|
|
||||||
map[":scream:"] = "😱"
|
|
||||||
map[":scream_cat:"] = "🙀"
|
|
||||||
map[":scroll:"] = "📜"
|
|
||||||
map[":seat:"] = "💺"
|
|
||||||
map[":secret:"] = "㊙️"
|
|
||||||
map[":see_no_evil:"] = "🙈"
|
|
||||||
map[":seedling:"] = "🌱"
|
|
||||||
map[":seven:"] = "7️⃣"
|
|
||||||
map[":shaved_ice:"] = "🍧"
|
|
||||||
map[":sheep:"] = "🐑"
|
|
||||||
map[":shell:"] = "🐚"
|
|
||||||
map[":ship:"] = "🚢"
|
|
||||||
map[":shirt:"] = "👕"
|
|
||||||
map[":shit:"] = "💩"
|
|
||||||
map[":shower:"] = "🚿"
|
|
||||||
map[":signal_strength:"] = "📶"
|
|
||||||
map[":six:"] = "6️⃣"
|
|
||||||
map[":six_pointed_star:"] = "🔯"
|
|
||||||
map[":ski:"] = "🎿"
|
|
||||||
map[":skull:"] = "💀"
|
|
||||||
map[":sleeping:"] = "😴"
|
|
||||||
map[":sleepy:"] = "😪"
|
|
||||||
map[":slot_machine:"] = "🎰"
|
|
||||||
map[":small_blue_diamond:"] = "🔹"
|
|
||||||
map[":small_orange_diamond:"] = "🔸"
|
|
||||||
map[":small_red_triangle:"] = "🔺"
|
|
||||||
map[":small_red_triangle_down:"] = "🔻"
|
|
||||||
map[":smile:"] = "😄"
|
|
||||||
map[":smile_cat:"] = "😸"
|
|
||||||
map[":smiley:"] = "😃"
|
|
||||||
map[":smiley_cat:"] = "😺"
|
|
||||||
map[":smiling_imp:"] = "😈"
|
|
||||||
map[":smirk:"] = "😏"
|
|
||||||
map[":smirk_cat:"] = "😼"
|
|
||||||
map[":smoking:"] = "🚬"
|
|
||||||
map[":snail:"] = "🐌"
|
|
||||||
map[":snake:"] = "🐍"
|
|
||||||
map[":snowboarder:"] = "🏂"
|
|
||||||
map[":snowflake:"] = "❄️"
|
|
||||||
map[":snowman:"] = "⛄"
|
|
||||||
map[":sob:"] = "😭"
|
|
||||||
map[":soccer:"] = "⚽"
|
|
||||||
map[":soon:"] = "🔜"
|
|
||||||
map[":sos:"] = "🆘"
|
|
||||||
map[":sound:"] = "🔉"
|
|
||||||
map[":space_invader:"] = "👾"
|
|
||||||
map[":spades:"] = "♠️"
|
|
||||||
map[":spaghetti:"] = "🍝"
|
|
||||||
map[":sparkler:"] = "🎇"
|
|
||||||
map[":sparkles:"] = "✨"
|
|
||||||
map[":sparkling_heart:"] = "💖"
|
|
||||||
map[":speak_no_evil:"] = "🙊"
|
|
||||||
map[":speaker:"] = "🔈"
|
|
||||||
map[":speech_balloon:"] = "💬"
|
|
||||||
map[":speedboat:"] = "🚤"
|
|
||||||
map[":star2:"] = "🌟"
|
|
||||||
map[":star:"] = "⭐"
|
|
||||||
map[":stars:"] = "🌠"
|
|
||||||
map[":station:"] = "🚉"
|
|
||||||
map[":statue_of_liberty:"] = "🗽"
|
|
||||||
map[":steam_locomotive:"] = "🚂"
|
|
||||||
map[":stew:"] = "🍲"
|
|
||||||
map[":straight_ruler:"] = "📏"
|
|
||||||
map[":strawberry:"] = "🍓"
|
|
||||||
map[":stuck_out_tongue:"] = "😛"
|
|
||||||
map[":stuck_out_tongue_closed_eyes:"] = "😝"
|
|
||||||
map[":stuck_out_tongue_winking_eye:"] = "😜"
|
|
||||||
map[":sun_with_face:"] = "🌞"
|
|
||||||
map[":sunflower:"] = "🌻"
|
|
||||||
map[":sunglasses:"] = "😎"
|
|
||||||
map[":sunny:"] = "☀️"
|
|
||||||
map[":sunrise:"] = "🌅"
|
|
||||||
map[":sunrise_over_mountains:"] = "🌄"
|
|
||||||
map[":surfer:"] = "🏄"
|
|
||||||
map[":sushi:"] = "🍣"
|
|
||||||
map[":suspension_railway:"] = "🚟"
|
|
||||||
map[":sweat:"] = "😓"
|
|
||||||
map[":sweat_drops:"] = "💦"
|
|
||||||
map[":sweat_smile:"] = "😅"
|
|
||||||
map[":sweet_potato:"] = "🍠"
|
|
||||||
map[":swimmer:"] = "🏊"
|
|
||||||
map[":symbols:"] = "🔣"
|
|
||||||
map[":syringe:"] = "💉"
|
|
||||||
map[":tada:"] = "🎉"
|
|
||||||
map[":tanabata_tree:"] = "🎋"
|
|
||||||
map[":tangerine:"] = "🍊"
|
|
||||||
map[":taurus:"] = "♉"
|
|
||||||
map[":taxi:"] = "🚕"
|
|
||||||
map[":tea:"] = "🍵"
|
|
||||||
map[":telephone:"] = "☎️"
|
|
||||||
map[":telephone_receiver:"] = "📞"
|
|
||||||
map[":telescope:"] = "🔭"
|
|
||||||
map[":tennis:"] = "🎾"
|
|
||||||
map[":tent:"] = "⛺"
|
|
||||||
map[":thought_balloon:"] = "💭"
|
|
||||||
map[":three:"] = "3️⃣"
|
|
||||||
map[":thumbsdown:"] = "👎"
|
|
||||||
map[":thumbsup:"] = "👍"
|
|
||||||
map[":ticket:"] = "🎫"
|
|
||||||
map[":tiger2:"] = "🐅"
|
|
||||||
map[":tiger:"] = "🐯"
|
|
||||||
map[":tired_face:"] = "😫"
|
|
||||||
map[":tm:"] = "™️"
|
|
||||||
map[":toilet:"] = "🚽"
|
|
||||||
map[":tokyo_tower:"] = "🗼"
|
|
||||||
map[":tomato:"] = "🍅"
|
|
||||||
map[":tongue:"] = "👅"
|
|
||||||
map[":top:"] = "🔝"
|
|
||||||
map[":tophat:"] = "🎩"
|
|
||||||
map[":tractor:"] = "🚜"
|
|
||||||
map[":traffic_light:"] = "🚥"
|
|
||||||
map[":train2:"] = "🚆"
|
|
||||||
map[":train:"] = "🚋"
|
|
||||||
map[":tram:"] = "🚊"
|
|
||||||
map[":triangular_flag_on_post:"] = "🚩"
|
|
||||||
map[":triangular_ruler:"] = "📐"
|
|
||||||
map[":trident:"] = "🔱"
|
|
||||||
map[":triumph:"] = "😤"
|
|
||||||
map[":trolleybus:"] = "🚎"
|
|
||||||
map[":trophy:"] = "🏆"
|
|
||||||
map[":tropical_drink:"] = "🍹"
|
|
||||||
map[":tropical_fish:"] = "🐠"
|
|
||||||
map[":truck:"] = "🚚"
|
|
||||||
map[":trumpet:"] = "🎺"
|
|
||||||
map[":tulip:"] = "🌷"
|
|
||||||
map[":turtle:"] = "🐢"
|
|
||||||
map[":tv:"] = "📺"
|
|
||||||
map[":twisted_rightwards_arrows:"] = "🔀"
|
|
||||||
map[":two:"] = "2️⃣"
|
|
||||||
map[":two_men_holding_hands:"] = "👬"
|
|
||||||
map[":two_women_holding_hands:"] = "👭"
|
|
||||||
map[":u5272:"] = "🈹"
|
|
||||||
map[":u5408:"] = "🈴"
|
|
||||||
map[":u55b6:"] = "🈺"
|
|
||||||
map[":u6307:"] = "🈯"
|
|
||||||
map[":u6708:"] = "🈷️"
|
|
||||||
map[":u6709:"] = "🈶"
|
|
||||||
map[":u6e80:"] = "🈵"
|
|
||||||
map[":u7121:"] = "🈚"
|
|
||||||
map[":u7533:"] = "🈸"
|
|
||||||
map[":u7981:"] = "🈲"
|
|
||||||
map[":u7a7a:"] = "🈳"
|
|
||||||
map[":umbrella:"] = "☔"
|
|
||||||
map[":unamused:"] = "😒"
|
|
||||||
map[":underage:"] = "🔞"
|
|
||||||
map[":unlock:"] = "🔓"
|
|
||||||
map[":up:"] = "🆙"
|
|
||||||
map[":us:"] = "🇺🇸"
|
|
||||||
map[":v:"] = "✌️"
|
|
||||||
map[":vertical_traffic_light:"] = "🚦"
|
|
||||||
map[":vhs:"] = "📼"
|
|
||||||
map[":vibration_mode:"] = "📳"
|
|
||||||
map[":video_camera:"] = "📹"
|
|
||||||
map[":video_game:"] = "🎮"
|
|
||||||
map[":violin:"] = "🎻"
|
|
||||||
map[":virgo:"] = "♍"
|
|
||||||
map[":volcano:"] = "🌋"
|
|
||||||
map[":vs:"] = "🆚"
|
|
||||||
map[":walking:"] = "🚶"
|
|
||||||
map[":waning_crescent_moon:"] = "🌘"
|
|
||||||
map[":waning_gibbous_moon:"] = "🌖"
|
|
||||||
map[":warning:"] = "⚠️"
|
|
||||||
map[":watch:"] = "⌚"
|
|
||||||
map[":water_buffalo:"] = "🐃"
|
|
||||||
map[":watermelon:"] = "🍉"
|
|
||||||
map[":wave:"] = "👋"
|
|
||||||
map[":wavy_dash:"] = "〰️"
|
|
||||||
map[":waxing_crescent_moon:"] = "🌒"
|
|
||||||
map[":waxing_gibbous_moon:"] = "🌔"
|
|
||||||
map[":wc:"] = "🚾"
|
|
||||||
map[":weary:"] = "😩"
|
|
||||||
map[":wedding:"] = "💒"
|
|
||||||
map[":whale2:"] = "🐋"
|
|
||||||
map[":whale:"] = "🐳"
|
|
||||||
map[":wheelchair:"] = "♿"
|
|
||||||
map[":white_check_mark:"] = "✅"
|
|
||||||
map[":white_circle:"] = "⚪"
|
|
||||||
map[":white_flower:"] = "💮"
|
|
||||||
map[":white_square_button:"] = "🔳"
|
|
||||||
map[":wind_chime:"] = "🎐"
|
|
||||||
map[":wine_glass:"] = "🍷"
|
|
||||||
map[":wink:"] = "😉"
|
|
||||||
map[":wolf:"] = "🐺"
|
|
||||||
map[":woman:"] = "👩"
|
|
||||||
map[":womans_clothes:"] = "👚"
|
|
||||||
map[":womans_hat:"] = "👒"
|
|
||||||
map[":womens:"] = "🚺"
|
|
||||||
map[":worried:"] = "😟"
|
|
||||||
map[":wrench:"] = "🔧"
|
|
||||||
map[":x:"] = "❌"
|
|
||||||
map[":yellow_heart:"] = "💛"
|
|
||||||
map[":yen:"] = "💴"
|
|
||||||
map[":yum:"] = "😋"
|
|
||||||
map[":zap:"] = "⚡"
|
|
||||||
map[":zero:"] = "0️⃣"
|
|
||||||
map[":zzz:"] = "💤"
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
if ($0 ~ /<pre>/) in_pre = 1
|
if ($0 ~ /<pre>/) in_pre = 1
|
||||||
@@ -833,6 +17,7 @@ BEGIN {
|
|||||||
code_count = 0
|
code_count = 0
|
||||||
line = $0
|
line = $0
|
||||||
out = ""
|
out = ""
|
||||||
|
|
||||||
while (match(line, /<code>[^<]*<\/code>/)) {
|
while (match(line, /<code>[^<]*<\/code>/)) {
|
||||||
code_count++
|
code_count++
|
||||||
code_store[code_count] = substr(line, RSTART, RLENGTH)
|
code_store[code_count] = substr(line, RSTART, RLENGTH)
|
||||||
@@ -841,14 +26,23 @@ BEGIN {
|
|||||||
}
|
}
|
||||||
out = out line
|
out = out line
|
||||||
|
|
||||||
for (sc in map) {
|
line = out
|
||||||
if (index(out, sc)) {
|
out = ""
|
||||||
gsub(sc, map[sc], out)
|
while (match(line, /:[A-Za-z0-9_+\-]+:/)) {
|
||||||
|
token = substr(line, RSTART, RLENGTH)
|
||||||
|
out = out substr(line, 1, RSTART - 1)
|
||||||
|
if (token in map) {
|
||||||
|
out = out map[token]
|
||||||
|
} else {
|
||||||
|
out = out token
|
||||||
}
|
}
|
||||||
|
line = substr(line, RSTART + RLENGTH)
|
||||||
}
|
}
|
||||||
|
out = out line
|
||||||
|
|
||||||
for (i = 1; i <= code_count; i++) {
|
for (i = 1; i <= code_count; i++) {
|
||||||
gsub("\034EC" i "\034", code_store[i], out)
|
gsub("\034EC" i "\034", code_store[i], out)
|
||||||
|
delete code_store[i]
|
||||||
}
|
}
|
||||||
$0 = out
|
$0 = out
|
||||||
}
|
}
|
||||||
|
|||||||
827
awk/emoji.tsv
Normal file
827
awk/emoji.tsv
Normal file
@@ -0,0 +1,827 @@
|
|||||||
|
:+1: 👍
|
||||||
|
:100: 💯
|
||||||
|
:1234: 🔢
|
||||||
|
:8ball: 🎱
|
||||||
|
:a: 🅰️
|
||||||
|
:ab: 🆎
|
||||||
|
:abc: 🔤
|
||||||
|
:abcd: 🔡
|
||||||
|
:accept: 🉑
|
||||||
|
:aerial_tramway: 🚡
|
||||||
|
:airplane: ✈️
|
||||||
|
:alarm_clock: ⏰
|
||||||
|
:alien: 👽
|
||||||
|
:ambulance: 🚑
|
||||||
|
:anchor: ⚓
|
||||||
|
:angel: 👼
|
||||||
|
:anger: 💢
|
||||||
|
:angry: 😠
|
||||||
|
:anguished: 😧
|
||||||
|
:ant: 🐜
|
||||||
|
:apple: 🍎
|
||||||
|
:aquarius: ♒
|
||||||
|
:aries: ♈
|
||||||
|
:arrow_backward: ◀️
|
||||||
|
:arrow_double_down: ⏬
|
||||||
|
:arrow_double_up: ⏫
|
||||||
|
:arrow_down: ⬇️
|
||||||
|
:arrow_down_small: 🔽
|
||||||
|
:arrow_forward: ▶️
|
||||||
|
:arrow_heading_down: ⤵️
|
||||||
|
:arrow_heading_up: ⤴️
|
||||||
|
:arrow_left: ⬅️
|
||||||
|
:arrow_lower_left: ↙️
|
||||||
|
:arrow_lower_right: ↘️
|
||||||
|
:arrow_right: ➡️
|
||||||
|
:arrow_right_hook: ↪️
|
||||||
|
:arrow_up: ⬆️
|
||||||
|
:arrow_up_down: ↕️
|
||||||
|
:arrow_up_small: 🔼
|
||||||
|
:arrow_upper_left: ↖️
|
||||||
|
:arrow_upper_right: ↗️
|
||||||
|
:arrows_clockwise: 🔃
|
||||||
|
:arrows_counterclockwise: 🔄
|
||||||
|
:art: 🎨
|
||||||
|
:articulated_lorry: 🚛
|
||||||
|
:astonished: 😲
|
||||||
|
:atm: 🏧
|
||||||
|
:b: 🅱️
|
||||||
|
:baby: 👶
|
||||||
|
:baby_bottle: 🍼
|
||||||
|
:baby_chick: 🐤
|
||||||
|
:baby_symbol: 🚼
|
||||||
|
:baggage_claim: 🛄
|
||||||
|
:balloon: 🎈
|
||||||
|
:ballot_box_with_check: ☑️
|
||||||
|
:bamboo: 🎍
|
||||||
|
:banana: 🍌
|
||||||
|
:bangbang: ‼️
|
||||||
|
:bank: 🏦
|
||||||
|
:bar_chart: 📊
|
||||||
|
:barber: 💈
|
||||||
|
:baseball: ⚾
|
||||||
|
:basketball: 🏀
|
||||||
|
:bath: 🛀
|
||||||
|
:bathtub: 🛁
|
||||||
|
:battery: 🔋
|
||||||
|
:bear: 🐻
|
||||||
|
:beer: 🍺
|
||||||
|
:beers: 🍻
|
||||||
|
:beetle: 🪲
|
||||||
|
:beginner: 🔰
|
||||||
|
:bell: 🔔
|
||||||
|
:bento: 🍱
|
||||||
|
:bicyclist: 🚴
|
||||||
|
:bike: 🚲
|
||||||
|
:bikini: 👙
|
||||||
|
:bird: 🐦
|
||||||
|
:birthday: 🎂
|
||||||
|
:black_circle: ⚫
|
||||||
|
:black_joker: 🃏
|
||||||
|
:black_nib: ✒️
|
||||||
|
:black_square_button: 🔲
|
||||||
|
:blossom: 🌼
|
||||||
|
:blowfish: 🐡
|
||||||
|
:blue_book: 📘
|
||||||
|
:blue_car: 🚙
|
||||||
|
:blue_heart: 💙
|
||||||
|
:blush: 😊
|
||||||
|
:boar: 🐗
|
||||||
|
:boat: ⛵
|
||||||
|
:bomb: 💣
|
||||||
|
:book: 📖
|
||||||
|
:bookmark: 🔖
|
||||||
|
:bookmark_tabs: 📑
|
||||||
|
:books: 📚
|
||||||
|
:boom: 💥
|
||||||
|
:boot: 👢
|
||||||
|
:bouquet: 💐
|
||||||
|
:bow: 🙇
|
||||||
|
:bowling: 🎳
|
||||||
|
:boy: 👦
|
||||||
|
:bread: 🍞
|
||||||
|
:bride_with_veil: 👰♀️
|
||||||
|
:bridge_at_night: 🌉
|
||||||
|
:briefcase: 💼
|
||||||
|
:broken_heart: 💔
|
||||||
|
:bug: 🐛
|
||||||
|
:bulb: 💡
|
||||||
|
:bullettrain_front: 🚅
|
||||||
|
:bullettrain_side: 🚄
|
||||||
|
:bus: 🚌
|
||||||
|
:busstop: 🚏
|
||||||
|
:bust_in_silhouette: 👤
|
||||||
|
:busts_in_silhouette: 👥
|
||||||
|
:cactus: 🌵
|
||||||
|
:cake: 🍰
|
||||||
|
:calendar: 📆
|
||||||
|
:calling: 📲
|
||||||
|
:camel: 🐫
|
||||||
|
:camera: 📷
|
||||||
|
:cancer: ♋
|
||||||
|
:candy: 🍬
|
||||||
|
:capital_abcd: 🔠
|
||||||
|
:capricorn: ♑
|
||||||
|
:car: 🚗
|
||||||
|
:card_index: 📇
|
||||||
|
:carousel_horse: 🎠
|
||||||
|
:cat2: 🐈
|
||||||
|
:cat: 🐱
|
||||||
|
:cd: 💿
|
||||||
|
:chart: 💹
|
||||||
|
:chart_with_downwards_trend: 📉
|
||||||
|
:chart_with_upwards_trend: 📈
|
||||||
|
:checkered_flag: 🏁
|
||||||
|
:cherries: 🍒
|
||||||
|
:cherry_blossom: 🌸
|
||||||
|
:chestnut: 🌰
|
||||||
|
:chicken: 🐔
|
||||||
|
:children_crossing: 🚸
|
||||||
|
:chocolate_bar: 🍫
|
||||||
|
:christmas_tree: 🎄
|
||||||
|
:church: ⛪
|
||||||
|
:cinema: 🎦
|
||||||
|
:circus_tent: 🎪
|
||||||
|
:city_sunrise: 🌇
|
||||||
|
:city_sunset: 🌆
|
||||||
|
:cl: 🆑
|
||||||
|
:clap: 👏
|
||||||
|
:clapper: 🎬
|
||||||
|
:clipboard: 📋
|
||||||
|
:clock1030: 🕥
|
||||||
|
:clock10: 🕙
|
||||||
|
:clock1130: 🕦
|
||||||
|
:clock11: 🕚
|
||||||
|
:clock1230: 🕧
|
||||||
|
:clock12: 🕛
|
||||||
|
:clock130: 🕜
|
||||||
|
:clock1: 🕐
|
||||||
|
:clock230: 🕝
|
||||||
|
:clock2: 🕑
|
||||||
|
:clock330: 🕞
|
||||||
|
:clock3: 🕒
|
||||||
|
:clock430: 🕟
|
||||||
|
:clock4: 🕓
|
||||||
|
:clock530: 🕠
|
||||||
|
:clock5: 🕔
|
||||||
|
:clock630: 🕡
|
||||||
|
:clock6: 🕕
|
||||||
|
:clock730: 🕢
|
||||||
|
:clock7: 🕖
|
||||||
|
:clock830: 🕣
|
||||||
|
:clock8: 🕗
|
||||||
|
:clock930: 🕤
|
||||||
|
:clock9: 🕘
|
||||||
|
:closed_book: 📕
|
||||||
|
:closed_lock_with_key: 🔐
|
||||||
|
:closed_umbrella: 🌂
|
||||||
|
:cloud: ☁️
|
||||||
|
:clubs: ♣️
|
||||||
|
:cn: 🇨🇳
|
||||||
|
:cocktail: 🍸
|
||||||
|
:coffee: ☕
|
||||||
|
:cold_sweat: 😰
|
||||||
|
:computer: 💻
|
||||||
|
:confetti_ball: 🎊
|
||||||
|
:confounded: 😖
|
||||||
|
:confused: 😕
|
||||||
|
:congratulations: ㊗️
|
||||||
|
:construction: 🚧
|
||||||
|
:construction_worker: 👷
|
||||||
|
:convenience_store: 🏪
|
||||||
|
:cookie: 🍪
|
||||||
|
:cool: 🆒
|
||||||
|
:cop: 👮
|
||||||
|
:copyright: ©️
|
||||||
|
:corn: 🌽
|
||||||
|
:couple: 👫
|
||||||
|
:couple_with_heart: 💑
|
||||||
|
:couplekiss: 💏
|
||||||
|
:cow2: 🐄
|
||||||
|
:cow: 🐮
|
||||||
|
:credit_card: 💳
|
||||||
|
:crocodile: 🐊
|
||||||
|
:crossed_flags: 🎌
|
||||||
|
:crown: 👑
|
||||||
|
:cry: 😢
|
||||||
|
:crying_cat_face: 😿
|
||||||
|
:crystal_ball: 🔮
|
||||||
|
:cupid: 💘
|
||||||
|
:curly_loop: ➰
|
||||||
|
:currency_exchange: 💱
|
||||||
|
:curry: 🍛
|
||||||
|
:custard: 🍮
|
||||||
|
:customs: 🛃
|
||||||
|
:cyclone: 🌀
|
||||||
|
:dancer: 💃
|
||||||
|
:dancers: 👯
|
||||||
|
:dango: 🍡
|
||||||
|
:dart: 🎯
|
||||||
|
:dash: 💨
|
||||||
|
:date: 📅
|
||||||
|
:de: 🇩🇪
|
||||||
|
:deciduous_tree: 🌳
|
||||||
|
:department_store: 🏬
|
||||||
|
:diamond_shape_with_a_dot_inside: 💠
|
||||||
|
:diamonds: ♦️
|
||||||
|
:disappointed: 😞
|
||||||
|
:disappointed_relieved: 😥
|
||||||
|
:dizzy: 💫
|
||||||
|
:dizzy_face: 😵
|
||||||
|
:do_not_litter: 🚯
|
||||||
|
:dog2: 🐕
|
||||||
|
:dog: 🐶
|
||||||
|
:dollar: 💵
|
||||||
|
:dolls: 🎎
|
||||||
|
:dolphin: 🐬
|
||||||
|
:door: 🚪
|
||||||
|
:doughnut: 🍩
|
||||||
|
:dragon: 🐉
|
||||||
|
:dragon_face: 🐲
|
||||||
|
:dress: 👗
|
||||||
|
:dromedary_camel: 🐪
|
||||||
|
:droplet: 💧
|
||||||
|
:dvd: 📀
|
||||||
|
:ear: 👂
|
||||||
|
:ear_of_rice: 🌾
|
||||||
|
:earth_africa: 🌍
|
||||||
|
:earth_americas: 🌎
|
||||||
|
:earth_asia: 🌏
|
||||||
|
:egg: 🥚
|
||||||
|
:eggplant: 🍆
|
||||||
|
:eight: 8️⃣
|
||||||
|
:eight_pointed_black_star: ✴️
|
||||||
|
:eight_spoked_asterisk: ✳️
|
||||||
|
:electric_plug: 🔌
|
||||||
|
:elephant: 🐘
|
||||||
|
:email: 📧
|
||||||
|
:end: 🔚
|
||||||
|
:envelope: ✉️
|
||||||
|
:es: 🇪🇸
|
||||||
|
:euro: 💶
|
||||||
|
:european_castle: 🏰
|
||||||
|
:european_post_office: 🏤
|
||||||
|
:evergreen_tree: 🌲
|
||||||
|
:exclamation: ❗
|
||||||
|
:expressionless: 😑
|
||||||
|
:eyeglasses: 👓
|
||||||
|
:eyes: 👀
|
||||||
|
:factory: 🏭
|
||||||
|
:fallen_leaf: 🍂
|
||||||
|
:family: 👪
|
||||||
|
:fast_forward: ⏩
|
||||||
|
:fax: 📠
|
||||||
|
:fearful: 😨
|
||||||
|
:feet: 🐾
|
||||||
|
:ferris_wheel: 🎡
|
||||||
|
:file_folder: 📁
|
||||||
|
:fire: 🔥
|
||||||
|
:fire_engine: 🚒
|
||||||
|
:fireworks: 🎆
|
||||||
|
:first_quarter_moon: 🌓
|
||||||
|
:first_quarter_moon_with_face: 🌛
|
||||||
|
:fish: 🐟
|
||||||
|
:fish_cake: 🍥
|
||||||
|
:fishing_pole_and_fish: 🎣
|
||||||
|
:fist: ✊
|
||||||
|
:five: 5️⃣
|
||||||
|
:flags: 🎏
|
||||||
|
:flashlight: 🔦
|
||||||
|
:floppy_disk: 💾
|
||||||
|
:flower_playing_cards: 🎴
|
||||||
|
:flushed: 😳
|
||||||
|
:foggy: 🌁
|
||||||
|
:football: 🏈
|
||||||
|
:fork_and_knife: 🍴
|
||||||
|
:fountain: ⛲
|
||||||
|
:four: 4️⃣
|
||||||
|
:four_leaf_clover: 🍀
|
||||||
|
:fr: 🇫🇷
|
||||||
|
:free: 🆓
|
||||||
|
:fried_shrimp: 🍤
|
||||||
|
:fries: 🍟
|
||||||
|
:frog: 🐸
|
||||||
|
:frowning: 😦
|
||||||
|
:fuelpump: ⛽
|
||||||
|
:full_moon: 🌕
|
||||||
|
:full_moon_with_face: 🌝
|
||||||
|
:game_die: 🎲
|
||||||
|
:gem: 💎
|
||||||
|
:gemini: ♊
|
||||||
|
:ghost: 👻
|
||||||
|
:gift: 🎁
|
||||||
|
:gift_heart: 💝
|
||||||
|
:girl: 👧
|
||||||
|
:globe_with_meridians: 🌐
|
||||||
|
:goat: 🐐
|
||||||
|
:golf: ⛳
|
||||||
|
:grapes: 🍇
|
||||||
|
:green_apple: 🍏
|
||||||
|
:green_book: 📗
|
||||||
|
:green_heart: 💚
|
||||||
|
:grey_exclamation: ❕
|
||||||
|
:grey_question: ❔
|
||||||
|
:grimacing: 😬
|
||||||
|
:grin: 😁
|
||||||
|
:grinning: 😀
|
||||||
|
:guardsman: 💂♂️
|
||||||
|
:guitar: 🎸
|
||||||
|
:gun: 🔫
|
||||||
|
:haircut: 💇
|
||||||
|
:hamburger: 🍔
|
||||||
|
:hammer: 🔨
|
||||||
|
:hamster: 🐹
|
||||||
|
:handbag: 👜
|
||||||
|
:hankey: 💩
|
||||||
|
:hash: #️⃣
|
||||||
|
:hatched_chick: 🐥
|
||||||
|
:hatching_chick: 🐣
|
||||||
|
:headphones: 🎧
|
||||||
|
:hear_no_evil: 🙉
|
||||||
|
:heart: ❤️
|
||||||
|
:heart_decoration: 💟
|
||||||
|
:heart_eyes: 😍
|
||||||
|
:heart_eyes_cat: 😻
|
||||||
|
:heartbeat: 💓
|
||||||
|
:hearts: ♥️
|
||||||
|
:heavy_check_mark: ✔️
|
||||||
|
:heavy_division_sign: ➗
|
||||||
|
:heavy_dollar_sign: 💲
|
||||||
|
:heavy_minus_sign: ➖
|
||||||
|
:heavy_multiplication_x: ✖️
|
||||||
|
:heavy_plus_sign: ➕
|
||||||
|
:helicopter: 🚁
|
||||||
|
:herb: 🌿
|
||||||
|
:hibiscus: 🌺
|
||||||
|
:high_brightness: 🔆
|
||||||
|
:high_heel: 👠
|
||||||
|
:honey_pot: 🍯
|
||||||
|
:horse: 🐴
|
||||||
|
:horse_racing: 🏇
|
||||||
|
:hospital: 🏥
|
||||||
|
:hotel: 🏨
|
||||||
|
:hotsprings: ♨️
|
||||||
|
:hourglass: ⌛
|
||||||
|
:hourglass_flowing_sand: ⏳
|
||||||
|
:house: 🏠
|
||||||
|
:house_with_garden: 🏡
|
||||||
|
:hushed: 😯
|
||||||
|
:ice_cream: 🍨
|
||||||
|
:icecream: 🍦
|
||||||
|
:id: 🆔
|
||||||
|
:ideograph_advantage: 🉐
|
||||||
|
:imp: 👿
|
||||||
|
:inbox_tray: 📥
|
||||||
|
:incoming_envelope: 📨
|
||||||
|
:information_desk_person: 💁
|
||||||
|
:information_source: ℹ️
|
||||||
|
:innocent: 😇
|
||||||
|
:interrobang: ⁉️
|
||||||
|
:iphone: 📱
|
||||||
|
:it: 🇮🇹
|
||||||
|
:izakaya_lantern: 🏮
|
||||||
|
:jack_o_lantern: 🎃
|
||||||
|
:japan: 🗾
|
||||||
|
:japanese_castle: 🏯
|
||||||
|
:japanese_goblin: 👺
|
||||||
|
:japanese_ogre: 👹
|
||||||
|
:jeans: 👖
|
||||||
|
:joy: 😂
|
||||||
|
:joy_cat: 😹
|
||||||
|
:jp: 🇯🇵
|
||||||
|
:key: 🔑
|
||||||
|
:keycap_ten: 🔟
|
||||||
|
:kimono: 👘
|
||||||
|
:kiss: 💋
|
||||||
|
:kissing: 😗
|
||||||
|
:kissing_cat: 😽
|
||||||
|
:kissing_closed_eyes: 😚
|
||||||
|
:kissing_heart: 😘
|
||||||
|
:kissing_smiling_eyes: 😙
|
||||||
|
:koala: 🐨
|
||||||
|
:koko: 🈁
|
||||||
|
:kr: 🇰🇷
|
||||||
|
:large_blue_diamond: 🔷
|
||||||
|
:large_orange_diamond: 🔶
|
||||||
|
:last_quarter_moon: 🌗
|
||||||
|
:last_quarter_moon_with_face: 🌜
|
||||||
|
:laughing: 😆
|
||||||
|
:leaves: 🍃
|
||||||
|
:ledger: 📒
|
||||||
|
:left_luggage: 🛅
|
||||||
|
:left_right_arrow: ↔️
|
||||||
|
:leftwards_arrow_with_hook: ↩️
|
||||||
|
:lemon: 🍋
|
||||||
|
:leo: ♌
|
||||||
|
:leopard: 🐆
|
||||||
|
:libra: ♎
|
||||||
|
:light_rail: 🚈
|
||||||
|
:link: 🔗
|
||||||
|
:lips: 👄
|
||||||
|
:lipstick: 💄
|
||||||
|
:lock: 🔒
|
||||||
|
:lock_with_ink_pen: 🔏
|
||||||
|
:lollipop: 🍭
|
||||||
|
:loop: ➿
|
||||||
|
:loudspeaker: 📢
|
||||||
|
:love_hotel: 🏩
|
||||||
|
:love_letter: 💌
|
||||||
|
:low_brightness: 🔅
|
||||||
|
:m: Ⓜ️
|
||||||
|
:mag: 🔍
|
||||||
|
:mag_right: 🔎
|
||||||
|
:mahjong: 🀄
|
||||||
|
:mailbox: 📫
|
||||||
|
:mailbox_closed: 📪
|
||||||
|
:mailbox_with_mail: 📬
|
||||||
|
:mailbox_with_no_mail: 📭
|
||||||
|
:man: 👨
|
||||||
|
:man_with_gua_pi_mao: 👲
|
||||||
|
:man_with_turban: 👳♂️
|
||||||
|
:mans_shoe: 👞
|
||||||
|
:maple_leaf: 🍁
|
||||||
|
:mask: 😷
|
||||||
|
:massage: 💆
|
||||||
|
:meat_on_bone: 🍖
|
||||||
|
:mega: 📣
|
||||||
|
:melon: 🍈
|
||||||
|
:memo: 📝
|
||||||
|
:mens: 🚹
|
||||||
|
:metal: 🤘
|
||||||
|
:metro: 🚇
|
||||||
|
:microphone: 🎤
|
||||||
|
:microscope: 🔬
|
||||||
|
:milky_way: 🌌
|
||||||
|
:minibus: 🚐
|
||||||
|
:minidisc: 💽
|
||||||
|
:mobile_phone_off: 📴
|
||||||
|
:money_with_wings: 💸
|
||||||
|
:moneybag: 💰
|
||||||
|
:monkey: 🐒
|
||||||
|
:monkey_face: 🐵
|
||||||
|
:monorail: 🚝
|
||||||
|
:mortar_board: 🎓
|
||||||
|
:mount_fuji: 🗻
|
||||||
|
:mountain_bicyclist: 🚵
|
||||||
|
:mountain_cableway: 🚠
|
||||||
|
:mountain_railway: 🚞
|
||||||
|
:mouse2: 🐁
|
||||||
|
:mouse: 🐭
|
||||||
|
:movie_camera: 🎥
|
||||||
|
:moyai: 🗿
|
||||||
|
:muscle: 💪
|
||||||
|
:mushroom: 🍄
|
||||||
|
:musical_keyboard: 🎹
|
||||||
|
:musical_note: 🎵
|
||||||
|
:musical_score: 🎼
|
||||||
|
:mute: 🔇
|
||||||
|
:nail_care: 💅
|
||||||
|
:name_badge: 📛
|
||||||
|
:necktie: 👔
|
||||||
|
:negative_squared_cross_mark: ❎
|
||||||
|
:neutral_face: 😐
|
||||||
|
:new: 🆕
|
||||||
|
:new_moon: 🌑
|
||||||
|
:new_moon_with_face: 🌚
|
||||||
|
:newspaper: 📰
|
||||||
|
:ng: 🆖
|
||||||
|
:nine: 9️⃣
|
||||||
|
:no_bell: 🔕
|
||||||
|
:no_bicycles: 🚳
|
||||||
|
:no_entry: ⛔
|
||||||
|
:no_entry_sign: 🚫
|
||||||
|
:no_good: 🙅
|
||||||
|
:no_mobile_phones: 📵
|
||||||
|
:no_mouth: 😶
|
||||||
|
:no_pedestrians: 🚷
|
||||||
|
:no_smoking: 🚭
|
||||||
|
:nose: 👃
|
||||||
|
:notebook: 📓
|
||||||
|
:notebook_with_decorative_cover: 📔
|
||||||
|
:notes: 🎶
|
||||||
|
:nut_and_bolt: 🔩
|
||||||
|
:o2: 🅾️
|
||||||
|
:o: ⭕
|
||||||
|
:ocean: 🌊
|
||||||
|
:octopus: 🐙
|
||||||
|
:oden: 🍢
|
||||||
|
:office: 🏢
|
||||||
|
:ok: 🆗
|
||||||
|
:ok_hand: 👌
|
||||||
|
:ok_woman: 🙆♀️
|
||||||
|
:older_man: 👴
|
||||||
|
:older_woman: 👵
|
||||||
|
:on: 🔛
|
||||||
|
:oncoming_automobile: 🚘
|
||||||
|
:oncoming_bus: 🚍
|
||||||
|
:oncoming_police_car: 🚔
|
||||||
|
:oncoming_taxi: 🚖
|
||||||
|
:one: 1️⃣
|
||||||
|
:open_file_folder: 📂
|
||||||
|
:open_hands: 👐
|
||||||
|
:open_mouth: 😮
|
||||||
|
:ophiuchus: ⛎
|
||||||
|
:orange_book: 📙
|
||||||
|
:outbox_tray: 📤
|
||||||
|
:ox: 🐂
|
||||||
|
:page_facing_up: 📄
|
||||||
|
:page_with_curl: 📃
|
||||||
|
:pager: 📟
|
||||||
|
:palm_tree: 🌴
|
||||||
|
:panda_face: 🐼
|
||||||
|
:paperclip: 📎
|
||||||
|
:parking: 🅿️
|
||||||
|
:part_alternation_mark: 〽️
|
||||||
|
:partly_sunny: ⛅
|
||||||
|
:passport_control: 🛂
|
||||||
|
:paw_prints: 🐾
|
||||||
|
:peach: 🍑
|
||||||
|
:pear: 🍐
|
||||||
|
:pencil2: ✏️
|
||||||
|
:pencil: 📝
|
||||||
|
:penguin: 🐧
|
||||||
|
:pensive: 😔
|
||||||
|
:performing_arts: 🎭
|
||||||
|
:persevere: 😣
|
||||||
|
:pig2: 🐖
|
||||||
|
:pig: 🐷
|
||||||
|
:pig_nose: 🐽
|
||||||
|
:pill: 💊
|
||||||
|
:pineapple: 🍍
|
||||||
|
:pisces: ♓
|
||||||
|
:pizza: 🍕
|
||||||
|
:point_down: 👇
|
||||||
|
:point_left: 👈
|
||||||
|
:point_right: 👉
|
||||||
|
:point_up: ☝️
|
||||||
|
:point_up_2: 👆
|
||||||
|
:police_car: 🚓
|
||||||
|
:poodle: 🐩
|
||||||
|
:poop: 💩
|
||||||
|
:post_office: 🏣
|
||||||
|
:postal_horn: 📯
|
||||||
|
:postbox: 📮
|
||||||
|
:potable_water: 🚰
|
||||||
|
:pouch: 👝
|
||||||
|
:poultry_leg: 🍗
|
||||||
|
:pound: 💷
|
||||||
|
:pouting_cat: 😾
|
||||||
|
:pray: 🙏
|
||||||
|
:princess: 👸
|
||||||
|
:punch: 👊
|
||||||
|
:purple_heart: 💜
|
||||||
|
:purse: 👛
|
||||||
|
:pushpin: 📌
|
||||||
|
:put_litter_in_its_place: 🚮
|
||||||
|
:question: ❓
|
||||||
|
:rabbit2: 🐇
|
||||||
|
:rabbit: 🐰
|
||||||
|
:racehorse: 🐎
|
||||||
|
:radio: 📻
|
||||||
|
:radio_button: 🔘
|
||||||
|
:rage: 😡
|
||||||
|
:railway_car: 🚃
|
||||||
|
:rainbow: 🌈
|
||||||
|
:raised_hand: ✋
|
||||||
|
:raised_hands: 🙌
|
||||||
|
:raising_hand: 🙋
|
||||||
|
:ram: 🐏
|
||||||
|
:ramen: 🍜
|
||||||
|
:rat: 🐀
|
||||||
|
:recycle: ♻️
|
||||||
|
:red_car: 🚗
|
||||||
|
:red_circle: 🔴
|
||||||
|
:registered: ®️
|
||||||
|
:relaxed: ☺️
|
||||||
|
:relieved: 😌
|
||||||
|
:repeat: 🔁
|
||||||
|
:repeat_one: 🔂
|
||||||
|
:restroom: 🚻
|
||||||
|
:revolving_hearts: 💞
|
||||||
|
:rewind: ⏪
|
||||||
|
:ribbon: 🎀
|
||||||
|
:rice: 🍚
|
||||||
|
:rice_ball: 🍙
|
||||||
|
:rice_cracker: 🍘
|
||||||
|
:rice_scene: 🎑
|
||||||
|
:ring: 💍
|
||||||
|
:rocket: 🚀
|
||||||
|
:roller_coaster: 🎢
|
||||||
|
:rooster: 🐓
|
||||||
|
:rose: 🌹
|
||||||
|
:rotating_light: 🚨
|
||||||
|
:round_pushpin: 📍
|
||||||
|
:rowboat: 🚣
|
||||||
|
:ru: 🇷🇺
|
||||||
|
:rugby_football: 🏉
|
||||||
|
:runner: 🏃
|
||||||
|
:running_shirt_with_sash: 🎽
|
||||||
|
:sa: 🈂️
|
||||||
|
:sagittarius: ♐
|
||||||
|
:sailboat: ⛵
|
||||||
|
:sake: 🍶
|
||||||
|
:sandal: 👡
|
||||||
|
:santa: 🎅
|
||||||
|
:satellite: 📡
|
||||||
|
:satisfied: 😆
|
||||||
|
:saxophone: 🎷
|
||||||
|
:school: 🏫
|
||||||
|
:school_satchel: 🎒
|
||||||
|
:scissors: ✂️
|
||||||
|
:scorpius: ♏
|
||||||
|
:scream: 😱
|
||||||
|
:scream_cat: 🙀
|
||||||
|
:scroll: 📜
|
||||||
|
:seat: 💺
|
||||||
|
:secret: ㊙️
|
||||||
|
:see_no_evil: 🙈
|
||||||
|
:seedling: 🌱
|
||||||
|
:seven: 7️⃣
|
||||||
|
:shaved_ice: 🍧
|
||||||
|
:sheep: 🐑
|
||||||
|
:shell: 🐚
|
||||||
|
:ship: 🚢
|
||||||
|
:shirt: 👕
|
||||||
|
:shit: 💩
|
||||||
|
:shower: 🚿
|
||||||
|
:signal_strength: 📶
|
||||||
|
:six: 6️⃣
|
||||||
|
:six_pointed_star: 🔯
|
||||||
|
:ski: 🎿
|
||||||
|
:skull: 💀
|
||||||
|
:sleeping: 😴
|
||||||
|
:sleepy: 😪
|
||||||
|
:slot_machine: 🎰
|
||||||
|
:small_blue_diamond: 🔹
|
||||||
|
:small_orange_diamond: 🔸
|
||||||
|
:small_red_triangle: 🔺
|
||||||
|
:small_red_triangle_down: 🔻
|
||||||
|
:smile: 😄
|
||||||
|
:smile_cat: 😸
|
||||||
|
:smiley: 😃
|
||||||
|
:smiley_cat: 😺
|
||||||
|
:smiling_imp: 😈
|
||||||
|
:smirk: 😏
|
||||||
|
:smirk_cat: 😼
|
||||||
|
:smoking: 🚬
|
||||||
|
:snail: 🐌
|
||||||
|
:snake: 🐍
|
||||||
|
:snowboarder: 🏂
|
||||||
|
:snowflake: ❄️
|
||||||
|
:snowman: ⛄
|
||||||
|
:sob: 😭
|
||||||
|
:soccer: ⚽
|
||||||
|
:soon: 🔜
|
||||||
|
:sos: 🆘
|
||||||
|
:sound: 🔉
|
||||||
|
:space_invader: 👾
|
||||||
|
:spades: ♠️
|
||||||
|
:spaghetti: 🍝
|
||||||
|
:sparkler: 🎇
|
||||||
|
:sparkles: ✨
|
||||||
|
:sparkling_heart: 💖
|
||||||
|
:speak_no_evil: 🙊
|
||||||
|
:speaker: 🔈
|
||||||
|
:speech_balloon: 💬
|
||||||
|
:speedboat: 🚤
|
||||||
|
:star2: 🌟
|
||||||
|
:star: ⭐
|
||||||
|
:stars: 🌠
|
||||||
|
:station: 🚉
|
||||||
|
:statue_of_liberty: 🗽
|
||||||
|
:steam_locomotive: 🚂
|
||||||
|
:stew: 🍲
|
||||||
|
:straight_ruler: 📏
|
||||||
|
:strawberry: 🍓
|
||||||
|
:stuck_out_tongue: 😛
|
||||||
|
:stuck_out_tongue_closed_eyes: 😝
|
||||||
|
:stuck_out_tongue_winking_eye: 😜
|
||||||
|
:sun_with_face: 🌞
|
||||||
|
:sunflower: 🌻
|
||||||
|
:sunglasses: 😎
|
||||||
|
:sunny: ☀️
|
||||||
|
:sunrise: 🌅
|
||||||
|
:sunrise_over_mountains: 🌄
|
||||||
|
:surfer: 🏄
|
||||||
|
:sushi: 🍣
|
||||||
|
:suspension_railway: 🚟
|
||||||
|
:sweat: 😓
|
||||||
|
:sweat_drops: 💦
|
||||||
|
:sweat_smile: 😅
|
||||||
|
:sweet_potato: 🍠
|
||||||
|
:swimmer: 🏊
|
||||||
|
:symbols: 🔣
|
||||||
|
:syringe: 💉
|
||||||
|
:tada: 🎉
|
||||||
|
:tanabata_tree: 🎋
|
||||||
|
:tangerine: 🍊
|
||||||
|
:taurus: ♉
|
||||||
|
:taxi: 🚕
|
||||||
|
:tea: 🍵
|
||||||
|
:telephone: ☎️
|
||||||
|
:telephone_receiver: 📞
|
||||||
|
:telescope: 🔭
|
||||||
|
:tennis: 🎾
|
||||||
|
:tent: ⛺
|
||||||
|
:thought_balloon: 💭
|
||||||
|
:three: 3️⃣
|
||||||
|
:thumbsdown: 👎
|
||||||
|
:thumbsup: 👍
|
||||||
|
:ticket: 🎫
|
||||||
|
:tiger2: 🐅
|
||||||
|
:tiger: 🐯
|
||||||
|
:tired_face: 😫
|
||||||
|
:tm: ™️
|
||||||
|
:toilet: 🚽
|
||||||
|
:tokyo_tower: 🗼
|
||||||
|
:tomato: 🍅
|
||||||
|
:tongue: 👅
|
||||||
|
:top: 🔝
|
||||||
|
:tophat: 🎩
|
||||||
|
:tractor: 🚜
|
||||||
|
:traffic_light: 🚥
|
||||||
|
:train2: 🚆
|
||||||
|
:train: 🚋
|
||||||
|
:tram: 🚊
|
||||||
|
:triangular_flag_on_post: 🚩
|
||||||
|
:triangular_ruler: 📐
|
||||||
|
:trident: 🔱
|
||||||
|
:triumph: 😤
|
||||||
|
:trolleybus: 🚎
|
||||||
|
:trophy: 🏆
|
||||||
|
:tropical_drink: 🍹
|
||||||
|
:tropical_fish: 🐠
|
||||||
|
:truck: 🚚
|
||||||
|
:trumpet: 🎺
|
||||||
|
:tulip: 🌷
|
||||||
|
:turtle: 🐢
|
||||||
|
:tv: 📺
|
||||||
|
:twisted_rightwards_arrows: 🔀
|
||||||
|
:two: 2️⃣
|
||||||
|
:two_men_holding_hands: 👬
|
||||||
|
:two_women_holding_hands: 👭
|
||||||
|
:u5272: 🈹
|
||||||
|
:u5408: 🈴
|
||||||
|
:u55b6: 🈺
|
||||||
|
:u6307: 🈯
|
||||||
|
:u6708: 🈷️
|
||||||
|
:u6709: 🈶
|
||||||
|
:u6e80: 🈵
|
||||||
|
:u7121: 🈚
|
||||||
|
:u7533: 🈸
|
||||||
|
:u7981: 🈲
|
||||||
|
:u7a7a: 🈳
|
||||||
|
:umbrella: ☔
|
||||||
|
:unamused: 😒
|
||||||
|
:underage: 🔞
|
||||||
|
:unlock: 🔓
|
||||||
|
:up: 🆙
|
||||||
|
:us: 🇺🇸
|
||||||
|
:v: ✌️
|
||||||
|
:vertical_traffic_light: 🚦
|
||||||
|
:vhs: 📼
|
||||||
|
:vibration_mode: 📳
|
||||||
|
:video_camera: 📹
|
||||||
|
:video_game: 🎮
|
||||||
|
:violin: 🎻
|
||||||
|
:virgo: ♍
|
||||||
|
:volcano: 🌋
|
||||||
|
:vs: 🆚
|
||||||
|
:walking: 🚶
|
||||||
|
:waning_crescent_moon: 🌘
|
||||||
|
:waning_gibbous_moon: 🌖
|
||||||
|
:warning: ⚠️
|
||||||
|
:watch: ⌚
|
||||||
|
:water_buffalo: 🐃
|
||||||
|
:watermelon: 🍉
|
||||||
|
:wave: 👋
|
||||||
|
:wavy_dash: 〰️
|
||||||
|
:waxing_crescent_moon: 🌒
|
||||||
|
:waxing_gibbous_moon: 🌔
|
||||||
|
:wc: 🚾
|
||||||
|
:weary: 😩
|
||||||
|
:wedding: 💒
|
||||||
|
:whale2: 🐋
|
||||||
|
:whale: 🐳
|
||||||
|
:wheelchair: ♿
|
||||||
|
:white_check_mark: ✅
|
||||||
|
:white_circle: ⚪
|
||||||
|
:white_flower: 💮
|
||||||
|
:white_square_button: 🔳
|
||||||
|
:wind_chime: 🎐
|
||||||
|
:wine_glass: 🍷
|
||||||
|
:wink: 😉
|
||||||
|
:wolf: 🐺
|
||||||
|
:woman: 👩
|
||||||
|
:womans_clothes: 👚
|
||||||
|
:womans_hat: 👒
|
||||||
|
:womens: 🚺
|
||||||
|
:worried: 😟
|
||||||
|
:wrench: 🔧
|
||||||
|
:x: ❌
|
||||||
|
:yellow_heart: 💛
|
||||||
|
:yen: 💴
|
||||||
|
:yum: 😋
|
||||||
|
:zap: ⚡
|
||||||
|
:zero: 0️⃣
|
||||||
|
:zzz: 💤
|
||||||
|
@@ -8,7 +8,7 @@ BEGIN { fn_count = 0 }
|
|||||||
text = substr($0, id_end + 2)
|
text = substr($0, id_end + 2)
|
||||||
# Trim leading space
|
# Trim leading space
|
||||||
sub(/^[ \t]+/, "", text)
|
sub(/^[ \t]+/, "", text)
|
||||||
|
|
||||||
fn_ids[++fn_count] = id
|
fn_ids[++fn_count] = id
|
||||||
fn_texts[id] = text
|
fn_texts[id] = text
|
||||||
next
|
next
|
||||||
@@ -21,19 +21,19 @@ BEGIN { fn_count = 0 }
|
|||||||
END {
|
END {
|
||||||
for (i = 1; i <= line_count; i++) {
|
for (i = 1; i <= line_count; i++) {
|
||||||
line = lines[i]
|
line = lines[i]
|
||||||
|
|
||||||
for (j = 1; j <= fn_count; j++) {
|
for (j = 1; j <= fn_count; j++) {
|
||||||
id = fn_ids[j]
|
id = fn_ids[j]
|
||||||
marker = "[^" id "]"
|
marker = "[^" id "]"
|
||||||
repl = "<sup><a href=\"#fn:" id "\" id=\"fnref:" id "\">" id "</a></sup>"
|
repl = "<sup><a href=\"#fn:" id "\" id=\"fnref:" id "\">" id "</a></sup>"
|
||||||
|
|
||||||
while ((pos = index(line, marker)) > 0) {
|
while ((pos = index(line, marker)) > 0) {
|
||||||
line = substr(line, 1, pos - 1) repl substr(line, pos + length(marker))
|
line = substr(line, 1, pos - 1) repl substr(line, pos + length(marker))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print line
|
print line
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fn_count > 0) {
|
if (fn_count > 0) {
|
||||||
print "<hr />"
|
print "<hr />"
|
||||||
print "<section class=\"footnotes\">"
|
print "<section class=\"footnotes\">"
|
||||||
|
|||||||
@@ -3,6 +3,15 @@ function title_from_name(name) {
|
|||||||
gsub(/-/, " ", name)
|
gsub(/-/, " ", name)
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
function url_encode_path(path) {
|
||||||
|
gsub(/%/, "%25", path)
|
||||||
|
gsub(/ /, "%20", path)
|
||||||
|
gsub(/#/, "%23", path)
|
||||||
|
gsub(/\?/, "%3F", path)
|
||||||
|
gsub(/"/, "%22", path)
|
||||||
|
gsub(/'/, "%27", path)
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
function get_title(path, default_title, full_path, line, title, in_fm) {
|
function get_title(path, default_title, full_path, line, title, in_fm) {
|
||||||
full_path = src "/" path
|
full_path = src "/" path
|
||||||
@@ -172,7 +181,7 @@ END {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
printf "<li><a href=\"/%sindex.html\">%s</a><ul>\n", dir_path, get_title(this_d, title_from_name(parts[i]))
|
printf "<li><a href=\"/%sindex.html\">%s</a><ul>\n", url_encode_path(dir_path), get_title(this_d, title_from_name(parts[i]))
|
||||||
opened_levels[++depth] = i
|
opened_levels[++depth] = i
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +192,7 @@ END {
|
|||||||
is_single = (single_file_index == "true" && md_count[curr_dir] == 1 && !has_index[curr_dir])
|
is_single = (single_file_index == "true" && md_count[curr_dir] == 1 && !has_index[curr_dir])
|
||||||
|
|
||||||
if (parts[n] != "index.md" && !is_single) {
|
if (parts[n] != "index.md" && !is_single) {
|
||||||
path = "/" rel
|
path = url_encode_path("/" rel)
|
||||||
gsub(/\.md$/, ".html", path)
|
gsub(/\.md$/, ".html", path)
|
||||||
printf "<li><a href=\"%s\">%s</a></li>\n", path, get_title(rel, title_from_name(parts[n]))
|
printf "<li><a href=\"%s\">%s</a></li>\n", path, get_title(rel, title_from_name(parts[n]))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,31 @@ function strip_markdown(s) {
|
|||||||
gsub(/-+$/, "", s)
|
gsub(/-+$/, "", s)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
function unique_id(raw_id, candidate) {
|
||||||
|
candidate = raw_id
|
||||||
|
if (candidate == "") candidate = "section"
|
||||||
|
if (!(candidate in seen_ids)) {
|
||||||
|
seen_ids[candidate] = 1
|
||||||
|
return candidate
|
||||||
|
}
|
||||||
|
seen_ids[candidate]++
|
||||||
|
return candidate "-" seen_ids[candidate]
|
||||||
|
}
|
||||||
|
function has_inline_link(line) {
|
||||||
|
return (index(line, "<a ") > 0 || index(line, "<a\t") > 0)
|
||||||
|
}
|
||||||
|
function print_heading(tag, line, id) {
|
||||||
|
id = unique_id(strip_markdown(line))
|
||||||
|
if (enable_header_links == "true") {
|
||||||
|
if (has_inline_link(line)) {
|
||||||
|
print "<" tag " id=\"" id "\">" line " <a href=\"#" id "\" class=\"header-anchor\" aria-label=\"Link to this section\">#</a></" tag ">"
|
||||||
|
} else {
|
||||||
|
print "<" tag " id=\"" id "\"><a href=\"#" id "\" class=\"header-link\">" line "<span class=\"header-anchor\" aria-hidden=\"true\">#</span></a></" tag ">"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print "<" tag " id=\"" id "\">" line "</" tag ">"
|
||||||
|
}
|
||||||
|
}
|
||||||
function print_header(line) {
|
function print_header(line) {
|
||||||
tag = ""
|
tag = ""
|
||||||
if (line ~ /^# /) { tag = "h1"; sub(/^# /, "", line) }
|
if (line ~ /^# /) { tag = "h1"; sub(/^# /, "", line) }
|
||||||
@@ -23,12 +48,7 @@ function print_header(line) {
|
|||||||
else if (line ~ /^###### /) { tag = "h6"; sub(/^###### /, "", line) }
|
else if (line ~ /^###### /) { tag = "h6"; sub(/^###### /, "", line) }
|
||||||
|
|
||||||
if (tag != "") {
|
if (tag != "") {
|
||||||
id = strip_markdown(line)
|
print_heading(tag, line)
|
||||||
if (enable_header_links == "true") {
|
|
||||||
print "<" tag " id=\"" id "\"><a href=\"#" id "\" class=\"header-anchor\">" line "</a></" tag ">"
|
|
||||||
} else {
|
|
||||||
print "<" tag " id=\"" id "\">" line "</" tag ">"
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
print line
|
print line
|
||||||
}
|
}
|
||||||
@@ -52,7 +72,7 @@ BEGIN {
|
|||||||
|
|
||||||
if ($0 ~ /^=+$/) {
|
if ($0 ~ /^=+$/) {
|
||||||
if (has_prev && prev != "" && prev !~ /^<[a-z]/) {
|
if (has_prev && prev != "" && prev !~ /^<[a-z]/) {
|
||||||
print "<h1 id=\"" strip_markdown(prev) "\">" prev "</h1>"
|
print_heading("h1", prev)
|
||||||
has_prev = 0
|
has_prev = 0
|
||||||
} else {
|
} else {
|
||||||
if (has_prev) print_header(prev)
|
if (has_prev) print_header(prev)
|
||||||
@@ -61,7 +81,7 @@ BEGIN {
|
|||||||
}
|
}
|
||||||
} else if ($0 ~ /^-+$/) {
|
} else if ($0 ~ /^-+$/) {
|
||||||
if (has_prev && prev != "" && prev !~ /^<[a-z]/) {
|
if (has_prev && prev != "" && prev !~ /^<[a-z]/) {
|
||||||
print "<h2 id=\"" strip_markdown(prev) "\">" prev "</h2>"
|
print_heading("h2", prev)
|
||||||
has_prev = 0
|
has_prev = 0
|
||||||
} else {
|
} else {
|
||||||
if (has_prev) print_header(prev)
|
if (has_prev) print_header(prev)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ BEGIN { in_code = 0; in_html_pre = 0 }
|
|||||||
{
|
{
|
||||||
if ($0 ~ /<pre>/) in_html_pre = 1
|
if ($0 ~ /<pre>/) in_html_pre = 1
|
||||||
if ($0 ~ /<\/pre>/) { in_html_pre = 0; if (in_code) { print "</code></pre>"; in_code = 0 }; print; next }
|
if ($0 ~ /<\/pre>/) { in_html_pre = 0; if (in_code) { print "</code></pre>"; in_code = 0 }; print; next }
|
||||||
|
|
||||||
if (!in_html_pre && $0 ~ /^(\t| )/) {
|
if (!in_html_pre && $0 ~ /^(\t| )/) {
|
||||||
if (!in_code) { printf "%s", "<pre><code>"; in_code = 1 }
|
if (!in_code) { printf "%s", "<pre><code>"; in_code = 1 }
|
||||||
sub(/^(\t| )/, "", $0)
|
sub(/^(\t| )/, "", $0)
|
||||||
@@ -10,7 +10,7 @@ BEGIN { in_code = 0; in_html_pre = 0 }
|
|||||||
print
|
print
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_code) {
|
if (in_code) {
|
||||||
print "</code></pre>"
|
print "</code></pre>"
|
||||||
in_code = 0
|
in_code = 0
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ BEGIN {
|
|||||||
# get indentation level
|
# get indentation level
|
||||||
match(line, /^[ \t]*/)
|
match(line, /^[ \t]*/)
|
||||||
indent = RLENGTH
|
indent = RLENGTH
|
||||||
|
|
||||||
if (depth == 0 || indent > cur_indent[depth]) {
|
if (depth == 0 || indent > cur_indent[depth]) {
|
||||||
depth++
|
depth++
|
||||||
cur_indent[depth] = indent
|
cur_indent[depth] = indent
|
||||||
|
|||||||
@@ -140,18 +140,18 @@ function css_highlight_line(line, m, prop, val) {
|
|||||||
match(line, /:[[:space:]]*/)
|
match(line, /:[[:space:]]*/)
|
||||||
sep_pos = RSTART
|
sep_pos = RSTART
|
||||||
sep_len = RLENGTH
|
sep_len = RLENGTH
|
||||||
|
|
||||||
pre_sep = substr(line, 1, sep_pos - 1)
|
pre_sep = substr(line, 1, sep_pos - 1)
|
||||||
sep = substr(line, sep_pos, sep_len)
|
sep = substr(line, sep_pos, sep_len)
|
||||||
post_sep = substr(line, sep_pos + sep_len)
|
post_sep = substr(line, sep_pos + sep_len)
|
||||||
|
|
||||||
match(pre_sep, /--?[A-Za-z0-9_-]+/)
|
match(pre_sep, /--?[A-Za-z0-9_-]+/)
|
||||||
prop_pos = RSTART
|
prop_pos = RSTART
|
||||||
prop_len = RLENGTH
|
prop_len = RLENGTH
|
||||||
|
|
||||||
indent = substr(pre_sep, 1, prop_pos - 1)
|
indent = substr(pre_sep, 1, prop_pos - 1)
|
||||||
prop_name = substr(pre_sep, prop_pos, prop_len)
|
prop_name = substr(pre_sep, prop_pos, prop_len)
|
||||||
|
|
||||||
if (match(post_sep, /;[[:space:]]*$/)) {
|
if (match(post_sep, /;[[:space:]]*$/)) {
|
||||||
val_part = substr(post_sep, 1, RSTART - 1)
|
val_part = substr(post_sep, 1, RSTART - 1)
|
||||||
suffix = substr(post_sep, RSTART)
|
suffix = substr(post_sep, RSTART)
|
||||||
@@ -159,11 +159,11 @@ function css_highlight_line(line, m, prop, val) {
|
|||||||
val_part = post_sep
|
val_part = post_sep
|
||||||
suffix = ""
|
suffix = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
prop = "<span class=\"tok-prop\">" prop_name "</span>"
|
prop = "<span class=\"tok-prop\">" prop_name "</span>"
|
||||||
gsub(/var\(--[A-Za-z0-9_-]+\)/, "<span class=\"tok-var\">&</span>", val_part)
|
gsub(/var\(--[A-Za-z0-9_-]+\)/, "<span class=\"tok-var\">&</span>", val_part)
|
||||||
val = "<span class=\"tok-val\">" val_part "</span>"
|
val = "<span class=\"tok-val\">" val_part "</span>"
|
||||||
|
|
||||||
return indent prop sep val suffix
|
return indent prop sep val suffix
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,6 +375,13 @@ function rewrite_img_tags(line, out, rest, tag, src, alt, force_inline_tag, e
|
|||||||
} else if (is_image_ext(ext_of(src)) && force_inline_tag == "") {
|
} else if (is_image_ext(ext_of(src)) && force_inline_tag == "") {
|
||||||
# Preserve hand-written <img> attributes (style/class/etc) for normal images.
|
# Preserve hand-written <img> attributes (style/class/etc) for normal images.
|
||||||
repl = tag
|
repl = tag
|
||||||
|
} else if (force_inline_tag != "" && !is_global_url(src) && is_inline_text_ext(ext_of(src))) {
|
||||||
|
repl = render_code_include(src, 1)
|
||||||
|
if (repl != "") {
|
||||||
|
repl = "<pre><code>" repl "</code></pre>"
|
||||||
|
} else {
|
||||||
|
repl = render_embed(src, alt, (alt != ""), 1)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
repl = render_embed(src, alt, (alt != ""), (force_inline_tag != ""))
|
repl = render_embed(src, alt, (alt != ""), (force_inline_tag != ""))
|
||||||
}
|
}
|
||||||
@@ -399,7 +406,12 @@ function rewrite_double_bang_with_parens(line, out, rest, token, inside, src,
|
|||||||
src = substr(inside, sep + 2)
|
src = substr(inside, sep + 2)
|
||||||
sub(/\)$/, "", src)
|
sub(/\)$/, "", src)
|
||||||
|
|
||||||
repl = render_embed(src, alt, (alt != ""), 1)
|
repl = render_code_include(src, 1)
|
||||||
|
if (repl != "") {
|
||||||
|
repl = "<pre><code>" repl "</code></pre>"
|
||||||
|
} else {
|
||||||
|
repl = render_embed(src, alt, (alt != ""), 1)
|
||||||
|
}
|
||||||
out = out pre repl
|
out = out pre repl
|
||||||
rest = post
|
rest = post
|
||||||
}
|
}
|
||||||
@@ -416,7 +428,12 @@ function rewrite_double_bang_bare(line, out, rest, token, src, pre, post, rep
|
|||||||
src = token
|
src = token
|
||||||
sub(/^!!\[/, "", src)
|
sub(/^!!\[/, "", src)
|
||||||
sub(/\]$/, "", src)
|
sub(/\]$/, "", src)
|
||||||
repl = render_embed(src, "", 0, 1)
|
repl = render_code_include(src, 1)
|
||||||
|
if (repl != "") {
|
||||||
|
repl = "<pre><code>" repl "</code></pre>"
|
||||||
|
} else {
|
||||||
|
repl = render_embed(src, "", 0, 1)
|
||||||
|
}
|
||||||
out = out pre repl
|
out = out pre repl
|
||||||
rest = post
|
rest = post
|
||||||
}
|
}
|
||||||
@@ -576,6 +593,75 @@ function restore_plain_markers(line) {
|
|||||||
return line
|
return line
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function break_code_double_bang(line, out, rest, pstart, pend, code_content, token, pre, post, inside, sep, src, alt, repl) {
|
||||||
|
out = ""
|
||||||
|
rest = line
|
||||||
|
while (1) {
|
||||||
|
pstart = index(rest, "<code>")
|
||||||
|
if (pstart == 0) {
|
||||||
|
out = out rest
|
||||||
|
break
|
||||||
|
}
|
||||||
|
out = out substr(rest, 1, pstart - 1)
|
||||||
|
rest = substr(rest, pstart)
|
||||||
|
pend = index(substr(rest, 7), "</code>")
|
||||||
|
if (pend == 0) {
|
||||||
|
out = out rest
|
||||||
|
break
|
||||||
|
}
|
||||||
|
pend = pend + 6
|
||||||
|
code_content = substr(rest, 7, pend - 7)
|
||||||
|
rest = substr(rest, pend + 7)
|
||||||
|
if (match(code_content, /!!\[[^\]]*\]\([^)]*\)/)) {
|
||||||
|
token = substr(code_content, RSTART, RLENGTH)
|
||||||
|
pre = substr(code_content, 1, RSTART - 1)
|
||||||
|
post = substr(code_content, RSTART + RLENGTH)
|
||||||
|
inside = token
|
||||||
|
sub(/^!!\[/, "", inside)
|
||||||
|
sep = index(inside, "](")
|
||||||
|
alt = substr(inside, 1, sep - 1)
|
||||||
|
src = substr(inside, sep + 2)
|
||||||
|
sub(/\)$/, "", src)
|
||||||
|
repl = render_code_include(src, 1)
|
||||||
|
if (repl != "") {
|
||||||
|
repl = "<pre><code>" repl "</code></pre>"
|
||||||
|
} else {
|
||||||
|
repl = render_embed(src, alt, (alt != ""), 1)
|
||||||
|
}
|
||||||
|
if (repl == "") {
|
||||||
|
out = out "<code>" code_content "</code>"
|
||||||
|
} else {
|
||||||
|
if (pre != "") out = out "<code>" pre "</code>"
|
||||||
|
out = out repl
|
||||||
|
if (post != "") out = out "<code>" post "</code>"
|
||||||
|
}
|
||||||
|
} else if (match(code_content, /!!\[[^\]]+\]/)) {
|
||||||
|
token = substr(code_content, RSTART, RLENGTH)
|
||||||
|
pre = substr(code_content, 1, RSTART - 1)
|
||||||
|
post = substr(code_content, RSTART + RLENGTH)
|
||||||
|
src = token
|
||||||
|
sub(/^!!\[/, "", src)
|
||||||
|
sub(/\]$/, "", src)
|
||||||
|
repl = render_code_include(src, 1)
|
||||||
|
if (repl != "") {
|
||||||
|
repl = "<pre><code>" repl "</code></pre>"
|
||||||
|
} else {
|
||||||
|
repl = render_embed(src, "", 0, 1)
|
||||||
|
}
|
||||||
|
if (repl == "") {
|
||||||
|
out = out "<code>" code_content "</code>"
|
||||||
|
} else {
|
||||||
|
if (pre != "") out = out "<code>" pre "</code>"
|
||||||
|
out = out repl
|
||||||
|
if (post != "") out = out "<code>" post "</code>"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out = out "<code>" code_content "</code>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
input_dir = dirname_of(input_file)
|
input_dir = dirname_of(input_file)
|
||||||
in_pre_code = 0
|
in_pre_code = 0
|
||||||
@@ -601,6 +687,9 @@ BEGIN {
|
|||||||
|
|
||||||
line = apply_td_vertical_align(line)
|
line = apply_td_vertical_align(line)
|
||||||
line = restore_plain_markers(line)
|
line = restore_plain_markers(line)
|
||||||
|
if (!(in_pre_code || start_pre)) {
|
||||||
|
line = break_code_double_bang(line)
|
||||||
|
}
|
||||||
print line
|
print line
|
||||||
|
|
||||||
if (start_pre && !end_pre) {
|
if (start_pre && !end_pre) {
|
||||||
|
|||||||
@@ -46,14 +46,9 @@ function mask(s, t) {
|
|||||||
while (match(substr(line, p), /`+/)) {
|
while (match(substr(line, p), /`+/)) {
|
||||||
pstart = p + RSTART - 1
|
pstart = p + RSTART - 1
|
||||||
plen = RLENGTH
|
plen = RLENGTH
|
||||||
if (plen >= 3) {
|
|
||||||
out = out substr(line, p, pstart - p + plen)
|
|
||||||
p = pstart + plen
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
# Found 1 or 2 backticks at pstart
|
# Found backtick sequence at pstart
|
||||||
# Search for closing marker
|
# Search for closing marker of same length
|
||||||
marker = substr(line, pstart, plen)
|
marker = substr(line, pstart, plen)
|
||||||
tail = substr(line, pstart + plen)
|
tail = substr(line, pstart + plen)
|
||||||
mpos = index(tail, marker)
|
mpos = index(tail, marker)
|
||||||
@@ -65,13 +60,24 @@ function mask(s, t) {
|
|||||||
p = pstart + plen
|
p = pstart + plen
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
# Found match!
|
# Found match!
|
||||||
content = substr(tail, 1, mpos - 1)
|
content = substr(tail, 1, mpos - 1)
|
||||||
out = out substr(line, p, pstart - p)
|
out = out substr(line, p, pstart - p)
|
||||||
if (plen == 2 && substr(content, 1, 1) == " " && substr(content, length(content), 1) == " ") {
|
if (plen >= 2 && substr(content, 1, 1) == " " && substr(content, length(content), 1) == " ") {
|
||||||
content = substr(content, 2, length(content) - 2)
|
content = substr(content, 2, length(content) - 2)
|
||||||
}
|
}
|
||||||
|
if (content ~ /!!\[/) {
|
||||||
|
_rb_test = content
|
||||||
|
gsub(/!!\[[^\]]*\]\([^)]*\)/, "", _rb_test)
|
||||||
|
gsub(/!!\[[^\]]+\]/, "", _rb_test)
|
||||||
|
gsub(/[[:space:]]+/, "", _rb_test)
|
||||||
|
if (_rb_test == "") {
|
||||||
|
out = out content
|
||||||
|
p = pstart + plen + mpos + plen - 1
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
out = out "<code>" mask(content) "</code>"
|
out = out "<code>" mask(content) "</code>"
|
||||||
p = pstart + plen + mpos + plen - 1
|
p = pstart + plen + mpos + plen - 1
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ BEGIN { in_plain = 0; in_script_style = 0 }
|
|||||||
script_start = RSTART; script_len = RLENGTH
|
script_start = RSTART; script_len = RLENGTH
|
||||||
pos_style = match(tolower(tmp_line), /<style([ >]|$)/)
|
pos_style = match(tolower(tmp_line), /<style([ >]|$)/)
|
||||||
style_start = RSTART; style_len = RLENGTH
|
style_start = RSTART; style_len = RLENGTH
|
||||||
|
|
||||||
if (pos_script == 0 && pos_style == 0) {
|
if (pos_script == 0 && pos_style == 0) {
|
||||||
out2 = out2 tmp_line
|
out2 = out2 tmp_line
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ BEGIN {
|
|||||||
|
|
||||||
{
|
{
|
||||||
if ($0 ~ /<pre>/) in_pre = 1
|
if ($0 ~ /<pre>/) in_pre = 1
|
||||||
|
|
||||||
if (in_pre) {
|
if (in_pre) {
|
||||||
if (in_p) { print "</p>"; in_p = 0 }
|
if (in_p) { print "</p>"; in_p = 0 }
|
||||||
print
|
print
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ END {
|
|||||||
in_pre = 0
|
in_pre = 0
|
||||||
i = 1
|
i = 1
|
||||||
while (i <= count) {
|
while (i <= count) {
|
||||||
if (lines[i] ~ /^<pre><code>/) {
|
if (lines[i] ~ /^<pre><code/) {
|
||||||
in_pre = 1
|
in_pre = 1
|
||||||
print lines[i]
|
print lines[i]
|
||||||
i++
|
i++
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ BEGIN {
|
|||||||
style_path = ENVIRON["AWK_STYLE_PATH"]
|
style_path = ENVIRON["AWK_STYLE_PATH"]
|
||||||
head_extra = ENVIRON["AWK_HEAD_EXTRA"]
|
head_extra = ENVIRON["AWK_HEAD_EXTRA"]
|
||||||
header_brand = ENVIRON["AWK_HEADER_BRAND"]
|
header_brand = ENVIRON["AWK_HEADER_BRAND"]
|
||||||
|
header_search = ENVIRON["AWK_HEADER_SEARCH"]
|
||||||
lang = ENVIRON["AWK_LANG"]
|
lang = ENVIRON["AWK_LANG"]
|
||||||
version = ENVIRON["AWK_VERSION"]
|
version = ENVIRON["AWK_VERSION"]
|
||||||
content_warning = ENVIRON["AWK_CONTENT_WARNING"]
|
content_warning = ENVIRON["AWK_CONTENT_WARNING"]
|
||||||
@@ -33,6 +34,7 @@ BEGIN {
|
|||||||
line = replace_all(line, "{{CSS}}", style_path)
|
line = replace_all(line, "{{CSS}}", style_path)
|
||||||
line = replace_all(line, "{{HEAD_EXTRA}}", head_extra)
|
line = replace_all(line, "{{HEAD_EXTRA}}", head_extra)
|
||||||
line = replace_all(line, "{{HEADER_BRAND}}", header_brand)
|
line = replace_all(line, "{{HEADER_BRAND}}", header_brand)
|
||||||
|
line = replace_all(line, "{{HEADER_SEARCH}}", header_search)
|
||||||
line = replace_all(line, "{{VERSION}}", version)
|
line = replace_all(line, "{{VERSION}}", version)
|
||||||
|
|
||||||
pos = index(line, "{{CONTENT}}")
|
pos = index(line, "{{CONTENT}}")
|
||||||
|
|||||||
@@ -18,17 +18,17 @@ BEGIN {
|
|||||||
if (title_end > 0) {
|
if (title_end > 0) {
|
||||||
title = substr(title_str, 1, title_end - 1)
|
title = substr(title_str, 1, title_end - 1)
|
||||||
gsub(/<[^>]+>/, "", title)
|
gsub(/<[^>]+>/, "", title)
|
||||||
|
|
||||||
# extract id
|
# extract id
|
||||||
id_start = match($0, /id="[^"]*"/)
|
id_start = match($0, /id="[^"]*"/)
|
||||||
if (id_start > 0) {
|
if (id_start > 0) {
|
||||||
id_str = substr($0, id_start + 4)
|
id_str = substr($0, id_start + 4)
|
||||||
id_end = index(id_str, "\"")
|
id_end = index(id_str, "\"")
|
||||||
id = substr(id_str, 1, id_end - 1)
|
id = substr(id_str, 1, id_end - 1)
|
||||||
|
|
||||||
# what tag? level
|
# what tag? level
|
||||||
level = substr($0, match($0, /<h[23]/) + 2, 1)
|
level = substr($0, match($0, /<h[23]/) + 2, 1)
|
||||||
|
|
||||||
if (level == "2") {
|
if (level == "2") {
|
||||||
toc_str = toc_str "<li class=\"toc-h2\"><a href=\"#" id "\">" title "</a></li>\n"
|
toc_str = toc_str "<li class=\"toc-h2\"><a href=\"#" id "\">" title "</a></li>\n"
|
||||||
} else if (level == "3") {
|
} else if (level == "3") {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
BEGIN {
|
BEGIN {
|
||||||
new_title = ENVIRON["AWK_NEW_TITLE"]
|
new_title = ENVIRON["AWK_NEW_TITLE"]
|
||||||
done = 0
|
done = 0
|
||||||
}
|
}
|
||||||
/^title[[:space:]]*=/ {
|
/^title[[:space:]]*=/ {
|
||||||
print "title = \"" new_title "\""
|
print "title = \"" new_title "\""
|
||||||
|
|||||||
BIN
button.gif
BIN
button.gif
Binary file not shown.
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 1.5 KiB |
49
button.svg
Normal file
49
button.svg
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="88"
|
||||||
|
height="31"
|
||||||
|
viewBox="0 0 88 31"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="bg-grad" x1="0" y1="0" x2="1" y2="1">
|
||||||
|
<stop offset="0%" stop-color="#4a3b69" />
|
||||||
|
<stop offset="100%" stop-color="#352654" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<rect width="88" height="31" fill="#000" />
|
||||||
|
<rect x="1" y="1" width="86" height="29" fill="url(#bg-grad)" />
|
||||||
|
<text
|
||||||
|
x="5"
|
||||||
|
y="12"
|
||||||
|
font-family="Georgia, 'Times New Roman', Times, serif"
|
||||||
|
font-size="10"
|
||||||
|
font-weight="bold"
|
||||||
|
fill="#debfff"
|
||||||
|
style="letter-spacing: -0.5px;"
|
||||||
|
>made</text>
|
||||||
|
<text
|
||||||
|
x="5"
|
||||||
|
y="22"
|
||||||
|
font-family="Georgia, 'Times New Roman', Times, serif"
|
||||||
|
font-size="10"
|
||||||
|
font-weight="bold"
|
||||||
|
fill="#debfff"
|
||||||
|
style="letter-spacing: -0.5px;"
|
||||||
|
>with</text>
|
||||||
|
<text
|
||||||
|
x="80"
|
||||||
|
y="16"
|
||||||
|
text-anchor="end"
|
||||||
|
dominant-baseline="central"
|
||||||
|
font-family="Georgia, 'Times New Roman', Times, serif"
|
||||||
|
font-size="28"
|
||||||
|
font-weight="bold"
|
||||||
|
font-style="italic"
|
||||||
|
fill="#debfff"
|
||||||
|
letter-spacing="-2"
|
||||||
|
>kewt</text>
|
||||||
|
<rect x="1" y="1" width="86" height="1" fill="#ffffff" fill-opacity="0.2" />
|
||||||
|
<rect x="1" y="2" width="1" height="27" fill="#ffffff" fill-opacity="0.2" />
|
||||||
|
<rect x="1" y="29" width="86" height="1" fill="#000000" fill-opacity="0.4" />
|
||||||
|
<rect x="86" y="2" width="1" height="28" fill="#000000" fill-opacity="0.4" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
608
lib/builder.sh
Normal file
608
lib/builder.sh
Normal file
@@ -0,0 +1,608 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
needs_rebuild() {
|
||||||
|
src_file="$1"
|
||||||
|
out_file="$2"
|
||||||
|
[ ! -f "$out_file" ] && return 0
|
||||||
|
[ "$src_file" -nt "$out_file" ] && return 0
|
||||||
|
[ -f "./site.conf" ] && [ "./site.conf" -nt "$out_file" ] && return 0
|
||||||
|
[ -f "$src/site.conf" ] && [ "$src/site.conf" -nt "$out_file" ] && return 0
|
||||||
|
[ -f "$template" ] && [ "$template" -nt "$out_file" ] && return 0
|
||||||
|
[ -f "$script_dir/styles/$style.css" ] && [ "$script_dir/styles/$style.css" -nt "$out_file" ] && return 0
|
||||||
|
[ -f "$script_dir/styles/$style.root.css" ] && [ "$script_dir/styles/$style.root.css" -nt "$out_file" ] && return 0
|
||||||
|
[ -f "$src/styles.root.css" ] && [ "$src/styles.root.css" -nt "$out_file" ] && return 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
write_content_warning_outputs() {
|
||||||
|
_source_file="$1"
|
||||||
|
_content_out_file="$2"
|
||||||
|
_content_rel_url="$3"
|
||||||
|
_target_url="$4"
|
||||||
|
_landing_out_file="$5"
|
||||||
|
_is_home="$6"
|
||||||
|
|
||||||
|
is_cw_content_page="true"
|
||||||
|
render_markdown "$_source_file" "$_is_home" "$_target_url" > "$_content_out_file"
|
||||||
|
is_cw_content_page="false"
|
||||||
|
|
||||||
|
generate_content_warning_page "$fm_title" "$fm_content_warning" "$_content_rel_url" "$_target_url" "$_landing_out_file" "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
build_site() {
|
||||||
|
echo "Building site from '$src' to '$out'..."
|
||||||
|
|
||||||
|
build_markdown_manifest
|
||||||
|
build_full_nav
|
||||||
|
|
||||||
|
eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type d -print" | sort | while read -r dir; do
|
||||||
|
rel_dir="${dir#"$src"}"
|
||||||
|
rel_dir="${rel_dir#/}"
|
||||||
|
[ -z "$rel_dir" ] && rel_dir="."
|
||||||
|
out_dir="$out/$rel_dir"
|
||||||
|
mkdir -p "$out_dir"
|
||||||
|
|
||||||
|
if [ -f "$dir/styles.css" ]; then
|
||||||
|
if needs_rebuild "$dir/styles.css" "$out_dir/styles.css"; then
|
||||||
|
copy_style_with_resolved_vars "$dir/styles.css" "$out_dir/styles.css"
|
||||||
|
fi
|
||||||
|
elif [ -f "$dir/style.css" ]; then
|
||||||
|
if needs_rebuild "$dir/style.css" "$out_dir/styles.css"; then
|
||||||
|
copy_style_with_resolved_vars "$dir/style.css" "$out_dir/styles.css"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ "$dir_indexes" != "true" ] && continue
|
||||||
|
|
||||||
|
has_custom_index="false"
|
||||||
|
has_list="false"
|
||||||
|
if [ -f "$dir/index.md" ]; then
|
||||||
|
has_custom_index="true"
|
||||||
|
if grep -q '^[[:space:]]*{{LIST}}[[:space:]]*$' "$dir/index.md" 2>/dev/null; then
|
||||||
|
has_list="true"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$has_custom_index" = "false" ] || [ "$has_list" = "true" ]; then
|
||||||
|
is_posts_dir="false"
|
||||||
|
if is_posts_directory_rel "$rel_dir"; then
|
||||||
|
is_posts_dir="true"
|
||||||
|
fi
|
||||||
|
if [ "$single_file_index" = "true" ] && [ "$is_posts_dir" = "false" ] && [ "$has_list" = "false" ]; then
|
||||||
|
if load_manifest_dir_entry "$rel_dir" && [ "$dir_md_count" -eq 1 ]; then
|
||||||
|
md_file="$src/$dir_first_md"
|
||||||
|
is_home="false"; [ "$dir" = "$src" ] && is_home="true"
|
||||||
|
target_url=$(directory_index_url "$rel_dir")
|
||||||
|
if needs_rebuild "$md_file" "$out_dir/index.html"; then
|
||||||
|
parse_frontmatter "$md_file"
|
||||||
|
if [ -n "$fm_content_warning" ]; then
|
||||||
|
content_out_file="$out_dir/content.html"
|
||||||
|
if [ "$rel_dir" = "." ]; then
|
||||||
|
content_rel_url="/content.html"
|
||||||
|
else
|
||||||
|
content_rel_url="/$(encode_url_path "$rel_dir")/content.html"
|
||||||
|
fi
|
||||||
|
write_content_warning_outputs "$md_file" "$content_out_file" "$content_rel_url" "$target_url" "$out_dir/index.html" "$is_home"
|
||||||
|
else
|
||||||
|
render_markdown "$md_file" "$is_home" "$target_url" > "$out_dir/index.html"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
temp_index="$KEWT_TMPDIR/index.md"
|
||||||
|
temp_list="$KEWT_TMPDIR/list.md"
|
||||||
|
: > "$temp_list"
|
||||||
|
|
||||||
|
if [ "$has_custom_index" = "false" ]; then
|
||||||
|
display_dir="${rel_dir#.}"
|
||||||
|
[ -z "$display_dir" ] && display_dir="/"
|
||||||
|
echo "# Index of $display_dir" > "$temp_index"
|
||||||
|
echo "" >> "$temp_index"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
sort_args=""
|
||||||
|
# If this is the posts dir reverse
|
||||||
|
if is_posts_directory_rel "$rel_dir"; then
|
||||||
|
sort_args="-r"
|
||||||
|
fi
|
||||||
|
|
||||||
|
temp_entries="$KEWT_TMPDIR/entries_$$.txt"
|
||||||
|
: > "$temp_entries"
|
||||||
|
|
||||||
|
find "$dir" ! -name "$(basename "$dir")" -prune ! -name ".*" -print | while read -r entry; do
|
||||||
|
name="${entry##*/}"
|
||||||
|
case "$name" in
|
||||||
|
template.html|site.conf|style.css|styles.root.css|index.md) continue ;;
|
||||||
|
esac
|
||||||
|
if [ -d "$entry" ]; then
|
||||||
|
entry_rel_dir="${entry#"$src"/}"
|
||||||
|
manifest_dir_hidden_by_draft_index "$entry_rel_dir" && continue
|
||||||
|
dir_url="$(encode_url_path "$name")/index.html"
|
||||||
|
echo "${name}|- [${name}/](${dir_url})" >> "$temp_entries"
|
||||||
|
elif [ "${entry%.md}" != "$entry" ]; then
|
||||||
|
entry_rel_path="${entry#"$src"/}"
|
||||||
|
load_manifest_entry "$entry_rel_path" || continue
|
||||||
|
label="${name%.md}"
|
||||||
|
[ "$manifest_draft" = "true" ] && continue
|
||||||
|
|
||||||
|
post_h="$manifest_title"
|
||||||
|
|
||||||
|
is_post_entry="false"
|
||||||
|
if is_posts_directory_rel "$rel_dir"; then
|
||||||
|
is_post_entry="true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$post_h" ]; then
|
||||||
|
if [ "$is_post_entry" = "true" ]; then
|
||||||
|
if [ -n "$manifest_post_time" ]; then
|
||||||
|
label="$post_h - $manifest_post_date $manifest_post_time"
|
||||||
|
else
|
||||||
|
label="$post_h - $manifest_post_date"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
label="$post_h"
|
||||||
|
fi
|
||||||
|
elif [ "$is_post_entry" = "true" ]; then
|
||||||
|
if [ -n "$manifest_post_time" ]; then
|
||||||
|
label="$manifest_post_date $manifest_post_time"
|
||||||
|
else
|
||||||
|
label="$manifest_post_date"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [ "$is_post_entry" = "true" ]; then
|
||||||
|
sort_key="${manifest_post_date} ${manifest_post_time}"
|
||||||
|
else
|
||||||
|
sort_key="$name"
|
||||||
|
fi
|
||||||
|
entry_url=$(encode_url_path "${name%.md}.html")
|
||||||
|
echo "${sort_key}|- [$label](${entry_url})|$name|${entry_url}" >> "$temp_entries"
|
||||||
|
else
|
||||||
|
asset_url=$(encode_url_path "$name")
|
||||||
|
echo "${name}|- [$name]($asset_url)|$name|$asset_url" >> "$temp_entries"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$is_posts_dir" = "true" ]; then
|
||||||
|
LC_ALL=C sort $sort_args "$temp_entries" > "$KEWT_TMPDIR/sorted_entries_$$.txt"
|
||||||
|
cut -d'|' -f2 "$KEWT_TMPDIR/sorted_entries_$$.txt" >> "$temp_list"
|
||||||
|
mkdir -p "$KEWT_TMPDIR/prevnext"
|
||||||
|
awk -F'|' '
|
||||||
|
{
|
||||||
|
name[NR] = $3
|
||||||
|
url[NR] = $4
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
for(i=1; i<=NR; i++) {
|
||||||
|
prev_str = ""
|
||||||
|
next_str = ""
|
||||||
|
if(i > 1) {
|
||||||
|
next_str = "[Next >](" url[i-1] ")"
|
||||||
|
}
|
||||||
|
if(i < NR) {
|
||||||
|
prev_str = "[< Previous](" url[i+1] ")"
|
||||||
|
}
|
||||||
|
if (prev_str != "" || next_str != "") {
|
||||||
|
out = "'"$KEWT_TMPDIR"'/prevnext/" name[i]
|
||||||
|
printf "%s|%s\n", prev_str, next_str > out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' "$KEWT_TMPDIR/sorted_entries_$$.txt"
|
||||||
|
rm -f "$KEWT_TMPDIR/sorted_entries_$$.txt"
|
||||||
|
else
|
||||||
|
LC_ALL=C sort $sort_args "$temp_entries" | cut -d'|' -f2 >> "$temp_list"
|
||||||
|
fi
|
||||||
|
rm -f "$temp_entries"
|
||||||
|
|
||||||
|
is_home="false"; [ "$dir" = "$src" ] && is_home="true"
|
||||||
|
target_url=$(directory_index_url "$rel_dir")
|
||||||
|
|
||||||
|
num_items=$(wc -l < "$temp_list")
|
||||||
|
if [ "$is_posts_dir" = "true" ] && [ -n "$posts_per_page" ] && [ "$posts_per_page" -gt 0 ] && [ "$num_items" -gt "$posts_per_page" ]; then
|
||||||
|
num_pages=$(( (num_items + posts_per_page - 1) / posts_per_page ))
|
||||||
|
p=1
|
||||||
|
while [ "$p" -le "$num_pages" ]; do
|
||||||
|
chunk_list="$KEWT_TMPDIR/chunk.md"
|
||||||
|
start_line=$(( (p - 1) * posts_per_page + 1 ))
|
||||||
|
tail -n +$start_line "$temp_list" | head -n "$posts_per_page" > "$chunk_list"
|
||||||
|
|
||||||
|
base_url_dir="$(dirname "$target_url")"
|
||||||
|
[ "$base_url_dir" = "/" ] && base_url_dir=""
|
||||||
|
|
||||||
|
nav_html="<div class=\"pagination\">"
|
||||||
|
if [ "$p" -gt 1 ]; then
|
||||||
|
if [ "$p" -eq 2 ]; then
|
||||||
|
nav_html="$nav_html <a href=\"$base_url_dir/index.html\" class=\"prev-page\">« Prev</a> "
|
||||||
|
else
|
||||||
|
nav_html="$nav_html <a href=\"$base_url_dir/page/$((p-1))/index.html\" class=\"prev-page\">« Prev</a> "
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
nav_html="$nav_html <span class=\"page-number\">Page $p of $num_pages</span> "
|
||||||
|
if [ "$p" -lt "$num_pages" ]; then
|
||||||
|
nav_html="$nav_html <a href=\"$base_url_dir/page/$((p+1))/index.html\" class=\"next-page\">Next »</a> "
|
||||||
|
fi
|
||||||
|
nav_html="$nav_html</div>"
|
||||||
|
|
||||||
|
echo "" >> "$chunk_list"
|
||||||
|
echo "$nav_html" >> "$chunk_list"
|
||||||
|
|
||||||
|
temp_index_p="$KEWT_TMPDIR/index_p$p.md"
|
||||||
|
if [ "$has_custom_index" = "false" ]; then
|
||||||
|
display_dir="${rel_dir#.}"
|
||||||
|
[ -z "$display_dir" ] && display_dir="/"
|
||||||
|
echo "# Index of $display_dir" > "$temp_index_p"
|
||||||
|
echo "" >> "$temp_index_p"
|
||||||
|
else
|
||||||
|
: > "$temp_index_p"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$has_custom_index" = "true" ]; then
|
||||||
|
awk '
|
||||||
|
/^[[:space:]]*\{\{LIST\}\}[[:space:]]*$/ {
|
||||||
|
while((getline line < "'"$chunk_list"'") > 0) print line
|
||||||
|
close("'"$chunk_list"'")
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
' "$dir/index.md" >> "$temp_index_p"
|
||||||
|
else
|
||||||
|
cat "$chunk_list" >> "$temp_index_p"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$p" -eq 1 ]; then
|
||||||
|
out_file="$out_dir/index.html"
|
||||||
|
target_url_p="$target_url"
|
||||||
|
else
|
||||||
|
out_file="$out_dir/page/$p/index.html"
|
||||||
|
target_url_p="$base_url_dir/page/$p/index.html"
|
||||||
|
mkdir -p "$(dirname "$out_file")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
render_markdown "$temp_index_p" "$is_home" "$target_url_p" > "$out_file"
|
||||||
|
rm -f "$temp_index_p" "$chunk_list"
|
||||||
|
p=$((p + 1))
|
||||||
|
done
|
||||||
|
else
|
||||||
|
if [ "$has_custom_index" = "true" ]; then
|
||||||
|
awk '
|
||||||
|
/^[[:space:]]*\{\{LIST\}\}[[:space:]]*$/ {
|
||||||
|
while((getline line < "'"$temp_list"'") > 0) print line
|
||||||
|
close("'"$temp_list"'")
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
' "$dir/index.md" > "$temp_index"
|
||||||
|
else
|
||||||
|
cat "$temp_list" >> "$temp_index"
|
||||||
|
fi
|
||||||
|
|
||||||
|
do_rebuild="false"
|
||||||
|
needs_rebuild "$dir" "$out_dir/index.html" && do_rebuild="true"
|
||||||
|
[ "$has_custom_index" = "true" ] && needs_rebuild "$dir/index.md" "$out_dir/index.html" && do_rebuild="true"
|
||||||
|
|
||||||
|
if [ "$do_rebuild" = "false" ] && [ -f "$out_dir/index.html" ]; then
|
||||||
|
for _child in "$dir"/*; do
|
||||||
|
[ -e "$_child" ] || continue
|
||||||
|
if [ "$_child" -nt "$out_dir/index.html" ]; then
|
||||||
|
do_rebuild="true"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$do_rebuild" = "true" ]; then
|
||||||
|
if [ "$has_custom_index" = "true" ]; then
|
||||||
|
parse_frontmatter "$dir/index.md"
|
||||||
|
else
|
||||||
|
fm_content_warning=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$fm_content_warning" ]; then
|
||||||
|
content_out_file="$out_dir/content.html"
|
||||||
|
if [ "$rel_dir" = "." ]; then
|
||||||
|
content_rel_url="/content.html"
|
||||||
|
else
|
||||||
|
content_rel_url="/$(encode_url_path "$rel_dir")/content.html"
|
||||||
|
fi
|
||||||
|
write_content_warning_outputs "$temp_index" "$content_out_file" "$content_rel_url" "$target_url" "$out_dir/index.html" "$is_home"
|
||||||
|
else
|
||||||
|
render_markdown "$temp_index" "$is_home" "$target_url" > "$out_dir/index.html"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
rm -f "$temp_index" "$temp_list"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -f "$src/styles.css" ] && [ ! -f "$src/style.css" ]; then
|
||||||
|
if [ -f "$src/styles.root.css" ]; then
|
||||||
|
_base_css="$script_dir/styles/$style.css"
|
||||||
|
[ ! -f "$_base_css" ] && _base_css="$script_dir/styles/kewt.css"
|
||||||
|
if [ ! -f "$out/styles.css" ] || [ "$src/styles.root.css" -nt "$out/styles.css" ] || [ "$_base_css" -nt "$out/styles.css" ]; then
|
||||||
|
merge_root_style "$src/styles.root.css" "$_base_css" "$out/styles.css"
|
||||||
|
fi
|
||||||
|
elif [ -f "$script_dir/styles/$style.css" ]; then
|
||||||
|
if needs_rebuild "$script_dir/styles/$style.css" "$out/styles.css"; then
|
||||||
|
copy_style_with_resolved_vars "$script_dir/styles/$style.css" "$out/styles.css"
|
||||||
|
fi
|
||||||
|
elif [ -f "$script_dir/styles/$style.root.css" ]; then
|
||||||
|
_base_css="$script_dir/styles/kewt.css"
|
||||||
|
if [ ! -f "$out/styles.css" ] || [ "$script_dir/styles/$style.root.css" -nt "$out/styles.css" ] || [ "$_base_css" -nt "$out/styles.css" ]; then
|
||||||
|
merge_root_style "$script_dir/styles/$style.root.css" "$_base_css" "$out/styles.css"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -type f -print" | sort | while IFS= read -r file; do
|
||||||
|
rel_path="${file#"$src"}"
|
||||||
|
rel_path="${rel_path#/}"
|
||||||
|
dir_rel=$(dirname "$rel_path")
|
||||||
|
out_dir="$out/$dir_rel"
|
||||||
|
|
||||||
|
case "${file##*/}" in
|
||||||
|
template.html|site.conf|style.css|styles.css|styles.root.css) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "${file##*/}" = "index.md" ] && grep -q '^[[:space:]]*{{LIST}}[[:space:]]*$' "$file" 2>/dev/null; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
is_preserved=0
|
||||||
|
if [ -n "$(eval "find \"$file\" \( $PRESERVE_ARGS \) -print")" ]; then
|
||||||
|
is_preserved=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
is_posts_dir_2="false"
|
||||||
|
if is_posts_directory_rel "$dir_rel"; then
|
||||||
|
is_posts_dir_2="true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$single_file_index" = "true" ] && [ "${file%.md}" != "$file" ] && [ "$is_preserved" -eq 0 ] && [ ! -f "$(dirname "$file")/index.md" ] && [ "$is_posts_dir_2" = "false" ]; then
|
||||||
|
load_manifest_dir_entry "$dir_rel" && [ "$dir_md_count" -eq 1 ] && continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${file%.md}" != "$file" ] && [ "$is_preserved" -eq 0 ]; then
|
||||||
|
load_manifest_entry "$rel_path" || continue
|
||||||
|
[ "$manifest_draft" = "true" ] && continue
|
||||||
|
is_home="false"; [ "$file" = "$src/index.md" ] && is_home="true"
|
||||||
|
out_file="$out/${rel_path%.md}.html"
|
||||||
|
if needs_rebuild "$file" "$out_file"; then
|
||||||
|
fm_title="$manifest_title"
|
||||||
|
fm_content_warning="$manifest_content_warning"
|
||||||
|
if [ -n "$manifest_content_warning" ]; then
|
||||||
|
content_out_file="$out/${rel_path%.md}-content.html"
|
||||||
|
content_rel_url="/$(encode_url_path "${rel_path%.md}")-content.html"
|
||||||
|
orig_rel_url="$manifest_url"
|
||||||
|
write_content_warning_outputs "$file" "$content_out_file" "$content_rel_url" "$orig_rel_url" "$out_file" "$is_home"
|
||||||
|
else
|
||||||
|
render_markdown "$file" "$is_home" > "$out_file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if needs_rebuild "$file" "$out/$rel_path"; then
|
||||||
|
cp "$file" "$out/$rel_path"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$error_page" ] && [ ! -f "$out/$error_page" ]; then
|
||||||
|
temp_404="$KEWT_TMPDIR/404_gen.md"
|
||||||
|
echo "# 404 - Not Found" > "$temp_404"
|
||||||
|
echo "" >> "$temp_404"
|
||||||
|
echo "The requested page could not be found." >> "$temp_404"
|
||||||
|
render_markdown "$temp_404" "false" "/$error_page" > "$out/$error_page"
|
||||||
|
rm -f "$temp_404"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$base_url" ]; then
|
||||||
|
sitemap_file="$out/sitemap.xml"
|
||||||
|
base_url="${base_url%/}"
|
||||||
|
today=$(date +%Y-%m-%d)
|
||||||
|
|
||||||
|
printf '<?xml version="1.0" encoding="UTF-8"?>\n' > "$sitemap_file"
|
||||||
|
printf '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n' >> "$sitemap_file"
|
||||||
|
|
||||||
|
find "$out" -type f -name "*.html" -print | sort | while IFS= read -r html_file; do
|
||||||
|
rel_url="${html_file#"$out"}"
|
||||||
|
|
||||||
|
# Don't include 404 in the sitemap (duh)
|
||||||
|
[ "${rel_url#/}" = "$error_page" ] && continue
|
||||||
|
|
||||||
|
{
|
||||||
|
printf ' <url>\n'
|
||||||
|
printf ' <loc>%s%s</loc>\n' "$base_url" "$rel_url"
|
||||||
|
printf ' <lastmod>%s</lastmod>\n' "$today"
|
||||||
|
printf ' </url>\n'
|
||||||
|
} >> "$sitemap_file"
|
||||||
|
done
|
||||||
|
|
||||||
|
printf '</urlset>\n' >> "$sitemap_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$generate_feed" = "true" ] && [ -n "$base_url" ]; then
|
||||||
|
feed_path="$out/$feed_file"
|
||||||
|
base_url_feed="${base_url%/}"
|
||||||
|
build_date=$(date -u '+%a, %d %b %Y %H:%M:%S +0000')
|
||||||
|
|
||||||
|
printf '<?xml version="1.0" encoding="UTF-8"?>\n' > "$feed_path"
|
||||||
|
{
|
||||||
|
printf '<rss version="2.0">\n'
|
||||||
|
printf ' <channel>\n'
|
||||||
|
printf ' <title>%s</title>\n' "$title"
|
||||||
|
printf ' <link>%s</link>\n' "$base_url_feed"
|
||||||
|
printf ' <description>%s</description>\n' "$title"
|
||||||
|
printf ' <lastBuildDate>%s</lastBuildDate>\n' "$build_date"
|
||||||
|
} >> "$feed_path"
|
||||||
|
|
||||||
|
temp_feed_files="$KEWT_TMPDIR/feed_files_$$.txt"
|
||||||
|
: > "$temp_feed_files"
|
||||||
|
|
||||||
|
while IFS= read -r manifest_rel_path; do
|
||||||
|
case "$manifest_rel_path" in
|
||||||
|
*"${posts_dir:-__no_posts__}"*) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
load_manifest_entry "$manifest_rel_path" || continue
|
||||||
|
[ "$manifest_draft" = "true" ] && continue
|
||||||
|
printf '%s %s|%s\n' "$manifest_post_date" "$manifest_post_time" "$manifest_rel_path" >> "$temp_feed_files"
|
||||||
|
done < "$manifest_all_list"
|
||||||
|
|
||||||
|
LC_ALL=C sort -r "$temp_feed_files" | cut -d'|' -f2- | while IFS= read -r post_rel_path; do
|
||||||
|
load_manifest_entry "$post_rel_path" || continue
|
||||||
|
[ "$manifest_draft" = "true" ] && continue
|
||||||
|
|
||||||
|
post_date="$manifest_post_date"
|
||||||
|
post_time="$manifest_post_time"
|
||||||
|
post_heading="$manifest_title"
|
||||||
|
post_slug="$manifest_post_slug"
|
||||||
|
if [ -z "$post_heading" ] && [ -n "$post_slug" ] && ! echo "$post_slug" | grep -q '^[0-9]\+$'; then
|
||||||
|
post_heading=$(echo "$post_slug" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) substr($i,2)}1')
|
||||||
|
fi
|
||||||
|
feed_post_title="$post_heading - $post_date $post_time"
|
||||||
|
|
||||||
|
post_url="$base_url_feed$manifest_url"
|
||||||
|
|
||||||
|
pub_date=$(format_rfc2822_utc "$post_date" "$post_time")
|
||||||
|
|
||||||
|
{
|
||||||
|
printf ' <item>\n'
|
||||||
|
printf ' <title>%s</title>\n' "$feed_post_title"
|
||||||
|
printf ' <link>%s</link>\n' "$post_url"
|
||||||
|
printf ' <guid>%s</guid>\n' "$post_url"
|
||||||
|
printf ' <pubDate>%s</pubDate>\n' "$pub_date"
|
||||||
|
printf ' </item>\n'
|
||||||
|
} >> "$feed_path"
|
||||||
|
done
|
||||||
|
|
||||||
|
printf ' </channel>\n' >> "$feed_path"
|
||||||
|
printf '</rss>\n' >> "$feed_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$generate_search" = "true" ] || [ "$generate_tags" = "true" ]; then
|
||||||
|
if [ "$generate_search" = "true" ]; then
|
||||||
|
printf '[\n' > "$out/search.json"
|
||||||
|
fi
|
||||||
|
first_search_item="true"
|
||||||
|
temp_tags="$KEWT_TMPDIR/tags_$$.txt"
|
||||||
|
: > "$temp_tags"
|
||||||
|
|
||||||
|
while IFS= read -r rel_path; do
|
||||||
|
load_manifest_entry "$rel_path" || continue
|
||||||
|
|
||||||
|
if [ "$manifest_is_index" = "true" ]; then
|
||||||
|
if [ "$rel_path" = "index.md" ]; then
|
||||||
|
md_url="/index.html"
|
||||||
|
else
|
||||||
|
md_url=$(directory_index_url "${rel_path%/index.md}")
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
md_url="$manifest_url"
|
||||||
|
if [ "$single_file_index" = "true" ]; then
|
||||||
|
rel_dir_of_file="$manifest_dir_rel"
|
||||||
|
[ -z "$rel_dir_of_file" ] && rel_dir_of_file="."
|
||||||
|
if [ "$rel_dir_of_file" = "." ]; then
|
||||||
|
dir_of_file="$src"
|
||||||
|
else
|
||||||
|
dir_of_file="$src/$rel_dir_of_file"
|
||||||
|
fi
|
||||||
|
|
||||||
|
is_posts_dir_search="false"
|
||||||
|
if [ -n "$posts_dir" ] && { [ "$rel_dir_of_file" = "$posts_dir" ] || [ "./$rel_dir_of_file" = "$posts_dir" ]; }; then
|
||||||
|
is_posts_dir_search="true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$is_posts_dir_search" = "false" ] && [ ! -f "$dir_of_file/index.md" ]; then
|
||||||
|
if load_manifest_dir_entry "$rel_dir_of_file" && [ "$dir_md_count" -eq 1 ]; then
|
||||||
|
if [ "$rel_dir_of_file" = "." ]; then
|
||||||
|
md_url="/index.html"
|
||||||
|
else
|
||||||
|
md_url=$(directory_index_url "$rel_dir_of_file")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
[ "$manifest_draft" = "true" ] && continue
|
||||||
|
md_heading="$manifest_title"
|
||||||
|
|
||||||
|
if [ "$generate_search" = "true" ]; then
|
||||||
|
if [ -z "$manifest_content_warning" ] || [ "$include_cw_pages_in_search" = "true" ]; then
|
||||||
|
md_content="$manifest_search_content"
|
||||||
|
if [ "$first_search_item" = "false" ]; then
|
||||||
|
printf ',\n' >> "$out/search.json"
|
||||||
|
fi
|
||||||
|
printf ' {"url": "%s", "title": "%s", "content": "%s"}' "$md_url" "$md_heading" "$md_content" >> "$out/search.json"
|
||||||
|
first_search_item="false"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$generate_tags" = "true" ] && [ -n "$manifest_tags" ]; then
|
||||||
|
old_ifs=$IFS
|
||||||
|
IFS=','
|
||||||
|
for tag in $manifest_tags; do
|
||||||
|
tag=$(echo "$tag" | sed 's/^[ \t]*//;s/[ \t]*$//')
|
||||||
|
[ -z "$tag" ] && continue
|
||||||
|
printf '%s|%s|%s\n' "$tag" "$md_url" "$md_heading" >> "$temp_tags"
|
||||||
|
done
|
||||||
|
IFS=$old_ifs
|
||||||
|
fi
|
||||||
|
done < "$manifest_visible_list"
|
||||||
|
|
||||||
|
if [ "$generate_search" = "true" ]; then
|
||||||
|
printf '\n]\n' >> "$out/search.json"
|
||||||
|
|
||||||
|
cp "$script_dir/lib/search.js" "$out/search.js"
|
||||||
|
|
||||||
|
search_md="$KEWT_TMPDIR/search_$$.md"
|
||||||
|
printf '%s\n' '# Search' '' \
|
||||||
|
'<form class="kewt-search-page" action="/search.html" method="get">' \
|
||||||
|
' <input type="text" id="search-box" name="q" placeholder="Search..." required>' \
|
||||||
|
' <button type="submit">Search</button>' \
|
||||||
|
'</form>' '' \
|
||||||
|
'<div id="search-results-list">' \
|
||||||
|
' <p>Loading...</p>' \
|
||||||
|
'</div>' '' \
|
||||||
|
'<script src="/search.js"></script>' > "$search_md"
|
||||||
|
render_markdown "$search_md" "false" "/search.html" > "$out/search.html"
|
||||||
|
rm -f "$search_md"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$generate_tags" = "true" ]; then
|
||||||
|
tags_out_dir="$out/$tags_dir"
|
||||||
|
mkdir -p "$tags_out_dir"
|
||||||
|
|
||||||
|
tags_index_md="$KEWT_TMPDIR/tags_index_$$.md"
|
||||||
|
echo "# Tags" > "$tags_index_md"
|
||||||
|
echo "" >> "$tags_index_md"
|
||||||
|
|
||||||
|
cut -d'|' -f1 "$temp_tags" | sort -u | while IFS= read -r tag; do
|
||||||
|
tag_slug=$(echo "$tag" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g')
|
||||||
|
|
||||||
|
echo "- [$tag](/$(echo "$tags_dir" | sed 's|^\/||; s|\/$||')/$tag_slug.html)" >> "$tags_index_md"
|
||||||
|
|
||||||
|
tag_page_md="$KEWT_TMPDIR/tag_page_$$.md"
|
||||||
|
echo "# Tag: $tag" > "$tag_page_md"
|
||||||
|
echo "" >> "$tag_page_md"
|
||||||
|
echo "Posts tagged with **$tag**:" >> "$tag_page_md"
|
||||||
|
echo "" >> "$tag_page_md"
|
||||||
|
|
||||||
|
grep "^${tag}|" "$temp_tags" | while IFS='|' read -r _t t_url t_title; do
|
||||||
|
echo "- [$t_title]($t_url)" >> "$tag_page_md"
|
||||||
|
done
|
||||||
|
|
||||||
|
render_markdown "$tag_page_md" "false" "/$tags_dir/$tag_slug.html" > "$tags_out_dir/$tag_slug.html"
|
||||||
|
rm -f "$tag_page_md"
|
||||||
|
done
|
||||||
|
|
||||||
|
render_markdown "$tags_index_md" "false" "/$tags_dir/index.html" > "$tags_out_dir/index.html"
|
||||||
|
rm -f "$tags_index_md"
|
||||||
|
fi
|
||||||
|
rm -f "$temp_tags"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Build complete."
|
||||||
|
}
|
||||||
144
lib/commands.sh
Normal file
144
lib/commands.sh
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
invoked_as=$(basename "${KEWT_INVOKED_AS:-$0}")
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $invoked_as [--from <src>] [--to <out>]
|
||||||
|
$invoked_as [src] [out]
|
||||||
|
$invoked_as --new [title]
|
||||||
|
$invoked_as --update [dir]
|
||||||
|
$invoked_as --post
|
||||||
|
$invoked_as --generate-template
|
||||||
|
$invoked_as --version
|
||||||
|
$invoked_as --help
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help Show this help message.
|
||||||
|
--new, --init [title] Create a new site directory (default: site)
|
||||||
|
--clean Clean the output directory before building (default).
|
||||||
|
--no-clean Do not clean the output directory before building.
|
||||||
|
--update [dir] Update site.conf and template.html with latest defaults (defaults to current directory)
|
||||||
|
--post Create a new empty post file in the configured posts_dir with current date and time as name
|
||||||
|
--generate-template [path] Generate a new template file at <path> (default: template.html)
|
||||||
|
--version Show version information.
|
||||||
|
--from <src> Source directory (default: site)
|
||||||
|
--to <out> Output directory (default: out)
|
||||||
|
--watch, -w Watch for file changes and rebuild automatically.
|
||||||
|
--serve, -s [port] Start a local HTTP server after building (default port: 8000).
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
generate_template() {
|
||||||
|
_gt_path="$1"
|
||||||
|
[ -e "$_gt_path" ] && die "File '$_gt_path' already exists."
|
||||||
|
_gt_dir=$(dirname "$_gt_path")
|
||||||
|
[ -d "$_gt_dir" ] || mkdir -p "$_gt_dir"
|
||||||
|
printf '%s\n' "$DEFAULT_TMPL" > "$_gt_path"
|
||||||
|
echo "Generated template at '$_gt_path'."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
create_new_site() {
|
||||||
|
new_title="$1"
|
||||||
|
new_dir="site"
|
||||||
|
[ -n "$new_title" ] && new_dir="$new_title"
|
||||||
|
|
||||||
|
[ -e "$new_dir" ] && die "Target '$new_dir' already exists."
|
||||||
|
|
||||||
|
mkdir -p "$new_dir"
|
||||||
|
printf '%s\n' "$DEFAULT_CONF" > "$new_dir/site.conf"
|
||||||
|
printf '%s\n' "$DEFAULT_TMPL" > "$new_dir/template.html"
|
||||||
|
printf "# _kewt_ website\n" > "$new_dir/index.md"
|
||||||
|
|
||||||
|
if [ -n "$new_title" ]; then
|
||||||
|
AWK_NEW_TITLE="$new_title" awk -f "$awk_dir/update_site_conf.awk" "$new_dir/site.conf" > "$new_dir/site.conf.tmp" && mv "$new_dir/site.conf.tmp" "$new_dir/site.conf"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Created new site at '$new_dir'."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
create_new_post() {
|
||||||
|
post_src_dir="$1"
|
||||||
|
post_user_title="$2"
|
||||||
|
|
||||||
|
target_dir="$post_src_dir"
|
||||||
|
if [ -n "$posts_dir" ]; then
|
||||||
|
target_dir="$post_src_dir/$posts_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$target_dir"
|
||||||
|
|
||||||
|
base_filename="$(date +%Y-%m-%d-%H-%M)"
|
||||||
|
filename="${base_filename}.md"
|
||||||
|
file_path="$target_dir/$filename"
|
||||||
|
|
||||||
|
counter=1
|
||||||
|
while [ -e "$file_path" ]; do
|
||||||
|
filename="${base_filename}_${counter}.md"
|
||||||
|
file_path="$target_dir/$filename"
|
||||||
|
counter=$((counter + 1))
|
||||||
|
done
|
||||||
|
|
||||||
|
post_date_val="$(date "+%Y-%m-%d %H:%M")"
|
||||||
|
if [ -n "$post_user_title" ]; then
|
||||||
|
printf -- '---\ntitle = "%s"\ndate = "%s"\ndraft = %s\n---\n# %s\n' "$post_user_title" "$post_date_val" "$draft_by_default" "$post_user_title" > "$file_path"
|
||||||
|
else
|
||||||
|
printf -- '---\ndate = "%s"\ndraft = %s\n---\n' "$post_date_val" "$draft_by_default" > "$file_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Created new post at '$file_path'."
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
update_site() {
|
||||||
|
update_dir="${1:-.}"
|
||||||
|
[ -d "$update_dir" ] || die "Directory '$update_dir' does not exist."
|
||||||
|
|
||||||
|
target_conf="$update_dir/site.conf"
|
||||||
|
target_tmpl="$update_dir/template.html"
|
||||||
|
|
||||||
|
# Generate default site.conf
|
||||||
|
default_conf="$KEWT_TMPDIR/default_site.conf"
|
||||||
|
printf '%s\n' "$DEFAULT_CONF" > "$default_conf"
|
||||||
|
|
||||||
|
# Update site.conf
|
||||||
|
if [ ! -f "$target_conf" ]; then
|
||||||
|
echo "No site.conf found in '$update_dir'; nothing to update."
|
||||||
|
else
|
||||||
|
added=0
|
||||||
|
while IFS= read -r line; do
|
||||||
|
case "$line" in
|
||||||
|
''|'#'*) continue ;;
|
||||||
|
*=*) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
key=$(printf '%s' "${line%%=*}" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||||
|
if ! grep -q "^[[:space:]]*${key}[[:space:]]*=" "$target_conf"; then
|
||||||
|
printf '%s\n' "$line" >> "$target_conf"
|
||||||
|
echo " Added: $key"
|
||||||
|
added=$((added + 1))
|
||||||
|
fi
|
||||||
|
done < "$default_conf"
|
||||||
|
if [ "$added" -eq 0 ]; then
|
||||||
|
echo "site.conf is already up to date."
|
||||||
|
else
|
||||||
|
echo "Added $added new key(s) to '$target_conf'."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update template.html
|
||||||
|
if [ -f "$target_tmpl" ]; then
|
||||||
|
default_tmpl="$KEWT_TMPDIR/default_template.html"
|
||||||
|
printf '%s\n' "$DEFAULT_TMPL" > "$default_tmpl"
|
||||||
|
if cmp -s "$default_tmpl" "$target_tmpl" 2>/dev/null; then
|
||||||
|
echo "template.html is already up to date."
|
||||||
|
else
|
||||||
|
cp "$default_tmpl" "${target_tmpl}.default"
|
||||||
|
echo "template.html has local changes; saved latest default as '${target_tmpl}.default'."
|
||||||
|
echo ""
|
||||||
|
diff "$target_tmpl" "${target_tmpl}.default" || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
168
lib/config.sh
Normal file
168
lib/config.sh
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
DEFAULT_CONF='title = "kewt"
|
||||||
|
style = "kewt"
|
||||||
|
lang = "en"
|
||||||
|
draft_by_default = false
|
||||||
|
dir_indexes = true
|
||||||
|
single_file_index = true
|
||||||
|
flatten = false
|
||||||
|
order = ""
|
||||||
|
home_name = "Home"
|
||||||
|
show_home_in_nav = true
|
||||||
|
nav_links = ""
|
||||||
|
nav_extra = ""
|
||||||
|
footer = "made with <a href=\"https://kewt.krzak.org\">kewt</a>"
|
||||||
|
logo = ""
|
||||||
|
display_logo = false
|
||||||
|
display_title = true
|
||||||
|
logo_as_favicon = true
|
||||||
|
favicon = ""
|
||||||
|
generate_page_title = true
|
||||||
|
error_page = "not_found.html"
|
||||||
|
versioning = false
|
||||||
|
enable_header_links = true
|
||||||
|
base_url = ""
|
||||||
|
generate_feed = false
|
||||||
|
feed_file = "rss.xml"
|
||||||
|
posts_dir = ""
|
||||||
|
posts_per_page = 12
|
||||||
|
custom_admonitions = ""
|
||||||
|
cw_hide_url = true
|
||||||
|
generate_tags = false
|
||||||
|
tags_dir = "tags"
|
||||||
|
generate_search = false
|
||||||
|
search_in_footer = false
|
||||||
|
search_in_header = false
|
||||||
|
include_cw_pages_in_search = false'
|
||||||
|
|
||||||
|
DEFAULT_TMPL='<!doctype html>
|
||||||
|
<html lang="{{LANG}}">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>{{TITLE}}</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="{{CSS}}{{VERSION}}" type="text/css" />
|
||||||
|
{{HEAD_EXTRA}}
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<input type="checkbox" id="nav-toggle" class="nav-toggle" aria-hidden="true" />
|
||||||
|
<header>
|
||||||
|
<h1>{{HEADER_BRAND}}</h1>
|
||||||
|
{{HEADER_SEARCH}}
|
||||||
|
<label for="nav-toggle" class="nav-toggle-label" aria-hidden="true">☰</label>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<nav id="side-bar">{{NAV}}</nav>
|
||||||
|
|
||||||
|
<article>{{CONTENT}}</article>
|
||||||
|
<footer>{{FOOTER}}</footer>
|
||||||
|
</body>
|
||||||
|
</html>'
|
||||||
|
|
||||||
|
reset_config() {
|
||||||
|
title="kewt"
|
||||||
|
style="kewt"
|
||||||
|
lang="en"
|
||||||
|
draft_by_default="false"
|
||||||
|
dir_indexes="true"
|
||||||
|
single_file_index="true"
|
||||||
|
flatten="false"
|
||||||
|
order=""
|
||||||
|
home_name="Home"
|
||||||
|
show_home_in_nav="true"
|
||||||
|
nav_links=""
|
||||||
|
nav_extra=""
|
||||||
|
footer="made with <a href=\"https://kewt.krzak.org\">kewt</a>"
|
||||||
|
logo=""
|
||||||
|
display_logo="false"
|
||||||
|
display_title="true"
|
||||||
|
logo_as_favicon="true"
|
||||||
|
favicon=""
|
||||||
|
generate_page_title="true"
|
||||||
|
error_page="not_found.html"
|
||||||
|
versioning="false"
|
||||||
|
enable_header_links="true"
|
||||||
|
base_url=""
|
||||||
|
generate_feed="false"
|
||||||
|
feed_file="rss.xml"
|
||||||
|
posts_dir=""
|
||||||
|
posts_per_page="12"
|
||||||
|
custom_admonitions=""
|
||||||
|
cw_hide_url="true"
|
||||||
|
generate_tags="false"
|
||||||
|
tags_dir="tags"
|
||||||
|
generate_search="false"
|
||||||
|
search_in_footer="false"
|
||||||
|
search_in_header="false"
|
||||||
|
include_cw_pages_in_search="false"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_config() {
|
||||||
|
[ -f "$1" ] || return
|
||||||
|
while IFS= read -r line || [ -n "$line" ]; do
|
||||||
|
case "$line" in
|
||||||
|
''|'#'*) continue ;;
|
||||||
|
*=*) ;;
|
||||||
|
*) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
key=${line%%=*}
|
||||||
|
val=${line#*=}
|
||||||
|
|
||||||
|
key=$(printf '%s' "$key" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||||
|
val=$(printf '%s' "$val" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||||
|
case "$val" in
|
||||||
|
\"*\")
|
||||||
|
val=${val#\"}; val=${val%\"}
|
||||||
|
val=$(printf '%s' "$val" | sed 's/\\"/\"/g; s/\\\\/\\/g')
|
||||||
|
;;
|
||||||
|
\'*\')
|
||||||
|
val=${val#\'}; val=${val%\'}
|
||||||
|
val=$(printf '%s' "$val" | sed "s/\\\\'/'/g; s/\\\\/\\/g")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$key" in
|
||||||
|
title) title="$val" ;;
|
||||||
|
style) style="${val#/}" ;;
|
||||||
|
dir_indexes) dir_indexes="$val" ;;
|
||||||
|
single_file_index) single_file_index="$val" ;;
|
||||||
|
flatten) flatten="$val" ;;
|
||||||
|
order) order="$val" ;;
|
||||||
|
home_name) home_name="$val" ;;
|
||||||
|
show_home_in_nav) show_home_in_nav="$val" ;;
|
||||||
|
nav_links) nav_links="$val" ;;
|
||||||
|
nav_extra) nav_extra="$val" ;;
|
||||||
|
footer) footer="$val" ;;
|
||||||
|
logo) logo="${val#/}" ;;
|
||||||
|
display_logo) display_logo="$val" ;;
|
||||||
|
display_title) display_title="$val" ;;
|
||||||
|
logo_as_favicon) logo_as_favicon="$val" ;;
|
||||||
|
favicon) favicon="${val#/}" ;;
|
||||||
|
generate_page_title) generate_page_title="$val" ;;
|
||||||
|
error_page) error_page="${val#/}" ;;
|
||||||
|
versioning) versioning="$val" ;;
|
||||||
|
enable_header_links) enable_header_links="$val" ;;
|
||||||
|
base_url) base_url="$val" ;;
|
||||||
|
generate_feed) generate_feed="$val" ;;
|
||||||
|
feed_file) feed_file="${val#/}" ;;
|
||||||
|
posts_dir) posts_dir="${val#/}" ;;
|
||||||
|
posts_per_page) posts_per_page="$val" ;;
|
||||||
|
custom_admonitions) custom_admonitions="$val" ;;
|
||||||
|
cw_hide_url) cw_hide_url="$val" ;;
|
||||||
|
lang) lang="$val" ;;
|
||||||
|
draft_by_default) draft_by_default="$val" ;;
|
||||||
|
generate_tags) generate_tags="$val" ;;
|
||||||
|
tags_dir) tags_dir="${val#/}" ;;
|
||||||
|
generate_search) generate_search="$val" ;;
|
||||||
|
search_in_footer) search_in_footer="$val" ;;
|
||||||
|
search_in_header) search_in_header="$val" ;;
|
||||||
|
include_cw_pages_in_search) include_cw_pages_in_search="$val" ;;
|
||||||
|
esac
|
||||||
|
done < "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
reset_config
|
||||||
315
lib/generator.sh
Normal file
315
lib/generator.sh
Normal file
@@ -0,0 +1,315 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SEARCH_FORM_FOOTER='<form class="kewt-search-footer" action="/search.html" method="get"><input type="text" name="q" placeholder="Search..." required><button type="submit">Go</button></form>'
|
||||||
|
SEARCH_FORM_HEADER='<form class="kewt-search-header" action="/search.html" method="get"><input type="text" name="q" placeholder="Search..." required><button type="submit">Go</button></form>'
|
||||||
|
SEARCH_FORM_NAV='<div class="kewt-search-nav"><form action="/search.html" method="get"><input type="text" name="q" placeholder="Search..." required><button type="submit">Go</button></form></div>'
|
||||||
|
|
||||||
|
generate_nav() {
|
||||||
|
dinfo=$(eval "find \"$1\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -print" | sort | AWK_SRC="$1" awk -f "$awk_dir/collect_dir_info.awk")
|
||||||
|
nav_input="$KEWT_TMPDIR/nav_input.lst"
|
||||||
|
: > "$nav_input"
|
||||||
|
|
||||||
|
if [ -f "$manifest_visible_list" ]; then
|
||||||
|
while IFS= read -r nav_rel_path; do
|
||||||
|
printf '%s/%s\n' "$1" "$nav_rel_path" >> "$nav_input"
|
||||||
|
done < "$manifest_visible_list"
|
||||||
|
|
||||||
|
if [ -n "$posts_dir" ] && [ -d "$1/$posts_dir" ] && ! manifest_dir_hidden_by_draft_index "$posts_dir"; then
|
||||||
|
has_posts_nav_entry="false"
|
||||||
|
has_posts_index_entry="false"
|
||||||
|
while IFS= read -r nav_rel_path; do
|
||||||
|
case "$nav_rel_path" in
|
||||||
|
"$posts_dir"/index.md) has_posts_index_entry="true" ;;
|
||||||
|
"$posts_dir"/*) has_posts_nav_entry="true" ;;
|
||||||
|
esac
|
||||||
|
done < "$manifest_visible_list"
|
||||||
|
if [ "$has_posts_nav_entry" = "true" ] && [ "$has_posts_index_entry" = "false" ]; then
|
||||||
|
printf '%s/%s/index.md\n' "$1" "$posts_dir" >> "$nav_input"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
find_cmd="find \"$1\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -name \"*.md\" -print"
|
||||||
|
if [ -n "$posts_dir" ] && [ -d "$1/$posts_dir" ]; then
|
||||||
|
find_cmd="$find_cmd && echo \"$1/$posts_dir/index.md\""
|
||||||
|
fi
|
||||||
|
eval "$find_cmd" | sort -u > "$nav_input"
|
||||||
|
fi
|
||||||
|
|
||||||
|
sort -u "$nav_input" | AWK_SRC="$1" AWK_SINGLE_FILE_INDEX="$single_file_index" AWK_FLATTEN="$flatten" AWK_ORDER="$order" AWK_HOME_NAME="$home_name" AWK_SHOW_HOME_IN_NAV="$show_home_in_nav" AWK_DINFO="$dinfo" awk -f "$awk_dir/generate_sidebar.awk"
|
||||||
|
}
|
||||||
|
escape_html_text() {
|
||||||
|
printf '%s' "$1" | sed \
|
||||||
|
-e 's/&/\&/g' \
|
||||||
|
-e 's/</\</g' \
|
||||||
|
-e 's/>/\>/g'
|
||||||
|
}
|
||||||
|
escape_html_attr() {
|
||||||
|
printf '%s' "$1" | sed \
|
||||||
|
-e 's/&/\&/g' \
|
||||||
|
-e 's/"/\"/g' \
|
||||||
|
-e 's/</\</g' \
|
||||||
|
-e 's/>/\>/g'
|
||||||
|
}
|
||||||
|
nav_links_html() {
|
||||||
|
[ -n "$nav_links" ] || return
|
||||||
|
|
||||||
|
old_ifs=$IFS
|
||||||
|
set -f
|
||||||
|
IFS=','
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
set -- $nav_links
|
||||||
|
IFS=$old_ifs
|
||||||
|
set +f
|
||||||
|
|
||||||
|
[ $# -gt 0 ] || return
|
||||||
|
|
||||||
|
printf '<ul class="nav-extra-links">\n'
|
||||||
|
for raw_link in "$@"; do
|
||||||
|
link=$(printf '%s' "$raw_link" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')
|
||||||
|
[ -n "$link" ] || continue
|
||||||
|
|
||||||
|
case "$link" in
|
||||||
|
\[*\]\(*\))
|
||||||
|
label=${link#\[}
|
||||||
|
label=${label%%\]*}
|
||||||
|
link_url=${link#*](}
|
||||||
|
link_url=${link_url%)}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
link_url=$link
|
||||||
|
label=$(printf '%s' "$link" | sed \
|
||||||
|
-e 's|^[A-Za-z][A-Za-z0-9+.-]*://||' \
|
||||||
|
-e 's|/$||')
|
||||||
|
[ -n "$label" ] || label="$link"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ -n "$link_url" ] || continue
|
||||||
|
[ -n "$label" ] || label="$link_url"
|
||||||
|
|
||||||
|
link_attr=$(escape_html_attr "$link_url")
|
||||||
|
label_text=$(escape_html_text "$label")
|
||||||
|
printf '<li><a href="%s">%s</a></li>\n' "$link_attr" "$label_text"
|
||||||
|
done
|
||||||
|
printf '</ul>'
|
||||||
|
}
|
||||||
|
find_closest() {
|
||||||
|
target="$1"
|
||||||
|
start_dir="$2"
|
||||||
|
curr="$start_dir"
|
||||||
|
while [ "$curr" != "$src" ] && [ "$curr" != "." ] && [ "$curr" != "/" ]; do
|
||||||
|
if [ -f "$curr/$target" ]; then
|
||||||
|
echo "$curr/$target"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
curr=$(dirname "$curr")
|
||||||
|
done
|
||||||
|
if [ -f "$src/$target" ]; then
|
||||||
|
echo "$src/$target"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
copy_style_with_resolved_vars() {
|
||||||
|
src_style="$1"
|
||||||
|
out_style="$2"
|
||||||
|
awk -f "$awk_dir/replace_variables.awk" "$src_style" > "$out_style"
|
||||||
|
}
|
||||||
|
merge_root_style() {
|
||||||
|
root_file="$1"
|
||||||
|
base_css="$2"
|
||||||
|
out_file="$3"
|
||||||
|
{
|
||||||
|
cat "$root_file"
|
||||||
|
awk '
|
||||||
|
BEGIN { in_root = 0; brace_depth = 0 }
|
||||||
|
/^:root[[:space:]]*\{/ { in_root = 1; brace_depth = 1; next }
|
||||||
|
in_root {
|
||||||
|
for (i = 1; i <= length($0); i++) {
|
||||||
|
c = substr($0, i, 1)
|
||||||
|
if (c == "{") brace_depth++
|
||||||
|
if (c == "}") { brace_depth--; if (brace_depth == 0) { in_root = 0; next } }
|
||||||
|
}
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
' "$base_css"
|
||||||
|
} | awk -f "$awk_dir/replace_variables.awk" > "$out_file"
|
||||||
|
}
|
||||||
|
render_markdown() {
|
||||||
|
file="$1"
|
||||||
|
is_home="$2"
|
||||||
|
url_override="$3"
|
||||||
|
|
||||||
|
if [ -n "$url_override" ]; then
|
||||||
|
current_url="$url_override"
|
||||||
|
else
|
||||||
|
rel_path="${file#"$src"}"
|
||||||
|
rel_path="${rel_path#/}"
|
||||||
|
current_url=$(markdown_file_url "$rel_path")
|
||||||
|
fi
|
||||||
|
|
||||||
|
content_file="$file"
|
||||||
|
if [ -n "$posts_dir" ] && [ "$file" != "$src/$posts_dir/index.md" ]; then
|
||||||
|
rel_dir_of_url=$(dirname "$current_url")
|
||||||
|
rel_dir_of_url="${rel_dir_of_url#/}"
|
||||||
|
if { [ "$rel_dir_of_url" = "$posts_dir" ] || [ "./$rel_dir_of_url" = "$posts_dir" ]; } && [ "$(basename "$current_url")" != "index.html" ]; then
|
||||||
|
temp_post_with_backlink="$KEWT_TMPDIR/post_with_backlink_$$.md"
|
||||||
|
printf "[< Back](index.html)\n\n" > "$temp_post_with_backlink"
|
||||||
|
awk -f "$awk_dir/frontmatter.awk" "$file" >> "$temp_post_with_backlink"
|
||||||
|
|
||||||
|
post_md_name="$(basename "$current_url" .html).md"
|
||||||
|
prevnext_file="$KEWT_TMPDIR/prevnext/$post_md_name"
|
||||||
|
if [ -f "$prevnext_file" ]; then
|
||||||
|
IFS='|' read -r prev_str next_str < "$prevnext_file"
|
||||||
|
|
||||||
|
printf "\n\n---\n<div class=\"post-nav\">\n" >> "$temp_post_with_backlink"
|
||||||
|
if [ -n "$prev_str" ]; then
|
||||||
|
printf "<span class=\"prev-post\">%s</span>\n" "$prev_str" >> "$temp_post_with_backlink"
|
||||||
|
fi
|
||||||
|
if [ -n "$next_str" ]; then
|
||||||
|
printf "<span class=\"next-post\">%s</span>\n" "$next_str" >> "$temp_post_with_backlink"
|
||||||
|
fi
|
||||||
|
printf "</div>\n" >> "$temp_post_with_backlink"
|
||||||
|
fi
|
||||||
|
content_file="$temp_post_with_backlink"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local_template=$(find_closest "template.html" "$(dirname "$file")")
|
||||||
|
[ -z "$local_template" ] && local_template="$template"
|
||||||
|
|
||||||
|
closest_style_src=$(find_closest "styles.css" "$(dirname "$file")")
|
||||||
|
[ -z "$closest_style_src" ] && closest_style_src=$(find_closest "style.css" "$(dirname "$file")")
|
||||||
|
if [ -n "$closest_style_src" ]; then
|
||||||
|
style_rel_to_src="${closest_style_src#"$src"/}"
|
||||||
|
case "$closest_style_src" in
|
||||||
|
"$src/styles.css") style_rel_to_src="styles.css" ;;
|
||||||
|
"$src/style.css") style_rel_to_src="style.css" ;;
|
||||||
|
esac
|
||||||
|
style_path="/$(encode_url_path "${style_rel_to_src%styles.css}")"
|
||||||
|
style_path="${style_path%style.css}styles.css"
|
||||||
|
else
|
||||||
|
style_path="/styles.css"
|
||||||
|
fi
|
||||||
|
|
||||||
|
logo_html=""
|
||||||
|
if [ "$display_logo" = "true" ] && [ -n "$logo" ]; then
|
||||||
|
logo_html="<img class=\"site-logo\" src=\"$logo\" alt=\"$title\" />"
|
||||||
|
fi
|
||||||
|
|
||||||
|
brand_text=""
|
||||||
|
if [ "$display_title" = "true" ]; then
|
||||||
|
brand_text="$title"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$logo_html" ] && [ -n "$brand_text" ]; then
|
||||||
|
header_brand="<a href=\"/index.html\">$logo_html $brand_text</a>"
|
||||||
|
elif [ -n "$logo_html" ]; then
|
||||||
|
header_brand="<a href=\"/index.html\">$logo_html</a>"
|
||||||
|
elif [ -n "$brand_text" ]; then
|
||||||
|
header_brand="<a href=\"/index.html\">$brand_text</a>"
|
||||||
|
else
|
||||||
|
header_brand="<a href=\"/index.html\">$title</a>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
favicon_src=""
|
||||||
|
if [ "$logo_as_favicon" = "true" ] && [ -n "$logo" ]; then
|
||||||
|
favicon_src="$logo"
|
||||||
|
elif [ -n "$favicon" ]; then
|
||||||
|
favicon_src="$favicon"
|
||||||
|
fi
|
||||||
|
head_extra=""
|
||||||
|
if [ -n "$favicon_src" ]; then
|
||||||
|
if echo "$favicon_src" | grep -q "^http"; then
|
||||||
|
head_extra="<link rel=\"icon\" href=\"$favicon_src\" />"
|
||||||
|
elif echo "$favicon_src" | grep -q "^/"; then
|
||||||
|
head_extra="<link rel=\"icon\" href=\"$favicon_src\" />"
|
||||||
|
else
|
||||||
|
head_extra="<link rel=\"icon\" href=\"/$favicon_src\" />"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
parse_frontmatter "$file"
|
||||||
|
|
||||||
|
page_title="$title"
|
||||||
|
if [ -n "$fm_title" ]; then
|
||||||
|
page_title="$fm_title - $title"
|
||||||
|
elif [ "$generate_page_title" = "true" ] && [ -n "$file" ] && [ -f "$file" ]; then
|
||||||
|
if [ "$is_home" = "true" ] && [ -n "$home_name" ]; then
|
||||||
|
page_title="$home_name - $title"
|
||||||
|
else
|
||||||
|
first_heading=$(first_heading_from_markdown "$file")
|
||||||
|
if [ -n "$first_heading" ]; then
|
||||||
|
first_heading=$(strip_markdown_text "$first_heading")
|
||||||
|
page_title="$first_heading - $title"
|
||||||
|
else
|
||||||
|
basename_no_ext=$(basename "$file" .md)
|
||||||
|
if [ "$basename_no_ext" != "index" ] && [ "$basename_no_ext" != "404_gen" ]; then
|
||||||
|
cap_basename=$(echo "$basename_no_ext" | awk '{print toupper(substr($0,1,1)) substr($0,2)}')
|
||||||
|
page_title="$cap_basename - $title"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
head_extra_og="<meta property=\"og:title\" content=\"$(escape_html_attr "$page_title")\" />"
|
||||||
|
if [ -n "$fm_description" ]; then
|
||||||
|
head_extra_og="$head_extra_og
|
||||||
|
<meta property=\"og:description\" content=\"$(escape_html_attr "$fm_description")\" />"
|
||||||
|
fi
|
||||||
|
og_url="${base_url%/}${current_url}"
|
||||||
|
head_extra_og="$head_extra_og
|
||||||
|
<meta property=\"og:url\" content=\"$(escape_html_attr "$og_url")\" />"
|
||||||
|
|
||||||
|
if [ -n "$head_extra" ]; then
|
||||||
|
head_extra="$head_extra
|
||||||
|
$head_extra_og"
|
||||||
|
else
|
||||||
|
head_extra="$head_extra_og"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$is_cw_content_page" = "true" ] && [ "$cw_hide_url" = "true" ]; then
|
||||||
|
head_extra="$head_extra
|
||||||
|
<script>window.history.replaceState(null, '', '$current_url');</script>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
final_footer="$footer"
|
||||||
|
if [ "$search_in_footer" = "true" ]; then
|
||||||
|
final_footer="$footer $SEARCH_FORM_FOOTER"
|
||||||
|
fi
|
||||||
|
|
||||||
|
final_nav="$nav"
|
||||||
|
final_header_brand="$header_brand"
|
||||||
|
final_header_search=""
|
||||||
|
if [ "$search_in_header" = "true" ]; then
|
||||||
|
final_header_search="$SEARCH_FORM_HEADER"
|
||||||
|
final_nav="$SEARCH_FORM_NAV
|
||||||
|
$nav"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ENABLE_HEADER_LINKS="$enable_header_links" CUSTOM_ADMONITIONS="$custom_admonitions" MARKDOWN_SITE_ROOT="$src" MARKDOWN_FALLBACK_FILE="$script_dir/styles/$style.css" sh "$script_dir/markdown.sh" "$content_file" | AWK_LANG="$lang" AWK_CURRENT_URL="$current_url" AWK_TITLE="$page_title" AWK_NAV="$final_nav" AWK_FOOTER="$final_footer" AWK_STYLE_PATH="${style_path}" AWK_HEADER_BRAND="$final_header_brand" AWK_HEADER_SEARCH="$final_header_search" AWK_HEAD_EXTRA="$head_extra" AWK_VERSION="$asset_version" AWK_CONTENT_WARNING="$fm_content_warning" awk -f "$awk_dir/render_template.awk" "$local_template"
|
||||||
|
}
|
||||||
|
generate_content_warning_page() {
|
||||||
|
_fm_title="$1"
|
||||||
|
_fm_content_warning="$2"
|
||||||
|
_content_rel_url="$3"
|
||||||
|
_target_url="$4"
|
||||||
|
_out_file="$5"
|
||||||
|
_is_home="$6"
|
||||||
|
|
||||||
|
_temp_cw="$KEWT_TMPDIR/cw_$$.md"
|
||||||
|
_cw_text="${_fm_content_warning}"
|
||||||
|
[ "$_cw_text" = "true" ] && _cw_text="This content may be sensitive."
|
||||||
|
|
||||||
|
cat <<EOF > "$_temp_cw"
|
||||||
|
---
|
||||||
|
title = "$_fm_title"
|
||||||
|
---
|
||||||
|
|
||||||
|
> [!CAUTION]
|
||||||
|
> **Content Warning:** $_cw_text
|
||||||
|
|
||||||
|
<a href="$(basename "$_content_rel_url")" class="cw-button">Reveal Content</a>
|
||||||
|
EOF
|
||||||
|
render_markdown "$_temp_cw" "$_is_home" "$_target_url" > "$_out_file"
|
||||||
|
rm -f "$_temp_cw"
|
||||||
|
}
|
||||||
193
lib/manifest.sh
Normal file
193
lib/manifest.sh
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
shell_quote() {
|
||||||
|
printf "'%s'" "$(printf '%s' "$1" | sed "s/'/'\\\\''/g")"
|
||||||
|
}
|
||||||
|
|
||||||
|
manifest_meta_path() {
|
||||||
|
printf '%s/manifest/meta/%s.meta\n' "$KEWT_TMPDIR" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
manifest_dir_meta_path() {
|
||||||
|
printf '%s/manifest/dir-meta/%s.meta\n' "$KEWT_TMPDIR" "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
manifest_dir_hidden_by_draft_index() {
|
||||||
|
_manifest_hidden_dir="${1:-.}"
|
||||||
|
[ -f "$manifest_hidden_dirs_list" ] || return 1
|
||||||
|
|
||||||
|
while :; do
|
||||||
|
awk -v dir="$_manifest_hidden_dir" '$0 == dir { found = 1 } END { exit(found ? 0 : 1) }' "$manifest_hidden_dirs_list" >/dev/null 2>&1 && return 0
|
||||||
|
[ "$_manifest_hidden_dir" = "." ] && return 1
|
||||||
|
_manifest_hidden_parent=$(dirname "$_manifest_hidden_dir")
|
||||||
|
[ "$_manifest_hidden_parent" = "$_manifest_hidden_dir" ] && return 1
|
||||||
|
_manifest_hidden_dir="$_manifest_hidden_parent"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
write_manifest_dir_meta() {
|
||||||
|
_dir_meta_rel="$1"
|
||||||
|
_dir_meta_count="$2"
|
||||||
|
_dir_meta_first="$3"
|
||||||
|
_dir_meta_has_index="$4"
|
||||||
|
_dir_meta_path=$(manifest_dir_meta_path "$_dir_meta_rel")
|
||||||
|
mkdir -p "$(dirname "$_dir_meta_path")"
|
||||||
|
{
|
||||||
|
printf 'dir_manifest_rel=%s\n' "$(shell_quote "$_dir_meta_rel")"
|
||||||
|
printf 'dir_md_count=%s\n' "$(shell_quote "$_dir_meta_count")"
|
||||||
|
printf 'dir_first_md=%s\n' "$(shell_quote "$_dir_meta_first")"
|
||||||
|
printf 'dir_has_index=%s\n' "$(shell_quote "$_dir_meta_has_index")"
|
||||||
|
} > "$_dir_meta_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_manifest_dir_entry() {
|
||||||
|
_dir_manifest_rel="$1"
|
||||||
|
_dir_manifest_meta_path=$(manifest_dir_meta_path "$_dir_manifest_rel")
|
||||||
|
[ -f "$_dir_manifest_meta_path" ] || return 1
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
. "$_dir_manifest_meta_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_manifest_entry() {
|
||||||
|
_manifest_rel_path="$1"
|
||||||
|
_manifest_meta_path=$(manifest_meta_path "$_manifest_rel_path")
|
||||||
|
[ -f "$_manifest_meta_path" ] || return 1
|
||||||
|
# shellcheck disable=SC1090
|
||||||
|
. "$_manifest_meta_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
extract_search_content() {
|
||||||
|
_search_file="$1"
|
||||||
|
awk '{
|
||||||
|
if (NR == 1 && $0 == "---") { in_fm = 1; next }
|
||||||
|
if (in_fm && $0 == "---") { in_fm = 0; next }
|
||||||
|
if (in_fm) next
|
||||||
|
if ($0 ~ /^```/) { in_code = !in_code; next }
|
||||||
|
if (in_code) next
|
||||||
|
print
|
||||||
|
}' "$_search_file" | sed \
|
||||||
|
-e 's/^#\{1,6\} //' \
|
||||||
|
-e 's/\*\*\([^*]*\)\*\*/\1/g' \
|
||||||
|
-e 's/\*\([^*]*\)\*/\1/g' \
|
||||||
|
-e 's/__\([^_]*\)__/\1/g' \
|
||||||
|
-e 's/_\([^_]*\)_/\1/g' \
|
||||||
|
-e 's/`\([^`]*\)`/\1/g' \
|
||||||
|
-e 's/\[\([^]]*\)](\([^)]*\))/\1/g' \
|
||||||
|
-e 's/!\[\([^]]*\)](\([^)]*\))//g' \
|
||||||
|
-e 's/^[[:space:]]*[-*+] //' \
|
||||||
|
-e 's/^[[:space:]]*[0-9]\{1,\}\. //' \
|
||||||
|
-e 's/^>[[:space:]]*//' \
|
||||||
|
-e 's/<[^>]*>//g' \
|
||||||
|
-e '/^[[:space:]]*$/d' \
|
||||||
|
-e 's/|//g' \
|
||||||
|
-e 's/^[[:space:]]*---[[:space:]]*$//' |
|
||||||
|
tr '\n' ' ' |
|
||||||
|
sed -e 's/ */ /g' -e 's/\\/\\\\/g' -e 's/"/\\"/g' |
|
||||||
|
awk '{ print substr($0, 1, 500) }'
|
||||||
|
}
|
||||||
|
|
||||||
|
build_markdown_manifest() {
|
||||||
|
manifest_root="$KEWT_TMPDIR/manifest"
|
||||||
|
manifest_meta_root="$manifest_root/meta"
|
||||||
|
manifest_dir_meta_root="$manifest_root/dir-meta"
|
||||||
|
manifest_all_list="$manifest_root/all.lst"
|
||||||
|
manifest_visible_list="$manifest_root/visible.lst"
|
||||||
|
manifest_hidden_dirs_list="$manifest_root/hidden-dirs.lst"
|
||||||
|
|
||||||
|
rm -rf "$manifest_root"
|
||||||
|
mkdir -p "$manifest_meta_root"
|
||||||
|
mkdir -p "$manifest_dir_meta_root"
|
||||||
|
: > "$manifest_all_list"
|
||||||
|
: > "$manifest_visible_list"
|
||||||
|
: > "$manifest_hidden_dirs_list"
|
||||||
|
|
||||||
|
eval "find \"$src\" \( $IGNORE_ARGS \) -prune -o -name \"*.md\" -print" | sort | while IFS= read -r manifest_file; do
|
||||||
|
manifest_rel_path="${manifest_file#"$src"/}"
|
||||||
|
manifest_dir_rel=$(dirname "$manifest_rel_path")
|
||||||
|
manifest_filename=$(basename "$manifest_rel_path")
|
||||||
|
manifest_is_index="false"
|
||||||
|
[ "$manifest_filename" = "index.md" ] && manifest_is_index="true"
|
||||||
|
|
||||||
|
parse_frontmatter "$manifest_file"
|
||||||
|
if [ "$manifest_filename" = "index.md" ] && [ "$fm_draft" = "true" ]; then
|
||||||
|
printf '%s\n' "$manifest_dir_rel" >> "$manifest_hidden_dirs_list"
|
||||||
|
fi
|
||||||
|
markdown_title_from_loaded_file "$manifest_file" "$title - Page"
|
||||||
|
manifest_title="$markdown_title"
|
||||||
|
set_post_datetime "$fm_date" "$(basename "$manifest_file" .md)"
|
||||||
|
|
||||||
|
manifest_post_date="$post_date"
|
||||||
|
manifest_post_time="$post_time"
|
||||||
|
manifest_post_slug=$(basename "$manifest_file" .md | sed \
|
||||||
|
-e 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}[:\-][0-9]\{2\}//' \
|
||||||
|
-e 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}//' \
|
||||||
|
-e 's/^[_\-]//')
|
||||||
|
|
||||||
|
if [ "$manifest_is_index" = "true" ]; then
|
||||||
|
if [ "$manifest_rel_path" = "index.md" ]; then
|
||||||
|
manifest_url="/index.html"
|
||||||
|
else
|
||||||
|
manifest_url=$(directory_index_url "${manifest_rel_path%/index.md}")
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
manifest_url=$(markdown_file_url "$manifest_rel_path")
|
||||||
|
fi
|
||||||
|
|
||||||
|
manifest_search_content=""
|
||||||
|
if [ "$generate_search" = "true" ]; then
|
||||||
|
manifest_search_content=$(extract_search_content "$manifest_file")
|
||||||
|
fi
|
||||||
|
|
||||||
|
manifest_meta_file=$(manifest_meta_path "$manifest_rel_path")
|
||||||
|
mkdir -p "$(dirname "$manifest_meta_file")"
|
||||||
|
{
|
||||||
|
printf 'manifest_rel_path=%s\n' "$(shell_quote "$manifest_rel_path")"
|
||||||
|
printf 'manifest_dir_rel=%s\n' "$(shell_quote "$manifest_dir_rel")"
|
||||||
|
printf 'manifest_filename=%s\n' "$(shell_quote "$manifest_filename")"
|
||||||
|
printf 'manifest_is_index=%s\n' "$(shell_quote "$manifest_is_index")"
|
||||||
|
printf 'manifest_title=%s\n' "$(shell_quote "$manifest_title")"
|
||||||
|
printf 'manifest_date=%s\n' "$(shell_quote "$fm_date")"
|
||||||
|
printf 'manifest_draft=%s\n' "$(shell_quote "$fm_draft")"
|
||||||
|
printf 'manifest_description=%s\n' "$(shell_quote "$fm_description")"
|
||||||
|
printf 'manifest_content_warning=%s\n' "$(shell_quote "$fm_content_warning")"
|
||||||
|
printf 'manifest_tags=%s\n' "$(shell_quote "$fm_tags")"
|
||||||
|
printf 'manifest_url=%s\n' "$(shell_quote "$manifest_url")"
|
||||||
|
printf 'manifest_search_content=%s\n' "$(shell_quote "$manifest_search_content")"
|
||||||
|
printf 'manifest_post_date=%s\n' "$(shell_quote "$manifest_post_date")"
|
||||||
|
printf 'manifest_post_time=%s\n' "$(shell_quote "$manifest_post_time")"
|
||||||
|
printf 'manifest_post_slug=%s\n' "$(shell_quote "$manifest_post_slug")"
|
||||||
|
} > "$manifest_meta_file"
|
||||||
|
|
||||||
|
if load_manifest_dir_entry "$manifest_dir_rel"; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
dir_md_count=0
|
||||||
|
dir_first_md=""
|
||||||
|
dir_has_index="false"
|
||||||
|
fi
|
||||||
|
|
||||||
|
dir_md_count=$((dir_md_count + 1))
|
||||||
|
if [ -z "$dir_first_md" ]; then
|
||||||
|
dir_first_md="$manifest_rel_path"
|
||||||
|
fi
|
||||||
|
if [ "$manifest_filename" = "index.md" ]; then
|
||||||
|
dir_has_index="true"
|
||||||
|
fi
|
||||||
|
write_manifest_dir_meta "$manifest_dir_rel" "$dir_md_count" "$dir_first_md" "$dir_has_index"
|
||||||
|
|
||||||
|
printf '%s\n' "$manifest_rel_path" >> "$manifest_all_list"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -s "$manifest_hidden_dirs_list" ]; then
|
||||||
|
LC_ALL=C sort -u "$manifest_hidden_dirs_list" > "$manifest_hidden_dirs_list.sorted"
|
||||||
|
mv "$manifest_hidden_dirs_list.sorted" "$manifest_hidden_dirs_list"
|
||||||
|
fi
|
||||||
|
|
||||||
|
eval "find \"$src\" \( $IGNORE_ARGS -o $HIDE_ARGS -o $PRESERVE_ARGS \) -prune -o -name \"*.md\" -print" | sort | while IFS= read -r visible_file; do
|
||||||
|
visible_rel_path="${visible_file#"$src"/}"
|
||||||
|
load_manifest_entry "$visible_rel_path" || continue
|
||||||
|
[ "$manifest_draft" = "true" ] && continue
|
||||||
|
manifest_dir_hidden_by_draft_index "$manifest_dir_rel" && continue
|
||||||
|
printf '%s\n' "$visible_rel_path" >> "$manifest_visible_list"
|
||||||
|
done
|
||||||
|
}
|
||||||
105
lib/metadata.sh
Normal file
105
lib/metadata.sh
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
parse_frontmatter() {
|
||||||
|
_fm_file="$1"
|
||||||
|
_fm_out="$KEWT_TMPDIR/fm_vals.txt"
|
||||||
|
: > "$_fm_out"
|
||||||
|
awk -v fm_out="$_fm_out" -f "$awk_dir/frontmatter.awk" "$_fm_file" > /dev/null
|
||||||
|
fm_title=""
|
||||||
|
fm_date=""
|
||||||
|
fm_draft=""
|
||||||
|
fm_description=""
|
||||||
|
fm_content_warning=""
|
||||||
|
fm_tags=""
|
||||||
|
while IFS='=' read -r _fk _fv; do
|
||||||
|
case "$_fk" in
|
||||||
|
title) fm_title="$_fv" ;;
|
||||||
|
date) fm_date="$_fv" ;;
|
||||||
|
draft) fm_draft="$_fv" ;;
|
||||||
|
description) fm_description="$_fv" ;;
|
||||||
|
content_warning) fm_content_warning="$_fv" ;;
|
||||||
|
tags) fm_tags="$_fv" ;;
|
||||||
|
esac
|
||||||
|
done < "$_fm_out"
|
||||||
|
rm -f "$_fm_out"
|
||||||
|
}
|
||||||
|
|
||||||
|
strip_markdown_text() {
|
||||||
|
printf '%s' "$1" | sed \
|
||||||
|
-e 's/\[//g' \
|
||||||
|
-e 's/\]//g' \
|
||||||
|
-e 's/!//g' \
|
||||||
|
-e 's/\*//g' \
|
||||||
|
-e 's/_//g' \
|
||||||
|
-e 's/`//g' \
|
||||||
|
-e 's/([^)]*)//g' \
|
||||||
|
-e 's/\\//g'
|
||||||
|
}
|
||||||
|
|
||||||
|
first_heading_from_markdown() {
|
||||||
|
grep -m 1 '^# ' "$1" | sed 's/^# *//; s/ *$//'
|
||||||
|
}
|
||||||
|
|
||||||
|
markdown_title_from_loaded_file() {
|
||||||
|
_title_file="$1"
|
||||||
|
_title_default="$2"
|
||||||
|
markdown_title="$fm_title"
|
||||||
|
|
||||||
|
if [ -z "$markdown_title" ]; then
|
||||||
|
markdown_title=$(first_heading_from_markdown "$_title_file")
|
||||||
|
if [ -n "$markdown_title" ]; then
|
||||||
|
markdown_title=$(strip_markdown_text "$markdown_title")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$markdown_title" ]; then
|
||||||
|
basename_no_ext=$(basename "$_title_file" .md)
|
||||||
|
if [ "$basename_no_ext" != "index" ] && [ "$basename_no_ext" != "404_gen" ]; then
|
||||||
|
markdown_title=$(echo "$basename_no_ext" | awk '{print toupper(substr($0,1,1)) substr($0,2)}')
|
||||||
|
else
|
||||||
|
markdown_title="$_title_default"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
markdown_title_from_file() {
|
||||||
|
_title_file="$1"
|
||||||
|
_title_default="$2"
|
||||||
|
parse_frontmatter "$_title_file"
|
||||||
|
markdown_title_from_loaded_file "$_title_file" "$_title_default"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_post_datetime() {
|
||||||
|
_raw_date="$1"
|
||||||
|
_fallback_name="$2"
|
||||||
|
|
||||||
|
if [ -n "$_raw_date" ]; then
|
||||||
|
post_date=$(echo "$_raw_date" | sed 's/^\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\).*/\1/')
|
||||||
|
post_time=""
|
||||||
|
if echo "$_raw_date" | grep -q '^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}[ T_-]\?[0-9]\{2\}[:\-][0-9]\{2\}'; then
|
||||||
|
post_time=$(echo "$_raw_date" | sed 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}[ T_-]\?\([0-9]\{2\}[:\-][0-9]\{2\}\).*/\1/' | tr '-' ':')
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
post_date=$(echo "$_fallback_name" | sed 's/^\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\).*/\1/')
|
||||||
|
post_time="00:00"
|
||||||
|
if echo "$_fallback_name" | grep -q '^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}[:\-][0-9]\{2\}'; then
|
||||||
|
post_time=$(echo "$_fallback_name" | sed 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-\([0-9]\{2\}[:\-][0-9]\{2\}\).*/\1/' | tr '-' ':')
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_post_metadata() {
|
||||||
|
_post_file="$1"
|
||||||
|
_default_title="$2"
|
||||||
|
_basename_no_ext=$(basename "$_post_file" .md)
|
||||||
|
|
||||||
|
markdown_title_from_file "$_post_file" "$_default_title"
|
||||||
|
post_heading="$markdown_title"
|
||||||
|
set_post_datetime "$fm_date" "$_basename_no_ext"
|
||||||
|
|
||||||
|
post_slug=$(echo "$_basename_no_ext" | sed \
|
||||||
|
-e 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{2\}[:\-][0-9]\{2\}//' \
|
||||||
|
-e 's/^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}//' \
|
||||||
|
-e 's/^[_\-]//')
|
||||||
|
}
|
||||||
193
lib/runtime.sh
Normal file
193
lib/runtime.sh
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
trim_whitespace() {
|
||||||
|
printf '%s' "$1" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//'
|
||||||
|
}
|
||||||
|
|
||||||
|
encode_url_path() {
|
||||||
|
printf '%s' "$1" | sed \
|
||||||
|
-e 's/%/%25/g' \
|
||||||
|
-e 's/ /%20/g' \
|
||||||
|
-e 's/#/%23/g' \
|
||||||
|
-e 's/?/%3F/g' \
|
||||||
|
-e 's/"/%22/g' \
|
||||||
|
-e "s/'/%27/g"
|
||||||
|
}
|
||||||
|
|
||||||
|
markdown_file_url() {
|
||||||
|
_rel_path="$1"
|
||||||
|
printf '/%s.html\n' "$(encode_url_path "${_rel_path%.md}")"
|
||||||
|
}
|
||||||
|
|
||||||
|
directory_index_url() {
|
||||||
|
_rel_dir="$1"
|
||||||
|
if [ -z "$_rel_dir" ] || [ "$_rel_dir" = "." ]; then
|
||||||
|
printf '/index.html\n'
|
||||||
|
else
|
||||||
|
printf '/%s/index.html\n' "$(encode_url_path "$_rel_dir")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
format_rfc2822_utc() {
|
||||||
|
_rfc_date="$1"
|
||||||
|
_rfc_time="${2:-00:00}"
|
||||||
|
[ -n "$_rfc_time" ] || _rfc_time="00:00"
|
||||||
|
awk -v d="$_rfc_date" -v t="$_rfc_time" '
|
||||||
|
function weekday(y, m, day, k, j, h) {
|
||||||
|
if (m < 3) {
|
||||||
|
m += 12
|
||||||
|
y--
|
||||||
|
}
|
||||||
|
k = y % 100
|
||||||
|
j = int(y / 100)
|
||||||
|
h = (day + int((13 * (m + 1)) / 5) + k + int(k / 4) + int(j / 4) + 5 * j) % 7
|
||||||
|
return (h + 6) % 7
|
||||||
|
}
|
||||||
|
BEGIN {
|
||||||
|
split(d, da, "-")
|
||||||
|
split(t, ti, ":")
|
||||||
|
year = da[1] + 0
|
||||||
|
month = da[2] + 0
|
||||||
|
day = da[3] + 0
|
||||||
|
hour = (ti[1] == "" ? 0 : ti[1]) + 0
|
||||||
|
minute = (ti[2] == "" ? 0 : ti[2]) + 0
|
||||||
|
|
||||||
|
months[1] = "Jan"; months[2] = "Feb"; months[3] = "Mar"; months[4] = "Apr"
|
||||||
|
months[5] = "May"; months[6] = "Jun"; months[7] = "Jul"; months[8] = "Aug"
|
||||||
|
months[9] = "Sep"; months[10] = "Oct"; months[11] = "Nov"; months[12] = "Dec"
|
||||||
|
|
||||||
|
days[0] = "Sun"; days[1] = "Mon"; days[2] = "Tue"; days[3] = "Wed"
|
||||||
|
days[4] = "Thu"; days[5] = "Fri"; days[6] = "Sat"
|
||||||
|
|
||||||
|
printf "%s, %02d %s %04d %02d:%02d:00 +0000\n",
|
||||||
|
days[weekday(year, month, day)], day, months[month], year, hour, minute
|
||||||
|
}
|
||||||
|
'
|
||||||
|
}
|
||||||
|
|
||||||
|
append_find_rule() {
|
||||||
|
_expr="$1"
|
||||||
|
_rule="$2"
|
||||||
|
|
||||||
|
if [ -n "$_expr" ]; then
|
||||||
|
printf '%s -o %s\n' "$_expr" "$_rule"
|
||||||
|
else
|
||||||
|
printf '%s\n' "$_rule"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
append_pattern_rules_from_file() {
|
||||||
|
_expr="$1"
|
||||||
|
_root="$2"
|
||||||
|
_file="$3"
|
||||||
|
|
||||||
|
while IFS= read -r line || [ -n "$line" ]; do
|
||||||
|
case "$line" in
|
||||||
|
''|'#'*) continue ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
pattern=$(trim_whitespace "$line")
|
||||||
|
[ -z "$pattern" ] && continue
|
||||||
|
|
||||||
|
pattern_clean="${pattern#/}"
|
||||||
|
pattern_clean="${pattern_clean%/}"
|
||||||
|
|
||||||
|
if echo "$pattern" | grep -q "/"; then
|
||||||
|
_expr=$(append_find_rule "$_expr" "-path '$_root/$pattern_clean'")
|
||||||
|
_expr=$(append_find_rule "$_expr" "-path '$_root/$pattern_clean/*'")
|
||||||
|
else
|
||||||
|
_expr=$(append_find_rule "$_expr" "-name '$pattern_clean'")
|
||||||
|
fi
|
||||||
|
done < "$_file"
|
||||||
|
|
||||||
|
printf '%s\n' "$_expr"
|
||||||
|
}
|
||||||
|
|
||||||
|
append_nested_marker_rules() {
|
||||||
|
_expr="$1"
|
||||||
|
_root="$2"
|
||||||
|
_marker="$3"
|
||||||
|
_tmp_file="$KEWT_TMPDIR/${_marker#*.}_paths"
|
||||||
|
|
||||||
|
find "$_root" -name "$_marker" > "$_tmp_file"
|
||||||
|
while IFS= read -r marker_path; do
|
||||||
|
marker_dir="${marker_path%/"$marker"}"
|
||||||
|
if [ "$marker_dir" != "$_root" ] && [ "$marker_dir" != "." ]; then
|
||||||
|
_expr=$(append_find_rule "$_expr" "-path '$marker_dir'")
|
||||||
|
_expr=$(append_find_rule "$_expr" "-path '$marker_dir/*'")
|
||||||
|
fi
|
||||||
|
done < "$_tmp_file"
|
||||||
|
rm -f "$_tmp_file"
|
||||||
|
|
||||||
|
printf '%s\n' "$_expr"
|
||||||
|
}
|
||||||
|
|
||||||
|
build_rule_args() {
|
||||||
|
_root="$1"
|
||||||
|
_marker="$2"
|
||||||
|
_base_expr="$3"
|
||||||
|
|
||||||
|
_expr="$_base_expr"
|
||||||
|
if [ -f "$_root/$_marker" ]; then
|
||||||
|
_expr=$(append_pattern_rules_from_file "$_expr" "$_root" "$_root/$_marker")
|
||||||
|
fi
|
||||||
|
_expr=$(append_nested_marker_rules "$_expr" "$_root" "$_marker")
|
||||||
|
printf '%s\n' "$_expr"
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_template_path() {
|
||||||
|
template="$src/template.html"
|
||||||
|
[ -f "$template" ] || template="./template.html"
|
||||||
|
if [ ! -f "$template" ]; then
|
||||||
|
template="$KEWT_TMPDIR/default_template.html"
|
||||||
|
printf '%s\n' "$DEFAULT_TMPL" > "$template"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
build_full_nav() {
|
||||||
|
nav=$(generate_nav "$src")
|
||||||
|
extra_links=$(nav_links_html)
|
||||||
|
if [ -n "$extra_links" ]; then
|
||||||
|
nav="$nav
|
||||||
|
$extra_links"
|
||||||
|
fi
|
||||||
|
if [ -n "$nav_extra" ]; then
|
||||||
|
nav="$nav
|
||||||
|
$nav_extra"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh_build_context() {
|
||||||
|
reset_config
|
||||||
|
load_config "./site.conf"
|
||||||
|
load_config "$src/site.conf"
|
||||||
|
|
||||||
|
HIDE_ARGS="$BASE_HIDE_ARGS"
|
||||||
|
if [ -n "$posts_dir" ]; then
|
||||||
|
HIDE_ARGS=$(append_find_rule "$HIDE_ARGS" "-path '$src/$posts_dir/*'")
|
||||||
|
fi
|
||||||
|
|
||||||
|
asset_version=""
|
||||||
|
if [ "$versioning" = "true" ]; then
|
||||||
|
asset_version="?v=$(date '+%Y%m%d%H%M%S')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
resolve_template_path
|
||||||
|
}
|
||||||
|
|
||||||
|
watch_for_changes() {
|
||||||
|
_mark_file="$1"
|
||||||
|
|
||||||
|
changed="$(find "$src" -type f -newer "$_mark_file" 2>/dev/null | head -n 1)"
|
||||||
|
[ -z "$changed" ] && [ -f "site.conf" ] && [ "site.conf" -nt "$_mark_file" ] && changed="site.conf"
|
||||||
|
[ -z "$changed" ] && [ -f "$src/site.conf" ] && [ "$src/site.conf" -nt "$_mark_file" ] && changed="$src/site.conf"
|
||||||
|
[ -z "$changed" ] && [ -f "$template" ] && [ "$template" -nt "$_mark_file" ] && changed="$template"
|
||||||
|
[ -z "$changed" ] && [ -d "$script_dir/styles" ] && changed="$(find "$script_dir/styles" -type f -newer "$_mark_file" 2>/dev/null | head -n 1)"
|
||||||
|
|
||||||
|
printf '%s\n' "$changed"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_posts_directory_rel() {
|
||||||
|
_rel_dir="$1"
|
||||||
|
[ -n "$posts_dir" ] && { [ "$_rel_dir" = "$posts_dir" ] || [ "./$_rel_dir" = "$posts_dir" ]; }
|
||||||
|
}
|
||||||
54
lib/search.js
Normal file
54
lib/search.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
var params = new URLSearchParams(window.location.search);
|
||||||
|
var query = params.get("q");
|
||||||
|
var box = document.getElementById("search-box");
|
||||||
|
var resultsContainer = document.getElementById("search-results-list");
|
||||||
|
|
||||||
|
if (box && query) box.value = query;
|
||||||
|
|
||||||
|
if (!query) {
|
||||||
|
resultsContainer.innerHTML = "<p>Enter a search term above.</p>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch("/search.json")
|
||||||
|
.then(function (response) {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function (data) {
|
||||||
|
var q = query.toLowerCase();
|
||||||
|
var results = data.filter(function (item) {
|
||||||
|
return (
|
||||||
|
item.title.toLowerCase().indexOf(q) !== -1 ||
|
||||||
|
item.content.toLowerCase().indexOf(q) !== -1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
var esc = query.replace(/</g, "<").replace(/>/g, ">");
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
resultsContainer.innerHTML =
|
||||||
|
'<p>No results found for "<strong>' + esc + '</strong>".</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var html =
|
||||||
|
"<p>Found " +
|
||||||
|
results.length +
|
||||||
|
' result(s) for "<strong>' +
|
||||||
|
esc +
|
||||||
|
'</strong>":</p>';
|
||||||
|
results.forEach(function (result) {
|
||||||
|
var snippet = result.content.substring(0, 200);
|
||||||
|
if (result.content.length > 200) snippet += "...";
|
||||||
|
html += '<div class="search-result">';
|
||||||
|
html += '<a href="' + result.url + '">' + result.title + "</a>";
|
||||||
|
if (snippet) html += "<p>" + snippet + "</p>";
|
||||||
|
html += "</div>";
|
||||||
|
});
|
||||||
|
resultsContainer.innerHTML = html;
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
resultsContainer.innerHTML = "<p>Error loading search index.</p>";
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -15,7 +15,8 @@ sed_inplace() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_file="${KEWT_TMPDIR:-/tmp}/markdown.$$.md"
|
temp_parent="${KEWT_TMPDIR:-${TMPDIR:-/tmp}}"
|
||||||
|
temp_file="${temp_parent}/markdown.$$.md"
|
||||||
cat "$@" > "$temp_file"
|
cat "$@" > "$temp_file"
|
||||||
|
|
||||||
trap 'rm -f "$temp_file" "$temp_file.tmp" "$temp_file.fm"' EXIT INT TERM
|
trap 'rm -f "$temp_file" "$temp_file.tmp" "$temp_file.fm"' EXIT INT TERM
|
||||||
@@ -30,7 +31,7 @@ awk -f "$awk_dir/mask_inline_code.awk" "$temp_file" > "$temp_file.tmp" && mv "$t
|
|||||||
awk -f "$awk_dir/mask_plain.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/mask_plain.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
|
|
||||||
# Reference links
|
# Reference links
|
||||||
refs=$(cat "$@" | awk '/^\[[^\]]+\]: */')
|
refs=$(awk '/^\[[^\]]+\]: */' "$temp_file")
|
||||||
IFS='
|
IFS='
|
||||||
'
|
'
|
||||||
for ref in $refs; do
|
for ref in $refs; do
|
||||||
@@ -61,7 +62,6 @@ awk -v custom_admonitions="$CUSTOM_ADMONITIONS" -f "$awk_dir/blockquote_to_admon
|
|||||||
awk -f "$awk_dir/fenced_code.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/fenced_code.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -f "$awk_dir/indented_code.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/indented_code.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -f "$awk_dir/pipe_tables.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/pipe_tables.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -v enable_header_links="$ENABLE_HEADER_LINKS" -f "$awk_dir/headers.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
|
||||||
awk -f "$awk_dir/definition_lists.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/definition_lists.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -f "$awk_dir/lists.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/lists.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
|
|
||||||
@@ -75,7 +75,8 @@ awk -f "$awk_dir/breaks.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.t
|
|||||||
awk -f "$awk_dir/paragraphs.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/paragraphs.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
|
|
||||||
# Inline styles
|
# Inline styles
|
||||||
awk -f "$awk_dir/emoji.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -v emoji_file="$awk_dir/emoji.tsv" -f "$awk_dir/emoji.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -f "$awk_dir/markdown_inline.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
awk -f "$awk_dir/markdown_inline.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
|
awk -v enable_header_links="$ENABLE_HEADER_LINKS" -f "$awk_dir/headers.awk" "$temp_file" > "$temp_file.tmp" && mv "$temp_file.tmp" "$temp_file"
|
||||||
awk -v input_file="$1" -v site_root="$MARKDOWN_SITE_ROOT" -v fallback_file="$MARKDOWN_FALLBACK_FILE" -v script_dir="$script_dir" -f "$awk_dir/markdown_embed.awk" "$temp_file"
|
awk -v input_file="$1" -v site_root="$MARKDOWN_SITE_ROOT" -v fallback_file="$MARKDOWN_FALLBACK_FILE" -v script_dir="$script_dir" -f "$awk_dir/markdown_embed.awk" "$temp_file"
|
||||||
rm "$temp_file"
|
rm "$temp_file"
|
||||||
|
|||||||
@@ -3,5 +3,7 @@
|
|||||||
"description": "A minimalist static site generator inspired by werc",
|
"description": "A minimalist static site generator inspired by werc",
|
||||||
"global": "true",
|
"global": "true",
|
||||||
"install": "make install",
|
"install": "make install",
|
||||||
"scripts": ["kewt"]
|
"scripts": [
|
||||||
|
"kewt"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,4 +26,6 @@ build() {
|
|||||||
package() {
|
package() {
|
||||||
cd "${pkgname}"
|
cd "${pkgname}"
|
||||||
install -Dm755 kewt "${pkgdir}/usr/bin/kewt"
|
install -Dm755 kewt "${pkgdir}/usr/bin/kewt"
|
||||||
|
install -d "${pkgdir}/usr/share/zsh/site-functions"
|
||||||
|
"${pkgdir}/usr/bin/kewt" --dump-zsh-completions > "${pkgdir}/usr/share/zsh/site-functions/_kewt"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,4 +18,6 @@ build() {
|
|||||||
|
|
||||||
package() {
|
package() {
|
||||||
install -Dm755 "${srcdir}/${pkgname}-${pkgver}.sh" "${pkgdir}/usr/bin/kewt"
|
install -Dm755 "${srcdir}/${pkgname}-${pkgver}.sh" "${pkgdir}/usr/bin/kewt"
|
||||||
|
install -d "${pkgdir}/usr/share/zsh/site-functions"
|
||||||
|
"${pkgdir}/usr/bin/kewt" --dump-zsh-completions > "${pkgdir}/usr/share/zsh/site-functions/_kewt"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class Kewt < Formula
|
|||||||
|
|
||||||
def install
|
def install
|
||||||
bin.install "kewt"
|
bin.install "kewt"
|
||||||
|
generate_completions_from_executable(bin/"kewt", "--dump-zsh-completions", shells: [:zsh])
|
||||||
end
|
end
|
||||||
|
|
||||||
test do
|
test do
|
||||||
|
|||||||
25
packaging/zsh/_kewt
Normal file
25
packaging/zsh/_kewt
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#compdef kewt
|
||||||
|
|
||||||
|
_kewt() {
|
||||||
|
local -a args
|
||||||
|
args=(
|
||||||
|
'--help[Show help message]'
|
||||||
|
'(-h)--help[Show help message]'
|
||||||
|
'(-)--new[Create a new site directory]'
|
||||||
|
'(-)--init[Create a new site directory (alias for --new)]'
|
||||||
|
'(-)--clean[Clean the output directory before building]'
|
||||||
|
'(-)--no-clean[Do not clean the output directory before building]'
|
||||||
|
'(-)--update[Update site.conf and template.html with latest defaults]'
|
||||||
|
'(-)--post[Create a new empty post file in the configured posts_dir]'
|
||||||
|
'(-)--generate-template[Generate a new template file]'
|
||||||
|
'(-v --version)'{-v,--version}'[Show version information]'
|
||||||
|
'--from[Source directory]:directory:_directories'
|
||||||
|
'--to[Output directory]:directory:_directories'
|
||||||
|
'(-w --watch)'{-w,--watch}'[Watch for file changes and rebuild automatically]'
|
||||||
|
'(-s --serve)'{-s,--serve}'[Start a local HTTP server after building]::port:'
|
||||||
|
)
|
||||||
|
|
||||||
|
_arguments -S -C $args '*: :_directories'
|
||||||
|
}
|
||||||
|
|
||||||
|
_kewt "$@"
|
||||||
BIN
site/button.gif
BIN
site/button.gif
Binary file not shown.
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus malesuada lacus eu ligula semper pharetra. Cras viverra volutpat massa nec sagittis. Aliquam fringilla quam ut tincidunt ultricies. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed id sagittis nisi. Aenean vitae urna justo. Vivamus dictum eros ac mi convallis, blandit hendrerit nunc sagittis. Mauris feugiat neque quis justo molestie, vel pulvinar diam faucibus. Ut tempus magna sit amet ex pharetra mollis. Ut elementum metus metus, id consectetur est tempor eget. Proin sed nibh tincidunt, porttitor elit non, blandit ligula. Ut condimentum accumsan lobortis. Nullam nec tempus leo, sit amet iaculis erat. Donec rutrum, orci in elementum varius, nisl elit rutrum nunc, in lacinia lorem enim non enim.
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus malesuada lacus eu ligula semper pharetra. Cras viverra volutpat massa nec sagittis. Aliquam fringilla quam ut tincidunt ultricies. Aliquam erat volutpat. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed id sagittis nisi. Aenean vitae urna justo. Vivamus dictum eros ac mi convallis, blandit hendrerit nunc sagittis. Mauris feugiat neque quis justo molestie, vel pulvinar diam faucibus. Ut tempus magna sit amet ex pharetra mollis. Ut elementum metus metus, id consectetur est tempor eget. Proin sed nibh tincidunt, porttitor elit non, blandit ligula. Ut condimentum accumsan lobortis. Nullam nec tempus leo, sit amet iaculis erat. Donec rutrum, orci in elementum varius, nisl elit rutrum nunc, in lacinia lorem enim non enim.
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
This is a custom index for a directory
|
This is a custom index for a directory
|
||||||
|
|
||||||
{{LIST}}
|
{{LIST}}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ title = "Configuration"
|
|||||||
```conf
|
```conf
|
||||||
title = "kewt"
|
title = "kewt"
|
||||||
style = "kewt"
|
style = "kewt"
|
||||||
|
lang = "en"
|
||||||
|
draft_by_default = false
|
||||||
dir_indexes = true
|
dir_indexes = true
|
||||||
single_file_index = true
|
single_file_index = true
|
||||||
flatten = false
|
flatten = false
|
||||||
@@ -33,9 +35,17 @@ posts_dir = ""
|
|||||||
posts_per_page = 12
|
posts_per_page = 12
|
||||||
custom_admonitions = ""
|
custom_admonitions = ""
|
||||||
cw_hide_url = true
|
cw_hide_url = true
|
||||||
|
generate_tags = false
|
||||||
|
tags_dir = "tags"
|
||||||
|
generate_search = false
|
||||||
|
search_in_footer = false
|
||||||
|
search_in_header = false
|
||||||
|
include_cw_pages_in_search = false
|
||||||
```
|
```
|
||||||
- `title` - site title
|
- `title` - site title
|
||||||
- `style` - style file name from `./styles` (without `.css`)
|
- `style` - style name from the built-in `styles/` directory. See [Theming](theming.md)
|
||||||
|
- `lang` - document language, used for the `<html lang="...">` attribute (default: "en")
|
||||||
|
- `draft_by_default` - default value for the `draft` frontmatter field in new posts created (default: false)
|
||||||
- `dir_indexes` - generate directory index pages when missing `index.md`
|
- `dir_indexes` - generate directory index pages when missing `index.md`
|
||||||
- `single_file_index` - if a directory has one markdown file and no `index.md`, use that file as `index.html`
|
- `single_file_index` - if a directory has one markdown file and no `index.md`, use that file as `index.html`
|
||||||
- `flatten` - flatten sidebar directory levels
|
- `flatten` - flatten sidebar directory levels
|
||||||
@@ -52,18 +62,24 @@ cw_hide_url = true
|
|||||||
- `favicon` - explicit favicon path (used when `logo_as_favicon` is false or no logo is set)
|
- `favicon` - explicit favicon path (used when `logo_as_favicon` is false or no logo is set)
|
||||||
- `generate_page_title` - automatically generate title text from the first markdown heading or filename (default: true)
|
- `generate_page_title` - automatically generate title text from the first markdown heading or filename (default: true)
|
||||||
- `error_page` - filename for the generated 404 error page (default: "not_found.html", empty to disable)
|
- `error_page` - filename for the generated 404 error page (default: "not_found.html", empty to disable)
|
||||||
- `versioning` - append a version query parameter (`?v=timestamp`) to css asset urls to bypass cache (default: false)
|
- `versioning` - append a build-time version query parameter (for example `?v=20260505193210`) to css asset urls to bypass cache (default: false)
|
||||||
|
- `enable_header_links` - turns markdown section headings into clickable anchor links (default: true)
|
||||||
- `base_url` - absolute URL of the site, used for sitemap and RSS feed generation
|
- `base_url` - absolute URL of the site, used for sitemap and RSS feed generation
|
||||||
- `generate_feed` - enable RSS feed generation (requires `base_url`)
|
- `generate_feed` - enable RSS feed generation (requires `base_url`)
|
||||||
- `feed_file` - filename for the generated RSS feed (default: "rss.xml")
|
- `feed_file` - filename for the generated RSS feed (default: "rss.xml")
|
||||||
- `posts_dir` - directory name containing posts (e.g., "posts"). Enables reverse-chronological sorting, title headings in indexes, and automatic backlinks.
|
- `posts_dir` - directory name containing posts (e.g., "posts"). Enables reverse-chronological sorting, title headings in indexes, and automatic backlinks.
|
||||||
- `posts_per_page` - number of posts per page in paginated post indexes (default: 12). Set to 0 to disable pagination.
|
- `posts_per_page` - number of posts per page in paginated post indexes (default: 12). Set to 0 to disable pagination.
|
||||||
- `enable_header_links` - turns markdown section headings into clickable anchor links (default: true)
|
|
||||||
- `custom_admonitions` - comma separated list of custom admonitions
|
- `custom_admonitions` - comma separated list of custom admonitions
|
||||||
- `cw_hide_url` - embeds non-breaking JS to replace the URL in the browser bar on content warning pages (default: true)
|
- `cw_hide_url` - embeds non-breaking JS to replace the URL in the browser bar on content warning pages (default: true)
|
||||||
|
- `generate_tags` - generate tag index pages from post frontmatter (requires `posts_dir`)
|
||||||
|
- `tags_dir` - directory name for generated tag pages (default: "tags")
|
||||||
|
- `generate_search` - generate a `search.json` index for client-side search
|
||||||
|
- `search_in_footer` - include a search box in the page footer (requires `generate_search`)
|
||||||
|
- `search_in_header` - include a search box in the page header (requires `generate_search` and a template that includes `{{HEADER_SEARCH}}`)
|
||||||
|
- `include_cw_pages_in_search` - include content warning pages in the search index (default: false)
|
||||||
|
|
||||||
## Dot Files
|
## Dot Files
|
||||||
|
|
||||||
- `.kewtignore` - files/directories to ignore completely. If the file is empty, the whole directory gets ignored.
|
- `.kewtignore` - files/directories to ignore completely. If the file is empty, the whole directory gets ignored.
|
||||||
- `.kewthide` - files/directories to hide from navigation but still process. Same empty-file rules as `.kewtignore`.
|
- `.kewthide` - files/directories to hide from navigation but still process. Same empty-file rules as `.kewtignore`.
|
||||||
- `.kewtpreserve` - files/directories to copy as-is without converting markdown to HTML. Same empty-file rules again.
|
- `.kewtpreserve` - files/directories to copy as-is without converting markdown to HTML. Same empty-file rules again.
|
||||||
|
|||||||
@@ -13,6 +13,14 @@ title = "Embeds"
|
|||||||
|
|
||||||
If you want to **force** a file to be inlined, use `\!![]` instead of `\![]`
|
If you want to **force** a file to be inlined, use `\!![]` instead of `\![]`
|
||||||
|
|
||||||
|
## Reality-Breaking Embeds
|
||||||
|
|
||||||
|
`\!![link]` and `\!` work even inside inline code blocks. If the content between backticks consists only of `\!![]` embeds, the embed triggers and the content is inlined instead of being rendered as code.
|
||||||
|
|
||||||
|
```
|
||||||
|
`!![/file.sh]`
|
||||||
|
```
|
||||||
|
|
||||||
## Typed Embeds
|
## Typed Embeds
|
||||||
|
|
||||||
Force specific output regardless of extension:
|
Force specific output regardless of extension:
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ title = "Custom Page Title"
|
|||||||
date = "2026-03-23 11:32"
|
date = "2026-03-23 11:32"
|
||||||
draft = false
|
draft = false
|
||||||
description = "A short page summary"
|
description = "A short page summary"
|
||||||
|
tags = "example, tutorial"
|
||||||
---
|
---
|
||||||
```
|
```
|
||||||
- `title` - overrides the page title, post name in index links, and RSS `<title>`.
|
- `title` - overrides the page title, post name in index links, and RSS `<title>`.
|
||||||
- `date` - overrides the post date and time. Supports `YYYY-MM-DD` and `YYYY-MM-DD HH:MM` (or `HH-MM`).
|
- `date` - overrides the post date and time. Supports `YYYY-MM-DD` and `YYYY-MM-DD HH:MM` (or `HH-MM`).
|
||||||
- `draft` - if `true`, the file is excluded from HTML generation.
|
- `draft` - if `true`, the file is excluded from HTML generation. If not set, uses the `draft_by_default` config value.
|
||||||
- `description` - page description, used for Open Graph `og:description` meta tag.
|
- `description` - page description, used for Open Graph `og:description` meta tag.
|
||||||
|
- `tags` - comma separated list of tags. Used for tag index generation when `generate_tags` is enabled in `site.conf`.
|
||||||
- `content_warning` - if set, creates an interstitial warning page that the user must click through. If set to `true` uses a generic warning, otherwise uses your string.
|
- `content_warning` - if set, creates an interstitial warning page that the user must click through. If set to `true` uses a generic warning, otherwise uses your string.
|
||||||
|
|||||||
@@ -38,4 +38,83 @@ This renders as `<dl><dt>Term</dt><dd>Definition</dd></dl>`. Multiple definition
|
|||||||
|
|
||||||
## Emoji Shortcodes
|
## Emoji Shortcodes
|
||||||
|
|
||||||
Standard GitHub/MkDocs emoji shortcodes like `:smile:`, `:fire:`, `:rocket:` are automatically replaced with their Unicode emoji equivalents. Shortcodes inside code blocks are left as-is.
|
Standard GitHub/MkDocs emoji shortcodes like `:smile:`, `:fire:`, `:rocket:` are automatically replaced with their Unicode emoji equivalents. Shortcodes inside codeblocks are left as-is.
|
||||||
|
|
||||||
|
## Pipe Tables
|
||||||
|
|
||||||
|
Tables use the GitHub-style syntax:
|
||||||
|
|
||||||
|
```md
|
||||||
|
| Header 1 | Header 2 |
|
||||||
|
|---|---|
|
||||||
|
| cell 1 | cell 2 |
|
||||||
|
| cell 3 | cell 4 |
|
||||||
|
```
|
||||||
|
Column alignment is set with colons in the separator:
|
||||||
|
|
||||||
|
```md
|
||||||
|
| Left | Center | Right |
|
||||||
|
|:---|:---:|---:|
|
||||||
|
| a | b | c |
|
||||||
|
```
|
||||||
|
Tables can drop the header row and with a separator:
|
||||||
|
|
||||||
|
```md
|
||||||
|
|---|---|
|
||||||
|
| a | b |
|
||||||
|
```
|
||||||
|
## Blockquotes
|
||||||
|
|
||||||
|
Standard Markdown blockquote syntax using `>`:
|
||||||
|
|
||||||
|
```md
|
||||||
|
> This is a blockquote.
|
||||||
|
> It can span multiple lines.
|
||||||
|
```
|
||||||
|
### Admonitions
|
||||||
|
|
||||||
|
Blockquotes that start with a type tag become styled admonition blocks. Five built-in types are supported: `NOTE`, `TIP`, `IMPORTANT`, `WARNING`, `CAUTION`.
|
||||||
|
|
||||||
|
```md
|
||||||
|
> [!NOTE]
|
||||||
|
> This is a note admonition.
|
||||||
|
```
|
||||||
|
Custom admonition types can be added via the `custom_admonitions` config option in `site.conf`.
|
||||||
|
|
||||||
|
## Task Lists
|
||||||
|
|
||||||
|
GFM-style task lists are supported inside **both** ordered and unordered lists:
|
||||||
|
|
||||||
|
```md
|
||||||
|
- [ ] Unchecked item
|
||||||
|
- [x] Checked item
|
||||||
|
- Normal item
|
||||||
|
|
||||||
|
1. [ ] Unchecked item
|
||||||
|
2. [x] Checked item
|
||||||
|
3. Normal item
|
||||||
|
```
|
||||||
|
## Reference Links
|
||||||
|
|
||||||
|
Markdown reference-style links and images are supported:
|
||||||
|
|
||||||
|
```md
|
||||||
|
[link text][ref]
|
||||||
|
|
||||||
|
[ref]: https://example.com "Optional title"
|
||||||
|
|
||||||
|
![alt text][img-ref]
|
||||||
|
|
||||||
|
[img-ref]: /image.png "Optional title"
|
||||||
|
```
|
||||||
|
## Plain Text Blocks
|
||||||
|
|
||||||
|
Content inside `<plain>...</plain>` tags is rendered without any Markdown processing
|
||||||
|
|
||||||
|
## MFM Font Syntax
|
||||||
|
|
||||||
|
Misskey-style font syntax is supported for inline font family changes:
|
||||||
|
|
||||||
|
- `$[font.serif text]` - serif font
|
||||||
|
- `$[font.mono text]` - monospace font
|
||||||
|
- `$[font.sans text]` - sans-serif font
|
||||||
|
|||||||
32
site/docs/quickstart.md
Normal file
32
site/docs/quickstart.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
title = "Quickstart"
|
||||||
|
---
|
||||||
|
# Quickstart
|
||||||
|
|
||||||
|
## Creating a site
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kewt --new mysite
|
||||||
|
cd mysite
|
||||||
|
```
|
||||||
|
This creates a directory with a `site.conf`, `template.html`, and `index.md`.
|
||||||
|
|
||||||
|
## Writing content
|
||||||
|
|
||||||
|
Edit `index.md` (or any `.md` file) and just write markdown as usual. Files in subdirectories are added to the navigation automatically.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kewt src out # Replace with the directories you want
|
||||||
|
```
|
||||||
|
Reads from `src` and writes static HTML to `out`.
|
||||||
|
|
||||||
|
## Previewing
|
||||||
|
|
||||||
|
```sh
|
||||||
|
kewt --serve
|
||||||
|
```
|
||||||
|
Builds the site and starts a local HTTP server. Use `--watch` with `--serve` to rebuild automatically on file changes.
|
||||||
|
|
||||||
|
## That's it, if you want to do anything more, look at [the documentation](/docs)
|
||||||
@@ -13,3 +13,10 @@ When customizing `template.html`, the placeholders available are:
|
|||||||
- `{{LANG}}` - the configured document language
|
- `{{LANG}}` - the configured document language
|
||||||
- `{{HEAD_EXTRA}}` - meta-tags
|
- `{{HEAD_EXTRA}}` - meta-tags
|
||||||
- `{{HEADER_BRAND}}` - header rendering the name and/or logo
|
- `{{HEADER_BRAND}}` - header rendering the name and/or logo
|
||||||
|
- `{{HEADER_SEARCH}}` - header search form when `search_in_header = true`
|
||||||
|
|
||||||
|
## Search
|
||||||
|
|
||||||
|
When `generate_search` is enabled, kewt embeds a search bar into pages based on the `search_in_header` and `search_in_footer` config options. The search uses a `search.json` index generated at build time and a client-side JS script. No external dependencies are required.
|
||||||
|
|
||||||
|
If you use a custom template and want header search enabled, make sure your `template.html` includes `{{HEADER_SEARCH}}` somewhere inside `<header>`.
|
||||||
|
|||||||
62
site/docs/theming.md
Normal file
62
site/docs/theming.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
---
|
||||||
|
title = "Theming"
|
||||||
|
---
|
||||||
|
# Theming
|
||||||
|
|
||||||
|
*kewt* has a few colour palettes built-in. Set the `style` option in `site.conf` to a theme name to apply it.
|
||||||
|
|
||||||
|
## Built-in Themes
|
||||||
|
|
||||||
|
| Theme | `style` value | Dark/Light |
|
||||||
|
|---|---|---|
|
||||||
|
| Kewt (default) | `kewt` | Light |
|
||||||
|
| Kewt Light | `kewt-light` | Light |
|
||||||
|
| Nord | `nord` | Dark |
|
||||||
|
| Nord Light | `nord-light` | Light |
|
||||||
|
| Monokai | `monokai` | Dark |
|
||||||
|
| Monokai Light | `monokai-light` | Light |
|
||||||
|
| Grayscale | `grayscale` | Dark |
|
||||||
|
| Grayscale Light | `grayscale-light` | Light |
|
||||||
|
| One Dark | `onedark` | Dark |
|
||||||
|
| One Light | `onelight` | Light |
|
||||||
|
| Rose Pine | `rosepine` | Dark |
|
||||||
|
| Rose Pine Light | `rosepine-light` | Light |
|
||||||
|
| Solarized | `solarized` | Light |
|
||||||
|
| Solarized Dark | `solarized-dark` | Dark |
|
||||||
|
|
||||||
|
```conf
|
||||||
|
style = "kewt-light"
|
||||||
|
```
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
Each theme is a `.root.css` file containing a `:root` block with CSS custom properties. At build time, *kewt* merges the theme's variables with the base `kewt.css` stylesheet. The base `:root` block is stripped out and replaced with the theme's variables.
|
||||||
|
|
||||||
|
## Style Resolution
|
||||||
|
|
||||||
|
*kewt* resolves styles in this priority order (highest wins):
|
||||||
|
|
||||||
|
1. `site/styles.css` - a full custom stylesheet in your site directory. Overrides everything.
|
||||||
|
2. `site/styles.root.css` - custom `:root` variables merged with the built-in `kewt.css` base.
|
||||||
|
3. built-in `<style>.css` - a full stylesheet matching the `style` config value.
|
||||||
|
4. built-in `<style>.root.css` - `:root` variables merged with `kewt.css`.
|
||||||
|
|
||||||
|
If none of these exist, the unmodified `kewt.css` is used
|
||||||
|
|
||||||
|
## Custom Themes
|
||||||
|
|
||||||
|
To create a custom colour theme, place a `styles.root.css` file in your site directory. The file should contain only a `:root` block with the CSS variables you want to override:
|
||||||
|
|
||||||
|
```css
|
||||||
|
:root {
|
||||||
|
--bg: #1a1b26;
|
||||||
|
--fg: #c0caf5;
|
||||||
|
--fg-link: #7aa2f7;
|
||||||
|
--fg-heading: #c0caf5;
|
||||||
|
--code-bg: #24283b;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Any variables not overridden will fall back to the defaults in `kewt.css`. The `:root` block in the base stylesheet is automatically removed to prevent conflicts.
|
||||||
|
|
||||||
|
## Per-Directory Styles
|
||||||
|
|
||||||
|
Subdirectories can have their own `styles.css` or `styles.root.css` that apply only to pages in that directory. Per-directory styles follow the same priority.
|
||||||
@@ -20,4 +20,6 @@ kewt --serve [port]
|
|||||||
- `--generate-template [path]` writes the default `template.html` to the given path (defaults to `template.html` in the current directory).
|
- `--generate-template [path]` writes the default `template.html` to the given path (defaults to `template.html` in the current directory).
|
||||||
- `--update [dir]` adds any missing keys to `site.conf` and checks `template.html` against the latest default.
|
- `--update [dir]` adds any missing keys to `site.conf` and checks `template.html` against the latest default.
|
||||||
- `--watch` (`-w`) watches for file changes in the source directory and rebuilds automatically.
|
- `--watch` (`-w`) watches for file changes in the source directory and rebuilds automatically.
|
||||||
- `--serve` (`-s`) starts a local HTTP server (python3 or busybox) in the output directory after building. Use with the port number to specify the port. Composable with `--watch`.
|
- `--clean` cleans the output directory before building (default behavior).
|
||||||
|
- `--no-clean` does not clean the output directory before building. Useful with `--watch` to avoid clearing output on every rebuild.
|
||||||
|
- `--serve` (`-s`) starts a local HTTP server (python3 or busybox) in the output directory after building. Use with the port number to specify the port. The default port is `8000`. Composable with `--watch`.
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
---
|
---
|
||||||
title = "Heaven"
|
title = "Heaven"
|
||||||
content_warning = "This page may contain CSS"
|
content_warning = "This page may have bad effects on people with an allergy to cats"
|
||||||
---
|
---
|
||||||
# Heaven
|
# Heaven
|
||||||
|
|
||||||
Told you
|
Told you
|
||||||
|
|
||||||
Probably should've mentioned the catgirl too
|
![catgirl.jpg]
|
||||||
|
|
||||||
| --- | --- |
|
|
||||||
| ```![/styles.css]``` | <img style="vertical-align: top;" src="catgirl.jpg"> |
|
|
||||||
|
|||||||
@@ -41,5 +41,4 @@ It's meant to be a static site generator, like _[kew](https://github.com/uint23/
|
|||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
> [!WARNING]
|
## [Quickstart guide](/docs/quickstart.html)
|
||||||
> The base that all of this is built upon was coded at night, while sleepy and a bit sick, and after walking for about 4 hours around a forest, so...
|
|
||||||
|
|||||||
@@ -22,4 +22,9 @@ base_url = "https://kewt.krzak.org"
|
|||||||
custom_admonitions = ""
|
custom_admonitions = ""
|
||||||
generate_feed = false
|
generate_feed = false
|
||||||
feed_file = "rss.xml"
|
feed_file = "rss.xml"
|
||||||
posts_dir = ""
|
posts_dir = ""
|
||||||
|
generate_tags = false
|
||||||
|
generate_search = true
|
||||||
|
search_in_footer = true
|
||||||
|
search_in_header = true
|
||||||
|
include_cw_pages_in_search = false
|
||||||
|
|||||||
27
styles/grayscale-light.root.css
Normal file
27
styles/grayscale-light.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #f5f5f5;
|
||||||
|
--bg-deep: #e8e8e8;
|
||||||
|
--fg: #1a1a1a;
|
||||||
|
--fg-muted: #808080;
|
||||||
|
--fg-link: #333333;
|
||||||
|
--fg-heading: #000000;
|
||||||
|
--code-bg: #e8e8e8;
|
||||||
|
--code-border: #c0c0c0;
|
||||||
|
--code-fg: #1a1a1a;
|
||||||
|
--code-sel: #555555;
|
||||||
|
--code-prop: #333333;
|
||||||
|
--code-val: #666666;
|
||||||
|
--code-var: #444444;
|
||||||
|
--code-com: #999999;
|
||||||
|
--adm-note-bg: #e0e0ee;
|
||||||
|
--adm-note-border: #8888aa;
|
||||||
|
--adm-tip-bg: #e0eee0;
|
||||||
|
--adm-tip-border: #88aa88;
|
||||||
|
--adm-important-bg: #eee0ee;
|
||||||
|
--adm-important-border: #aa88aa;
|
||||||
|
--adm-warning-bg: #eeeed0;
|
||||||
|
--adm-warning-border: #aaaa78;
|
||||||
|
--adm-caution-bg: #eee0e0;
|
||||||
|
--adm-caution-border: #aa8888;
|
||||||
|
--thead-bg: #e8e8e8;
|
||||||
|
}
|
||||||
27
styles/grayscale.root.css
Normal file
27
styles/grayscale.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #1a1a1a;
|
||||||
|
--bg-deep: #111111;
|
||||||
|
--fg: #d4d4d4;
|
||||||
|
--fg-muted: #808080;
|
||||||
|
--fg-link: #e0e0e0;
|
||||||
|
--fg-heading: #ffffff;
|
||||||
|
--code-bg: #0d0d0d;
|
||||||
|
--code-border: #404040;
|
||||||
|
--code-fg: #d4d4d4;
|
||||||
|
--code-sel: #b8b8b8;
|
||||||
|
--code-prop: #e0e0e0;
|
||||||
|
--code-val: #a0a0a0;
|
||||||
|
--code-var: #c8c8c8;
|
||||||
|
--code-com: #585858;
|
||||||
|
--adm-note-bg: #1a1a2e;
|
||||||
|
--adm-note-border: #5a5a8a;
|
||||||
|
--adm-tip-bg: #1a2e1a;
|
||||||
|
--adm-tip-border: #5a8a5a;
|
||||||
|
--adm-important-bg: #2e1a2e;
|
||||||
|
--adm-important-border: #8a5a8a;
|
||||||
|
--adm-warning-bg: #2e2e1a;
|
||||||
|
--adm-warning-border: #8a8a5a;
|
||||||
|
--adm-caution-bg: #2e1a1a;
|
||||||
|
--adm-caution-border: #8a5a5a;
|
||||||
|
--thead-bg: #111111;
|
||||||
|
}
|
||||||
27
styles/kewt-light.root.css
Normal file
27
styles/kewt-light.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #f5f0ff;
|
||||||
|
--bg-deep: #e8dffa;
|
||||||
|
--fg: #2d1b4e;
|
||||||
|
--fg-muted: #7a6898;
|
||||||
|
--fg-link: #7b3fba;
|
||||||
|
--fg-heading: #3d2466;
|
||||||
|
--code-bg: #e8dffa;
|
||||||
|
--code-border: #d0c0e8;
|
||||||
|
--code-fg: #2d1b4e;
|
||||||
|
--code-sel: #b8860b;
|
||||||
|
--code-prop: #6f42c1;
|
||||||
|
--code-val: #0366d6;
|
||||||
|
--code-var: #22863a;
|
||||||
|
--code-com: #7a6898;
|
||||||
|
--adm-note-bg: #e0e0f8;
|
||||||
|
--adm-note-border: #5b6fc4;
|
||||||
|
--adm-tip-bg: #ddf0dd;
|
||||||
|
--adm-tip-border: #46a758;
|
||||||
|
--adm-important-bg: #eeddf5;
|
||||||
|
--adm-important-border: #8b5fc7;
|
||||||
|
--adm-warning-bg: #f5f0dd;
|
||||||
|
--adm-warning-border: #b8860b;
|
||||||
|
--adm-caution-bg: #f5dddd;
|
||||||
|
--adm-caution-border: #c44569;
|
||||||
|
--thead-bg: #e8dffa;
|
||||||
|
}
|
||||||
307
styles/kewt.css
307
styles/kewt.css
@@ -23,6 +23,7 @@
|
|||||||
--adm-warning-border: #ffe2bd;
|
--adm-warning-border: #ffe2bd;
|
||||||
--adm-caution-bg: #662d43;
|
--adm-caution-bg: #662d43;
|
||||||
--adm-caution-border: #ffc4d5;
|
--adm-caution-border: #ffc4d5;
|
||||||
|
--thead-bg: #3d2d5c;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -36,6 +37,11 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
flex-wrap: wrap;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
border-bottom: 1px solid var(--code-border);
|
border-bottom: 1px solid var(--code-border);
|
||||||
@@ -44,10 +50,15 @@ header {
|
|||||||
|
|
||||||
header h1 {
|
header h1 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
font-size: 35px;
|
font-size: 35px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
color: var(--fg-heading);
|
color: var(--fg-heading);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-logo {
|
.site-logo {
|
||||||
@@ -110,6 +121,12 @@ a {
|
|||||||
margin-left: -10px;
|
margin-left: -10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#side-bar a.current-page:hover,
|
||||||
|
#side-bar a.current-page:focus {
|
||||||
|
color: var(--fg);
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
background: var(--fg);
|
background: var(--fg);
|
||||||
color: var(--bg);
|
color: var(--bg);
|
||||||
@@ -127,6 +144,53 @@ h3 {
|
|||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header-link {
|
||||||
|
color: var(--fg);
|
||||||
|
display: inline;
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-color: var(--fg-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-link:hover,
|
||||||
|
.header-link:focus {
|
||||||
|
background: var(--fg);
|
||||||
|
color: var(--bg);
|
||||||
|
text-decoration-color: var(--fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-anchor {
|
||||||
|
opacity: 0;
|
||||||
|
margin-left: 0.25em;
|
||||||
|
transition: opacity 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1:hover > .header-anchor,
|
||||||
|
h2:hover > .header-anchor,
|
||||||
|
h3:hover > .header-anchor,
|
||||||
|
h4:hover > .header-anchor,
|
||||||
|
h5:hover > .header-anchor,
|
||||||
|
h6:hover > .header-anchor,
|
||||||
|
h1:focus-within > .header-anchor,
|
||||||
|
h2:focus-within > .header-anchor,
|
||||||
|
h3:focus-within > .header-anchor,
|
||||||
|
h4:focus-within > .header-anchor,
|
||||||
|
h5:focus-within > .header-anchor,
|
||||||
|
h6:focus-within > .header-anchor,
|
||||||
|
h1:hover .header-link .header-anchor,
|
||||||
|
h2:hover .header-link .header-anchor,
|
||||||
|
h3:hover .header-link .header-anchor,
|
||||||
|
h4:hover .header-link .header-anchor,
|
||||||
|
h5:hover .header-link .header-anchor,
|
||||||
|
h6:hover .header-link .header-anchor,
|
||||||
|
h1:focus-within .header-link .header-anchor,
|
||||||
|
h2:focus-within .header-link .header-anchor,
|
||||||
|
h3:focus-within .header-link .header-anchor,
|
||||||
|
h4:focus-within .header-link .header-anchor,
|
||||||
|
h5:focus-within .header-link .header-anchor,
|
||||||
|
h6:focus-within .header-link .header-anchor {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background: var(--code-bg);
|
background: var(--code-bg);
|
||||||
color: var(--code-fg);
|
color: var(--code-fg);
|
||||||
@@ -218,6 +282,7 @@ pre code {
|
|||||||
background: var(--adm-caution-bg);
|
background: var(--adm-caution-bg);
|
||||||
border-color: var(--adm-caution-border);
|
border-color: var(--adm-caution-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cw-button {
|
.cw-button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
@@ -267,6 +332,32 @@ hr {
|
|||||||
border-top: 1px solid var(--code-border);
|
border-top: 1px solid var(--code-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 20px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
border-bottom: 2px solid var(--code-border);
|
||||||
|
background: var(--thead-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: left;
|
||||||
|
padding: 8px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-top: 1px solid var(--code-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background: var(--bg-deep);
|
||||||
|
}
|
||||||
|
|
||||||
.nav-toggle,
|
.nav-toggle,
|
||||||
.nav-toggle-label {
|
.nav-toggle-label {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -299,7 +390,7 @@ hr {
|
|||||||
margin: 0 20px 20px 20px;
|
margin: 0 20px 20px 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-toggle:checked~#side-bar {
|
.nav-toggle:checked ~ #side-bar {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,4 +412,216 @@ hr {
|
|||||||
.task-list-item-checkbox {
|
.task-list-item-checkbox {
|
||||||
margin: 0 0.2em 0.25em -1.6em;
|
margin: 0 0.2em 0.25em -1.6em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.kewt-search-page {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-page input[type="text"] {
|
||||||
|
flex: 1;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: inherit;
|
||||||
|
background: var(--code-bg);
|
||||||
|
color: var(--fg);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
border-radius: 3px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-page input[type="text"]:focus {
|
||||||
|
border-color: var(--fg-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-page button {
|
||||||
|
padding: 8px 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: inherit;
|
||||||
|
background: var(--bg-deep);
|
||||||
|
color: var(--fg);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-page button:hover {
|
||||||
|
background: var(--fg);
|
||||||
|
color: var(--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result {
|
||||||
|
margin: 16px 0;
|
||||||
|
padding: 12px;
|
||||||
|
background: var(--code-bg);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result a {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: var(--fg-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result p {
|
||||||
|
margin: 6px 0 0 0;
|
||||||
|
color: var(--fg-muted);
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer search */
|
||||||
|
.kewt-search-footer {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 4px;
|
||||||
|
margin-left: 12px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-footer input[type="text"] {
|
||||||
|
padding: 3px 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
background: var(--code-bg);
|
||||||
|
color: var(--fg);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
border-radius: 3px;
|
||||||
|
outline: none;
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-footer input[type="text"]:focus {
|
||||||
|
border-color: var(--fg-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-footer button {
|
||||||
|
padding: 3px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
background: var(--bg-deep);
|
||||||
|
color: var(--fg);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-footer button:hover {
|
||||||
|
background: var(--fg);
|
||||||
|
color: var(--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-header {
|
||||||
|
display: inline-flex;
|
||||||
|
gap: 4px;
|
||||||
|
margin-left: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
font-style: normal;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-header input[type="text"] {
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
background: var(--code-bg);
|
||||||
|
color: var(--fg);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
border-radius: 3px;
|
||||||
|
outline: none;
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-header input[type="text"]:focus {
|
||||||
|
border-color: var(--fg-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-header button {
|
||||||
|
padding: 4px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
background: var(--bg-deep);
|
||||||
|
color: var(--fg);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-header button:hover {
|
||||||
|
background: var(--fg);
|
||||||
|
color: var(--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-nav {
|
||||||
|
display: none;
|
||||||
|
padding: 8px 0 12px 0;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
border-bottom: 1px solid var(--code-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-nav form {
|
||||||
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-nav input[type="text"] {
|
||||||
|
flex: 1;
|
||||||
|
padding: 6px 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
background: var(--code-bg);
|
||||||
|
color: var(--fg);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
border-radius: 3px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-nav input[type="text"]:focus {
|
||||||
|
border-color: var(--fg-link);
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-nav button {
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: inherit;
|
||||||
|
background: var(--bg-deep);
|
||||||
|
color: var(--fg);
|
||||||
|
border: 1px solid var(--code-border);
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-nav button:hover {
|
||||||
|
background: var(--fg);
|
||||||
|
color: var(--bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
.kewt-search-header {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-nav {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-page {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-page button {
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-footer {
|
||||||
|
display: flex;
|
||||||
|
margin-left: 0;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kewt-search-footer input[type="text"] {
|
||||||
|
flex: 1;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
27
styles/monokai-light.root.css
Normal file
27
styles/monokai-light.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #fafaf8;
|
||||||
|
--bg-deep: #f0efe8;
|
||||||
|
--fg: #272822;
|
||||||
|
--fg-muted: #8f8e84;
|
||||||
|
--fg-link: #5c8a1e;
|
||||||
|
--fg-heading: #272822;
|
||||||
|
--code-bg: #f0efe8;
|
||||||
|
--code-border: #cccbc2;
|
||||||
|
--code-fg: #272822;
|
||||||
|
--code-sel: #5c8a1e;
|
||||||
|
--code-prop: #c41e6a;
|
||||||
|
--code-val: #7a3ee0;
|
||||||
|
--code-var: #2e8faf;
|
||||||
|
--code-com: #8f8e84;
|
||||||
|
--adm-note-bg: #edf4f7;
|
||||||
|
--adm-note-border: #2e8faf;
|
||||||
|
--adm-tip-bg: #eef7ed;
|
||||||
|
--adm-tip-border: #5c8a1e;
|
||||||
|
--adm-important-bg: #f2eef7;
|
||||||
|
--adm-important-border: #7a3ee0;
|
||||||
|
--adm-warning-bg: #f7f5ed;
|
||||||
|
--adm-warning-border: #b0a01e;
|
||||||
|
--adm-caution-bg: #f7edee;
|
||||||
|
--adm-caution-border: #c41e6a;
|
||||||
|
--thead-bg: #f0efe8;
|
||||||
|
}
|
||||||
27
styles/monokai.root.css
Normal file
27
styles/monokai.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #272822;
|
||||||
|
--bg-deep: #1e1f1c;
|
||||||
|
--fg: #f8f8f2;
|
||||||
|
--fg-muted: #75715e;
|
||||||
|
--fg-link: #a6e22e;
|
||||||
|
--fg-heading: #f8f8f2;
|
||||||
|
--code-bg: #1e1f1c;
|
||||||
|
--code-border: #49483e;
|
||||||
|
--code-fg: #f8f8f2;
|
||||||
|
--code-sel: #a6e22e;
|
||||||
|
--code-prop: #f92672;
|
||||||
|
--code-val: #ae81ff;
|
||||||
|
--code-var: #66d9ef;
|
||||||
|
--code-com: #75715e;
|
||||||
|
--adm-note-bg: #272822;
|
||||||
|
--adm-note-border: #66d9ef;
|
||||||
|
--adm-tip-bg: #272822;
|
||||||
|
--adm-tip-border: #a6e22e;
|
||||||
|
--adm-important-bg: #272822;
|
||||||
|
--adm-important-border: #ae81ff;
|
||||||
|
--adm-warning-bg: #272822;
|
||||||
|
--adm-warning-border: #e6db74;
|
||||||
|
--adm-caution-bg: #272822;
|
||||||
|
--adm-caution-border: #f92672;
|
||||||
|
--thead-bg: #1e1f1c;
|
||||||
|
}
|
||||||
27
styles/nord-light.root.css
Normal file
27
styles/nord-light.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #eceff4;
|
||||||
|
--bg-deep: #d8dee9;
|
||||||
|
--fg: #2e3440;
|
||||||
|
--fg-muted: #4c566a;
|
||||||
|
--fg-link: #5e81ac;
|
||||||
|
--fg-heading: #3b4252;
|
||||||
|
--code-bg: #d8dee9;
|
||||||
|
--code-border: #c5cdd9;
|
||||||
|
--code-fg: #2e3440;
|
||||||
|
--code-sel: #d08770;
|
||||||
|
--code-prop: #5e81ac;
|
||||||
|
--code-val: #8fbcbb;
|
||||||
|
--code-var: #a3be8c;
|
||||||
|
--code-com: #4c566a;
|
||||||
|
--adm-note-bg: #d8dee9;
|
||||||
|
--adm-note-border: #5e81ac;
|
||||||
|
--adm-tip-bg: #e0ebd8;
|
||||||
|
--adm-tip-border: #a3be8c;
|
||||||
|
--adm-important-bg: #e5dbe8;
|
||||||
|
--adm-important-border: #b48ead;
|
||||||
|
--adm-warning-bg: #ede5d6;
|
||||||
|
--adm-warning-border: #ebcb8b;
|
||||||
|
--adm-caution-bg: #eddcdc;
|
||||||
|
--adm-caution-border: #bf616a;
|
||||||
|
--thead-bg: #d8dee9;
|
||||||
|
}
|
||||||
27
styles/nord.root.css
Normal file
27
styles/nord.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #2e3440;
|
||||||
|
--bg-deep: #242933;
|
||||||
|
--fg: #d8dee9;
|
||||||
|
--fg-muted: #a5b0c1;
|
||||||
|
--fg-link: #88c0d0;
|
||||||
|
--fg-heading: #eceff4;
|
||||||
|
--code-bg: #3b4252;
|
||||||
|
--code-border: #4c566a;
|
||||||
|
--code-fg: #d8dee9;
|
||||||
|
--code-sel: #ebcb8b;
|
||||||
|
--code-prop: #8fbcbb;
|
||||||
|
--code-val: #81a1c1;
|
||||||
|
--code-var: #a3be8c;
|
||||||
|
--code-com: #616e88;
|
||||||
|
--adm-note-bg: #3b4252;
|
||||||
|
--adm-note-border: #88c0d0;
|
||||||
|
--adm-tip-bg: #3b4340;
|
||||||
|
--adm-tip-border: #a3be8c;
|
||||||
|
--adm-important-bg: #3b4044;
|
||||||
|
--adm-important-border: #b48ead;
|
||||||
|
--adm-warning-bg: #3b4038;
|
||||||
|
--adm-warning-border: #ebcb8b;
|
||||||
|
--adm-caution-bg: #3b3840;
|
||||||
|
--adm-caution-border: #bf616a;
|
||||||
|
--thead-bg: #3b4252;
|
||||||
|
}
|
||||||
27
styles/onedark.root.css
Normal file
27
styles/onedark.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #282c34;
|
||||||
|
--bg-deep: #21252b;
|
||||||
|
--fg: #abb2bf;
|
||||||
|
--fg-muted: #636d83;
|
||||||
|
--fg-link: #61afef;
|
||||||
|
--fg-heading: #c8ccd4;
|
||||||
|
--code-bg: #21252b;
|
||||||
|
--code-border: #3e4451;
|
||||||
|
--code-fg: #abb2bf;
|
||||||
|
--code-sel: #e5c07b;
|
||||||
|
--code-prop: #e06c75;
|
||||||
|
--code-val: #56b6c2;
|
||||||
|
--code-var: #98c379;
|
||||||
|
--code-com: #5c6370;
|
||||||
|
--adm-note-bg: #2c313c;
|
||||||
|
--adm-note-border: #61afef;
|
||||||
|
--adm-tip-bg: #2c3a30;
|
||||||
|
--adm-tip-border: #98c379;
|
||||||
|
--adm-important-bg: #33303c;
|
||||||
|
--adm-important-border: #c678dd;
|
||||||
|
--adm-warning-bg: #3a352c;
|
||||||
|
--adm-warning-border: #e5c07b;
|
||||||
|
--adm-caution-bg: #3a2c2e;
|
||||||
|
--adm-caution-border: #e06c75;
|
||||||
|
--thead-bg: #21252b;
|
||||||
|
}
|
||||||
27
styles/onelight.root.css
Normal file
27
styles/onelight.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #fafafa;
|
||||||
|
--bg-deep: #eaeaeb;
|
||||||
|
--fg: #383a42;
|
||||||
|
--fg-muted: #a0a1a7;
|
||||||
|
--fg-link: #4078f2;
|
||||||
|
--fg-heading: #383a42;
|
||||||
|
--code-bg: #eaeaeb;
|
||||||
|
--code-border: #d4d4d5;
|
||||||
|
--code-fg: #383a42;
|
||||||
|
--code-sel: #986801;
|
||||||
|
--code-prop: #e45649;
|
||||||
|
--code-val: #0184bc;
|
||||||
|
--code-var: #50a14f;
|
||||||
|
--code-com: #a0a1a7;
|
||||||
|
--adm-note-bg: #e8eefa;
|
||||||
|
--adm-note-border: #4078f2;
|
||||||
|
--adm-tip-bg: #e8f5e8;
|
||||||
|
--adm-tip-border: #50a14f;
|
||||||
|
--adm-important-bg: #f2e8f5;
|
||||||
|
--adm-important-border: #a626a4;
|
||||||
|
--adm-warning-bg: #f5f0e0;
|
||||||
|
--adm-warning-border: #986801;
|
||||||
|
--adm-caution-bg: #fae8e8;
|
||||||
|
--adm-caution-border: #e45649;
|
||||||
|
--thead-bg: #eaeaeb;
|
||||||
|
}
|
||||||
27
styles/rosepine-light.root.css
Normal file
27
styles/rosepine-light.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #faf4ed;
|
||||||
|
--bg-deep: #f2e9e1;
|
||||||
|
--fg: #575279;
|
||||||
|
--fg-muted: #9893a5;
|
||||||
|
--fg-link: #907aa9;
|
||||||
|
--fg-heading: #286983;
|
||||||
|
--code-bg: #f2e9e1;
|
||||||
|
--code-border: #dfdad9;
|
||||||
|
--code-fg: #575279;
|
||||||
|
--code-sel: #ea9d34;
|
||||||
|
--code-prop: #b4637a;
|
||||||
|
--code-val: #56949f;
|
||||||
|
--code-var: #286983;
|
||||||
|
--code-com: #9893a5;
|
||||||
|
--adm-note-bg: #f0e8f5;
|
||||||
|
--adm-note-border: #907aa9;
|
||||||
|
--adm-tip-bg: #e8f0ee;
|
||||||
|
--adm-tip-border: #56949f;
|
||||||
|
--adm-important-bg: #f0e8f0;
|
||||||
|
--adm-important-border: #907aa9;
|
||||||
|
--adm-warning-bg: #f5f0e0;
|
||||||
|
--adm-warning-border: #ea9d34;
|
||||||
|
--adm-caution-bg: #f5e5e8;
|
||||||
|
--adm-caution-border: #b4637a;
|
||||||
|
--thead-bg: #f2e9e1;
|
||||||
|
}
|
||||||
27
styles/rosepine.root.css
Normal file
27
styles/rosepine.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #191724;
|
||||||
|
--bg-deep: #13111e;
|
||||||
|
--fg: #e0def4;
|
||||||
|
--fg-muted: #908caa;
|
||||||
|
--fg-link: #c4a7e7;
|
||||||
|
--fg-heading: #ebbcba;
|
||||||
|
--code-bg: #1f1d2e;
|
||||||
|
--code-border: #26233a;
|
||||||
|
--code-fg: #e0def4;
|
||||||
|
--code-sel: #f6c177;
|
||||||
|
--code-prop: #eb6f92;
|
||||||
|
--code-val: #9ccfd8;
|
||||||
|
--code-var: #31748f;
|
||||||
|
--code-com: #6e6a86;
|
||||||
|
--adm-note-bg: #1f1d2e;
|
||||||
|
--adm-note-border: #c4a7e7;
|
||||||
|
--adm-tip-bg: #1a2332;
|
||||||
|
--adm-tip-border: #9ccfd8;
|
||||||
|
--adm-important-bg: #2a1f2e;
|
||||||
|
--adm-important-border: #c4a7e7;
|
||||||
|
--adm-warning-bg: #2a251f;
|
||||||
|
--adm-warning-border: #f6c177;
|
||||||
|
--adm-caution-bg: #2a1f22;
|
||||||
|
--adm-caution-border: #eb6f92;
|
||||||
|
--thead-bg: #1f1d2e;
|
||||||
|
}
|
||||||
27
styles/solarized-dark.root.css
Normal file
27
styles/solarized-dark.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #002b36;
|
||||||
|
--bg-deep: #001e26;
|
||||||
|
--fg: #839496;
|
||||||
|
--fg-muted: #586e75;
|
||||||
|
--fg-link: #268bd2;
|
||||||
|
--fg-heading: #93a1a1;
|
||||||
|
--code-bg: #073642;
|
||||||
|
--code-border: #094959;
|
||||||
|
--code-fg: #839496;
|
||||||
|
--code-sel: #d33682;
|
||||||
|
--code-prop: #268bd2;
|
||||||
|
--code-val: #2aa198;
|
||||||
|
--code-var: #859900;
|
||||||
|
--code-com: #586e75;
|
||||||
|
--adm-note-bg: #073642;
|
||||||
|
--adm-note-border: #268bd2;
|
||||||
|
--adm-tip-bg: #07382e;
|
||||||
|
--adm-tip-border: #2aa198;
|
||||||
|
--adm-important-bg: #2a0736;
|
||||||
|
--adm-important-border: #d33682;
|
||||||
|
--adm-warning-bg: #363007;
|
||||||
|
--adm-warning-border: #b58900;
|
||||||
|
--adm-caution-bg: #360a07;
|
||||||
|
--adm-caution-border: #cb4b16;
|
||||||
|
--thead-bg: #073642;
|
||||||
|
}
|
||||||
27
styles/solarized.root.css
Normal file
27
styles/solarized.root.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
:root {
|
||||||
|
--bg: #fdf6e3;
|
||||||
|
--bg-deep: #eee8d5;
|
||||||
|
--fg: #657b83;
|
||||||
|
--fg-muted: #93a1a1;
|
||||||
|
--fg-link: #268bd2;
|
||||||
|
--fg-heading: #586e75;
|
||||||
|
--code-bg: #eee8d5;
|
||||||
|
--code-border: #d3cbb7;
|
||||||
|
--code-fg: #657b83;
|
||||||
|
--code-sel: #d33682;
|
||||||
|
--code-prop: #268bd2;
|
||||||
|
--code-val: #2aa198;
|
||||||
|
--code-var: #859900;
|
||||||
|
--code-com: #93a1a1;
|
||||||
|
--adm-note-bg: #eee8d5;
|
||||||
|
--adm-note-border: #268bd2;
|
||||||
|
--adm-tip-bg: #e8f5e0;
|
||||||
|
--adm-tip-border: #859900;
|
||||||
|
--adm-important-bg: #f0e8f5;
|
||||||
|
--adm-important-border: #6c71c4;
|
||||||
|
--adm-warning-bg: #fdf0e3;
|
||||||
|
--adm-warning-border: #b58900;
|
||||||
|
--adm-caution-bg: #fde8e8;
|
||||||
|
--adm-caution-border: #dc322f;
|
||||||
|
--thead-bg: #eee8d5;
|
||||||
|
}
|
||||||
@@ -28,10 +28,10 @@ EOF
|
|||||||
|
|
||||||
VERSION=$(git describe --tags 2>/dev/null || echo "standalone")
|
VERSION=$(git describe --tags 2>/dev/null || echo "standalone")
|
||||||
tmpbuild=$(mktemp -d)
|
tmpbuild=$(mktemp -d)
|
||||||
cp -r "$REPO_ROOT/kewt.sh" "$REPO_ROOT/markdown.sh" "$REPO_ROOT/awk" "$REPO_ROOT/styles" "$tmpbuild/"
|
cp -r "$REPO_ROOT/kewt.sh" "$REPO_ROOT/markdown.sh" "$REPO_ROOT/awk" "$REPO_ROOT/styles" "$REPO_ROOT/lib" "$tmpbuild/"
|
||||||
sed -e "s/kewt version git/kewt version $VERSION/" "$tmpbuild/kewt.sh" > "$tmpbuild/kewt.sh.tmp" && mv "$tmpbuild/kewt.sh.tmp" "$tmpbuild/kewt.sh"
|
sed -e "s/kewt version git/kewt version $VERSION/" "$tmpbuild/kewt.sh" > "$tmpbuild/kewt.sh.tmp" && mv "$tmpbuild/kewt.sh.tmp" "$tmpbuild/kewt.sh"
|
||||||
chmod +x "$tmpbuild/kewt.sh" "$tmpbuild/markdown.sh"
|
chmod +x "$tmpbuild/kewt.sh" "$tmpbuild/markdown.sh"
|
||||||
tar -cz -C "$tmpbuild" kewt.sh markdown.sh awk styles >> "$OUT_FILE"
|
tar -cz -C "$tmpbuild" kewt.sh markdown.sh awk styles lib >> "$OUT_FILE"
|
||||||
rm -rf "$tmpbuild"
|
rm -rf "$tmpbuild"
|
||||||
|
|
||||||
chmod +x "$OUT_FILE"
|
chmod +x "$OUT_FILE"
|
||||||
|
|||||||
Reference in New Issue
Block a user