From f5bb0cadd4ef749c2809dfc02965347cd8161665 Mon Sep 17 00:00:00 2001 From: pifty Date: Sat, 11 Jul 2020 02:47:12 +0000 Subject: [PATCH] initial commit --- FORKING | 4 + INSTALL | 30 + LICENSE | 11 + README | 207 +++++ bin/GOALS | 16 + bin/vee | 919 ++++++++++++++++++++++ bin/vee-publish | 56 ++ bin/vee-rebuild | 126 +++ bin/veecat | 119 +++ bin/veefind | 96 +++ bin/veels | 87 ++ custom-formatters/README | 6 + custom-formatters/vee-custom-3rd-party.sh | 51 ++ custom-formatters/vee-custom-utf8.sh | 75 ++ dot.veerc | 41 + patches/applied-11.11.2007.patch | 30 + sample-hooks/vee-hook.pl | 22 + sample-hooks/vee-hook.sh | 11 + sample-hooks/vee-hookmanager.pl | 34 + 19 files changed, 1941 insertions(+) create mode 100644 FORKING create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 README create mode 100644 bin/GOALS create mode 100755 bin/vee create mode 100755 bin/vee-publish create mode 100755 bin/vee-rebuild create mode 100755 bin/veecat create mode 100755 bin/veefind create mode 100755 bin/veels create mode 100644 custom-formatters/README create mode 100644 custom-formatters/vee-custom-3rd-party.sh create mode 100644 custom-formatters/vee-custom-utf8.sh create mode 100644 dot.veerc create mode 100644 patches/applied-11.11.2007.patch create mode 100755 sample-hooks/vee-hook.pl create mode 100755 sample-hooks/vee-hook.sh create mode 100755 sample-hooks/vee-hookmanager.pl diff --git a/FORKING b/FORKING new file mode 100644 index 0000000..160c130 --- /dev/null +++ b/FORKING @@ -0,0 +1,4 @@ +I am more than fine with anyone wishing to fork vee with the intention of creating +a new tool that may never be incorporated back into vee. + +Enjoy! diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..3648d25 --- /dev/null +++ b/INSTALL @@ -0,0 +1,30 @@ +HA!! You basically have to do nothing. Check it out. + +Just drop bin/vee somewhere, make sure it is in your path, and you are set to +go! + +When vee is run for the first time, it will create the necessary files and +directory that it needs. Note, this is done relative to `pwd` unless you use the +'-d' option to specify a directory. + +Example first time: + +% vee -d /path/to/my/www/myblog -t "first post.." + +Autogenerated files and directories: + +1) ./.vee :: stores all entries in here +2) ./vee.html :: entry index; the name +can be controlled with "-i custom.html" or "-I" which is equivalent to "-i +index.html" + +Manually created files vee looks for: + +1) ./.veerc :: custom config file +2) vee-top.tpl and vee-bottom.tpl :: template files; other can be specifed +with "-T" and "-B" + +Environmental variables vee looks at: + +1) "EDITOR" :: determines default editor; If not set, it will default to "vi" as +seen via PATH diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7ac3633 --- /dev/null +++ b/LICENSE @@ -0,0 +1,11 @@ +DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +Version 2, December 2004 + +Copyright (C) 2004 Sam Hocevar + +Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. + +DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/README b/README new file mode 100644 index 0000000..a283c0e --- /dev/null +++ b/README @@ -0,0 +1,207 @@ +vee is a highly portable, zero configuration (but configurable), cli +microblogging tool that I created because I hated having to set up +web-based blogging software every so often. It became popular for some +reason, and now it's used in some for by many people - mostly in silence. +It does everything I want it to do, hence the lack of feature creep; +however I am always interested in improving it in some basic way. + +It's available in a variety of package repositories, like pkgsrc and +FreeBSD Ports. + +vee is one of hundreds of "static site generators", many of which are +listed at https://staticsitegenerators.net. + +Version: + +2.0-rc1 +License: + +vee is released under the WTFPL. See the LICENSE file for more information. + +Portability Goals: + +0. no external dependencies other than Bourne Shell and traditional + Unix userland tools (no need to install non-optional utils) +1. any *nix platform that supports Bourne Shell (sh) +2. it "just works" out of the box +3. new versions won't require "upgrading" + +Incompatibilities: + +The goal of vee is that it should work on minimal systems using only +original Bourne shell (sh) and without having to install anything. I +originally began this work on FreeBSD, but it seems that a couple of +utilities seem to not be the most portable in their usage. In particular, +`date` and `sort` have caused some headaches, but alas they have been +tamed. + +Project Status: + +This is one of those "forever" projects that met my needs very early +on, and I have revisited the code for only incremental improvements. +A flurry of current activity has been spurred by the 'rona "stay at +home" orders and a feature request to support Gopher "phlogs". Current +work onthat is moving us towards version 2.0. + +Bug reports and Feature Requests: + + https://git.sdf.org/pifty/vee/issues + + Note: HTML support will only prioritize bug reports. Feature requests + related to Gopher support will receive the most interest. + +Via `vee -h`: + + .----------------. .----------------. .----------------. + | .--------------. || .--------------. || .--------------. | + | | ____ ____ | || | _________ | || | _________ | | + | ||_ _| |_ _| | || | |_ ___ | | || | |_ ___ | | | + | | \ \ / / | || | | |_ \_| | || | | |_ \_| | | + | | \ \ / / | || | | _| _ | || | | _| _ | | + | | \ ' / | || | _| |___/ | | || | _| |___/ | | | + | | \_/ | || | |_________| | || | |_________| | | + | | | || | | || | | | + | '--------------' || '--------------' || '--------------' | + '----------------' '----------------' '----------------' + the Zero-conf, commandline blog tool thingy + .... now with GopherMode! (gopherlog support) + (see -g|-G) + +Version: 2.0-rc1 + +Options: + -b Batch mode; used when piping in msg via stdin + -B file Define bottom template; default is ./vee-bottom.tpl + -c [1-9\d*] Specify the number of characters 'fold' allows per line + this only applies when 'fold' (-f) is used + -d 'publis_dir' Specify the directory .vee is in - defaults to PWD + -D Debug mode with, set -x + -f 'format' Option for setting formatinstead of the default, groff; + 'groff', 'fmt', 'fold', and 'none' are all supported + -g Update the gophermap file with the INDEX + -G Exclusively update the gophermap file rather than INDEX + Note: for -g|-G, the gophermap is merely appended to, there + is no maintaining of the order from newest first to last; + -g|-G will create the gophermap if it isn't found. + -h Prints this blurb + -i 'custom.html' Specify a custom index file over the default + -I force index file to be "index.html" + -l edit latest post's *.raw; used with '-r' publishes changes; + calls reformat automatically; + -L [1-9\d*] edit the Nth latest, relative to last post; lp starts at 1 + -m 'message ...' Epecify entry message at commandline and avoid vi + -n Lists all entries, newest first, then quits + -o Lists all entries, oldest first, then quits + -p See what *raw files don't have an entry in the INDEX + -P Forever deletes all *raw and formatted files associated with + posts that are listed with -p; + -r [1-9\d*] Reformats the Nth latest post + -R reformats _all_ .vee/*.raw files; -c applies as well + -s 'summary' Placed below title in INDEX + -t 'title' Specify title at commandline and avoid annoying default prompt + -T file Define top template; default is ./vee-top.tpl + -u Temporarily set umask to + -U Temporarily set umask to 0022 + -v Version and exit + -x hook Defines hook if not using default ./vee-pre; hook + must be executable, i.e., chmod 755 vee-pre + +Examples: + +%vee + + user will be prompted for title and presented with vi + + if no default dir/files are found, they will be created + +%vee -t "this is the title" + + user will just be presented with a vi session; + +%cat text.txt | vee -b -t "my title" -m "text to go before stdin" + + This publishes contents of text.txt with provided title; -m's msg will be + shown above the cat'd text. This means of publishing content is well suited + for use with cronjobs or batch processes. It also works when GopherMode! is + invoked (-g|-G). + +%vee -l # edit and reformat the latest post +%vee -L 5 # allows one to edit and reformats the fifth latest post +%vee -r 8 # reformats the 8th latest post +%vee -n # see which post is the 8th latest post +%vee -R # reformats ALL posts that have *.raw files + +To delete a post forever: + +1) delete the entry in the INDEX + +2) purge the entry: + %vee -p # make sure it is the one you want to purge + %vee -P # purge it! + + brings up the latest entry as a vi sessions; when changes are save, + all messages are reformatted + + :E We Need to Talk About Gopher Support :E + +vee supports the creation of content in the gophersphere by formatting text-only +posts using the provided formatters (meant for text-only anyway). vee also goes +a step further and generates the gophermap (index listing) for you. + +All of the vee commands immediately above *should* work when GopherMode! is on +which is as simple as adding the -g xor -G flags. -g invokes the Gopher bits +*and* the default www support. -G only invokes the Gopher bits. Not using -g + or -G only involes the traditional www support. + +Usage examples from above, with GopherMode! enabled: + +%vee -l -G # edit and reformat the latest post +%vee -L 5 -g # allows one to edit and reformats the fifth latest post +%vee -r 8 -G # reformats the 8th latest post +%vee -n # see which post is the 8th latest post +%vee -R -g # reformats ALL posts that have *.raw files + +Notes: + +0. Reminder - vee requires zero configurations to start, but *can* be coed + by creating a .veerc file. This is also the case when in GopherGeb!Mode + +1. Batch mode looks for piped input via STDIN; if none after a short time, + message creation fails UNLESS something was passed in via '-m' as well. + If nothing was passed in via '-t' for the title, some default is used; + This is set at the top of the script as 'DEFAULT_TITLE'. + +2. Interactive mode (default) prompts for a title if no '-t' is provided. + Such is the case even if '-m' is used. If '-m' is not used in this + +3. Gopher support (-g|-G) is limited and users may discover weird issues with + updating posts or the batch reformatting options. It's a best effort. Also + the gophermap is fully regenerated whenever a new post is added; for a large + number of posts this may take a few seconds. + +4. Patches are welcome; the goal is not more feature bloat, but a nicer + way of dealing with STDIN, etc and reports/fixes for any weird gopher phlog + bugs or UX would be greatly welcomed. vee development laid dormant for years, + being used as a niche static site generator. But the rediscovery of Gopher + by the masses has made adding Gopher support a high priority. + +Copyright (c) 2007-infinity /me +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE +AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + diff --git a/bin/GOALS b/bin/GOALS new file mode 100644 index 0000000..e5b7a77 --- /dev/null +++ b/bin/GOALS @@ -0,0 +1,16 @@ +The goals of the current additions are: + +1. to create a suite of vee related tools that function harmoniously in the Unix way +2. eventually fold vee-ified tools into vee itself, thus making vee itself an application + built out of these special tools + +The goals above represent the desire to transform into something that represents the Unix +traditions as closely as possible. In doing so, maximal flexibility will be achieved. For +example, vee's largest weakness is that post management is virtually nonexistent. It's my +hope to provide the commandline tools that make it possible to write very interesting post +management tools. And ultimately, vee itself will be more about putting together these tools +to provide the expected functionality that vee has come to provide. + +This approach is opposite of trying to make vee a kitchen-sink type of application. I wish +to take it in the opposite direction, and in doing so hope to better serve those using this +application even better. diff --git a/bin/vee b/bin/vee new file mode 100755 index 0000000..36c9734 --- /dev/null +++ b/bin/vee @@ -0,0 +1,919 @@ +#!/bin/sh + +VERSION=2.0-rc1 + +if [ ! "$EDITOR" ]; then + EDITOR=vi +fi + +MARGIN=67 +FORMAT=html +INDEX=vee.html +DIR=.vee +DRAFT="$DIR/.vee.tmp.$$" +USE_EDITOR=1 +LISTENSTDIN=0 +_CUSTOM_UMASK= # use -U to force to 0022 or -u to set something during post +PUBLISHED=$(date "+%m/%d/%Y") # date formated for index page entry +SORT_NEWEST="sort -t. -nr" # sorts all new to old +SORT_OLDEST="sort -t. -n" # sorts all old to new +RAWEXT=raw # default .raw (non-HTML) files, can change to .txt or something else in .veerc + # also used for updating $GOPHERMAP when $GOPHERMODE is 1 (-g) or 2 (-G) +DATE=$(date) +YEAR=$(date "+%Y") +TIME=$(date "+%Y-%m-%dT%H:%M:%S") +SEC=$(date "+%s") +TITLE= +DEFAULT_TITLE="Entry #$SEC (pid: $$)"; +HEADERTXT= # text or $(cat some.header.txt) +FOOTERTXT="Powered by vee
Copyright © 2006-$YEAR" +TOP_TPL=./vee-top.tpl # if file exists, used to generate top of HTML post by OUTPUT_TOP func +BOT_TPL=./vee-bottom.tpl # if file exists, used to generate bottom of HTML post by OUTPUT_BOT func +OUTPUT_TOP=output_top # default template processor, uses TOP_TPL +OUTPUT_BOT=output_bottom # default template processor, use s BOT_TPL + +# PRE/POST Format Hooks; used in both HTML and Gopher modes; to differentiate, $1 is always +# going to be 'html' or 'gopher' +PREFORMAT_HOOK=./vee-pre # the hook is assumed to be executable, else it is ignored +POSTFORMAT_HOOK=./vee-post # the hook is assumed to be executable, esle it is ignored + +# Gopher defaults +GOPHERMODE=0 # -g set it to 1, -G sets it to 2; set in .veerc to skip always typing -g or -G +GOPHER_FORMAT=txt # extension for files linked in gophermap +GOPHERMAP=gophermap # pretty standard, so low chance of this needing to be changed +OUTPUT_TOP_GOPHER= # may define a top "template" function for gopher posts +OUTPUT_BOT_GOPHER= # may define a bottom "template" function for gopher posts +# gophermap header text and footer text - sorry didn't separate them out like was done +# for the HTML support (but these can be customized in a .veerc!) +GOPHERMAP_HEADER="Welcome to my Gophertunnel!" +GOPHERMAP_FOOTER="Carl Spackler: [preparing to dynamite the gopher tunnel] In the immortal words of Jean Paul Sartre, Au revoir, gopher." + + guess_arch() +{ case $(uname) in + Linux) ARCH='linux' + ;; + FreeBSD) ARCH='freebsd' + ;; + NetBSD) ARCH='netbsd' + ;; + Darwin) ARCH='macosx' + ;; + *) ARCH='unknown' + ;; + esac +} + +ARCH='unknown' +guess_arch + +# define custom formatting define custom functions file; see example in # vee/sample-custom-format/vee-custom.sh +FORMAT_FUNC=format_with_groff +FORMAT_DISPATCHER=default_set_format_func +FORMAT_CUSTOM_DISPATCHER=custom_set_format_func +FORMAT_CUSTOM_DEFS=./vee-custom.sh # path is relative to -d DIR, where .veerc resides + +UPDATE_INDEX=default_update_index +CUSTOM_SETUP=default_setup + +# +# vee is a zero configuration, commandline blog tool that +# requires NO installation other than dropping the vee +# script into your ~/bin, or someother directory in your PATH +# +# vee accepts input when in batch mode (-b), so it is well +# suited for use in batch situations, such as in a cronjob +# + +# System utilities required via PATH: +# cat, cd, date, env, find, fmt, fold, grep, groff, +# head, ls, pwd, sort, tail, which +# +# vee provided utilities that must also be in PATH: +# vee (duh!), veels, veecat +# + + disclaimer() +{ echo "Copyright (c) 2007-infinity /me" + echo "Permission is hereby granted, free of charge, to any person" + echo "obtaining a copy of this software and associated documentation" + echo "files (the \"Software\"), to deal in the Software without" + echo "restriction, including without limitation the rights to use," + echo "copy, modify, merge, publish, distribute, sublicense, and/or" + echo "sell copies of the Software, and to permit persons to whom the" + echo "Software is furnished to do so, subject to the following" + echo "conditions:" + echo "The above copyright notice and this permission notice shall be" + echo "included in all copies or substantial portions of the Software." + echo "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY" + echo "KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE" + echo "WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE" + echo "AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT" + echo "HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY," + echo "WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING" + echo "FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR" + echo "OTHER DEALINGS IN THE SOFTWARE." +} + +# +# vee - the minimal, zero configuration command line blog thingy +# +# Contact (bugs, patches, suggestions) +# https://git.sdf.org/pifty/phlea/issues +# +# Instructions: +# 1. put in directory accessible via PATH +# 2. go to a web visible directory and type 'vee' +# 3. put in your title and write your post in vi +# 4. tell your mom to visit: http://..../yourdir/vee.html +# 5. tell your gen Z nephew to visit your gopherhole :E +# +# Tips: +# +# 1 You can force the index to be index.html using "-I", or +# you can specify the index with "-i somefile.html". But, +# if you do this, you'll have to specify this for all other +# commands, otherwise vee defaults to vee.html +# +# 2 vee respects your EDITOR environmental variable +# +# 3 What you do with vee.html or the formatting is up to you :) +# +# 4 Gopher support (-g|-G) may be lacking some parity with http/s +# support, but with feedback this can be fixed and go well beyond +# + +# CREDITS +# Francois Saint-Jacques (fsaintjacques@networkdump.com) supplied 2nd patch ever :) +# efbeha (efbeha@gmail.com) - supplied first patch ever :) +# Oliver @ forums.bsdnexus.com +# arun @ chat.taucher.net #bsd +# J65nko @ bsdforums.com + + default_set_format_func() +{ case $1 in + default) FORMAT_FUNC=format_with_groff + ;; + groff) FORMAT_FUNC=format_with_groff + ;; + fold) FORMAT_FUNC=format_with_fold + ;; + fmt) FORMAT_FUNC=format_with_fmt + ;; + none) FORMAT_FUNC=with_no_formatting + ;; + # if not a supplied format, see if it is in the custom format file, if it exists + *) if [ -e "$FORMAT_CUSTOM_DEFS" ]; then + # call dispatch function that is defined in + # the custom format file, pass on format nickname + $FORMAT_CUSTOM_DISPATCHER "$1" + else + echo "bad format type" + die_cleanly + fi + esac +} + + usage() +{ echo " " + echo " " + echo " .----------------. .----------------. .----------------. " + echo " | .--------------. || .--------------. || .--------------. | " + echo " | | ____ ____ | || | _________ | || | _________ | | " + echo " | ||_ _| |_ _| | || | |_ ___ | | || | |_ ___ | | | " + echo " | | \ \ / / | || | | |_ \_| | || | | |_ \_| | | " + echo " | | \ \ / / | || | | _| _ | || | | _| _ | | " + echo " | | \ ' / | || | _| |___/ | | || | _| |___/ | | | " + echo " | | \_/ | || | |_________| | || | |_________| | | " + echo " | | | || | | || | | | " + echo " | '--------------' || '--------------' || '--------------' | " + echo " '----------------' '----------------' '----------------' " + echo " the Zero-conf, commandline blog tool thingy " + echo " .... now with GopherMode! ("gopherlog" support) " + echo " (see -g|-G) " + echo " " + echo "Version: $VERSION " + echo " " + echo "Options: " + echo " -b Batch mode; used when piping in msg via stdin " + echo " -B file Define bottom template; default is ./vee-bottom.tpl " + echo " -c [1-9\d*] Specify the number of characters 'fold' allows per line " + echo " this only applies when 'fold' (-f) is used " + echo " -d 'publis_dir' Specify the directory .vee is in - defaults to PWD " + echo " -D Debug mode with, set -x " + echo " -f 'format' Option for setting formatinstead of the default, groff; " + echo " 'groff', 'fmt', 'fold', and 'none' are all supported " + echo " -g Update the gophermap file with the INDEX " + echo " -G Exclusively update the gophermap file rather than INDEX " + echo " Note: for -g|-G, the gophermap is merely appended to, there" + echo " is no maintaining of the order from newest first to last; " + echo " -g|-G will create the gophermap if it isn't found. " + echo " -h Prints this blurb " + echo " -i 'custom.html' Specify a custom index file over the default " + echo " -I force index file to be \"index.html\" " + echo " -l edit latest post's *.raw; used with '-r' publishes changes;" + echo " calls reformat automatically; " + echo " -L [1-9\d*] edit the Nth latest, relative to last post; lp starts at 1" + echo " -m 'message ...' Epecify entry message at commandline and avoid vi " + echo " -n Lists all entries, newest first, then quits " + echo " -o Lists all entries, oldest first, then quits " + echo " -p See what *raw files don't have an entry in the INDEX " + echo " -P Forever deletes all *raw and formatted files associated with" + echo " posts that are listed with -p; " + echo " -r [1-9\d*] Reformats the Nth latest post " + echo " -R reformats _all_ .vee/*.raw files; -c applies as well " + echo " -s 'summary' Placed below title in INDEX " + echo " -t 'title' Specify title at commandline and avoid annoying default prompt" + echo " -T file Define top template; default is ./vee-top.tpl " + echo " -u Temporarily set umask to " + echo " -U Temporarily set umask to 0022 " + echo " -v Version and exit " + echo " -x hook Defines hook if not using default "./vee-pre"; hook " + echo " must be executable, i.e., chmod 755 vee-pre " + echo " " + echo "Examples: " + echo " " + echo "%vee " + echo " " + echo " user will be prompted for title and presented with vi " + echo " " + echo " if no default dir/files are found, they will be created " + echo " " + echo "%vee -t \"this is the title\" " + echo " " + echo " user will just be presented with a vi session; " + echo " " + echo "%cat text.txt | vee -b -t \"my title\" -m \"text to go before stdin\" " + echo " " + echo " This publishes contents of text.txt with provided title; -m's msg will be " + echo " shown above the cat'd text. This means of publishing content is well suited " + echo " for use with cronjobs or batch processes. It also works when GopherMode! is " + echo " invoked (-g|-G). " + echo " " + echo "%vee -l # edit and reformat the latest post " + echo "%vee -L 5 # allows one to edit and reformats the fifth latest post " + echo "%vee -r 8 # reformats the 8th latest post " + echo "%vee -n # see which post is the 8th latest post " + echo "%vee -R # reformats ALL posts that have *.raw files " + echo " " + echo "To delete a post forever: " + echo " " + echo "1) delete the entry in the INDEX " + echo " " + echo "2) purge the entry: " + echo " %vee -p # make sure it is the one you want to purge " + echo " %vee -P # purge it! " + echo " " + echo " brings up the latest entry as a vi sessions; when changes are save, " + echo " all messages are reformatted " + echo " " + echo " :E We Need to Talk About Gopher Support :E " + echo " " + echo "vee supports the creation of content in the gophersphere by formatting text-only" + echo "posts using the provided formatters (meant for text-only anyway). vee also goes" + echo "a step further and generates the gophermap (index listing) for you. " + echo " " + echo "All of the vee commands immediately above *should* work when GopherMode! is on" + echo "which is as simple as adding the -g xor -G flags. -g invokes the Gopher bits " + echo "*and* the default www support. -G only invokes the Gopher bits. Not using -g " + echo " or -G only involes the traditional www support. " + echo " " + echo "Usage examples from above, with GopherMode! enabled: " + echo " " + echo "%vee -l -G # edit and reformat the latest post " + echo "%vee -L 5 -g # allows one to edit and reformats the fifth latest post " + echo "%vee -r 8 -G # reformats the 8th latest post " + echo "%vee -n # see which post is the 8th latest post " + echo "%vee -R -g # reformats ALL posts that have *.raw files " + echo " " + echo "Notes: " + echo " " + echo "0. Reminder - vee requires zero configurations to start, but *can* be coed " + echo " by creating a .veerc file. This is also the case when in GopherGeb!Mode " + echo " " + echo "1. Batch mode looks for piped input via STDIN; if none after a short time, " + echo " message creation fails UNLESS something was passed in via '-m' as well. " + echo " If nothing was passed in via '-t' for the title, some default is used; " + echo " This is set at the top of the script as 'DEFAULT_TITLE'. " + echo " " + echo "2. Interactive mode (default) prompts for a title if no '-t' is provided. " + echo " Such is the case even if '-m' is used. If '-m' is not used in this " + echo " " + echo "3. Gopher support (-g|-G) is limited and users may discover weird issues with " + echo " updating posts or the batch reformatting options. It's a best effort. Also " + echo " the gophermap is fully regenerated whenever a new post is added; for a large" + echo " number of posts this may take a few seconds. " + echo " " + echo "4. Patches are welcome; the goal is not more feature bloat, but a nicer " + echo " way of dealing with STDIN, etc and reports/fixes for any weird gopher phlog" + echo " bugs or UX would be greatly welcomed. vee development laid dormant for years," + echo " being used as a niche static site generator. But the rediscovery of Gopher " + echo " by the masses has made adding Gopher support a high priority. " + echo " " + disclaimer + exit 1 +} + + default_update_html_index() +{ echo "$PUBLISHED: $3" >> $INDEX + if [ -n "$SUMMARY" ]; then + SEC=$(expr "$SEC" - 1) + echo "$SUMMARY" >> "$INDEX" + fi +} + + default_update_gophermap() +{ # rebuild the entire $GOPHERMAP + # toggle IFS if in -b mode + if [ 1 -eq $LISTENSTDIN ]; then + _OLDIFS=$IFS + IFS=$OLDIFS + fi + if [ -e $GOPHERMAP ]; then + echo Found existing $GOPHERMAP, renaming to $GOPHERMAP.bkp + mv $GOPHERMAP $GOPHERMAP.bkp #(be nice, just move to the side) + fi + default_setup_gophermap # initialize gophermap + for f in $(veels -d "$DIR" -e "$GOPHER_FORMAT"); do + _RAW=$(echo $f | sed 's/$GOPHER_FORMAT/$RAWEXT/') + _TITLE=$(echo $_RAW | veecat -t) + _DATE=$(echo $_RAW | veecat -d | awk '{print $3 " " $2 " " $6}') #e.g., Fri May 29 09:02:12 UTC 2020 + # creating a symlink to $DIR because the default $DIR + # starts with a '.' and the gopher server seems to not + # want to serve files in such a directory + fileLink=$(echo $f | sed "s/$DIR/phlogsrc/") + # seems relative paths can't be directories that start + # with a dot (e.g., ".vee") + ln -s $DIR phlogsrc > /dev/null 2>&1 # rather than check if link exists, just try it and hide error + printf "0[$_DATE] $_TITLE\t$fileLink\n" >> $GOPHERMAP + done + echo >> $GOPHERMAP + echo >> $GOPHERMAP + echo $GOPHERMAP_FOOTER | fmt -w 67 >> $GOPHERMAP + echo >> $GOPHERMAP + echo >> $GOPHERMAP + echo Generated with vee. >> $GOPHERMAP + # toggle IFS back if temporarily set to interactive IFS above + if [ 1 -eq $LISTENSTDIN ]; then + IFS=$_OLDIFS + fi +} + + #"$FINAL" "$gFINAL" "$RAW" "$gRAW" "$TITLE" + default_update_index() +{ + if [ 2 != $GOPHERMODE ]; then + default_update_html_index "$1" "$3" "$5" + fi + if [ 0 != $GOPHERMODE ]; then + default_update_gophermap "$2" "$4" "$5" + fi +} + + output_top() +{ echo "$HEADERTXT" > "$FINAL" + if [ -e "$TOP_TPL" ]; then + cat "$TOP_TPL" >> "$FINAL" + else + echo "" >> "$FINAL" + echo "" >> "$FINAL" + echo " $TITLE - $DATE" >> "$FINAL" + echo " " >> "$FINAL" + echo "
"                                                                                   >> "$FINAL"
+     echo "[index][raw][main]" >> "$FINAL"
+   fi
+   echo                   >> "$FINAL"
+}
+
+ output_bottom()
+{ echo                   >> "$FINAL"
+  echo --                >> "$FINAL"
+  echo "$FOOTERTXT"      >> "$FINAL"
+  if [ -e "$BOT_TPL" ]; then
+    cat "$BOT_TPL"       >> "$FINAL"
+  else
+    echo "    
" >> "$FINAL" + echo " " >> "$FINAL" + echo "" >> "$FINAL" + fi +} + +# begin formatting funcs + + format_with_groff() +{ #sed 1liner from http://sed.sourceforge.net/sed1line.txt + if [ "html" = "$_OUTPUT_TYPE" ]; then + groff -man -Tascii "$RAW" > $$.tmp.$RAWEXT + sed '/^$/N;/\n$/D' < $$.tmp.$RAWEXT > $$.tmp.final + cat $$.tmp.final >> "$FINAL" + fi + if [ "gopher" = "$_OUTPUT_TYPE" ]; then + groff -man -Tascii "$gRAW" > $$.tmp.$RAWEXT + sed '/^$/N;/\n$/D' < $$.tmp.$RAWEXT > $$.tmp.final + cat $$.tmp.final > "$gFINAL" + fi + rm $$.tmp.$RAWEXT $$.tmp.final +} + + format_with_fmt() +{ if [ 0 -lt $MARGIN ]; then + if [ "html" = $_OUTPUT_TYPE ]; then + fmt -w $MARGIN "$RAW" > $$.tmp.$RAWEXT + cat $$.tmp.$RAWEXT >> "$FINAL" + fi + if [ "gopher" = $_OUTPUT_TYPE ]; then + fmt -w $MARGIN "$gRAW" > $$.tmp.$RAWEXT + cat $$.tmp.$RAWEXT > "$gFINAL" + fi + rm $$.tmp.$RAWEXT + else + with_no_formatting + fi +} + + format_with_fold() +{ if [ 0 -lt $MARGIN ]; then + if [ "html" = $_OUTPUT_TYPE ]; then + fold -s -w $MARGIN "$RAW" > $$.tmp.$RAWEXT + cat $$.tmp.$RAWEXT >> "$FINAL" + fi + if [ "gopher" = $_OUTPUT_TYPE ]; then + fold -s -w $MARGIN "$gRAW" > $$.tmp.$RAWEXT + cat $$.tmp.$RAWEXT > "$gFINAL" + fi + rm $$.tmp.$RAWEXT + else + with_no_formatting + fi +} + + with_no_formatting() +{ if [ "html" = $_OUTPUT_TYPE ]; then + cat "$RAW" >> "$FINAL" + fi + if [ "gopher" = $_OUTPUT_TYPE ]; then + cat "$gRAW" > "$gFINAL" + fi +} + +# +# preformat hook has been changed to NOT be a filter; +# +# $1 is 'html' or 'gopher' +# + preformat() +{ if [ -x "$PREFORMAT_HOOK" ]; then + "$PREFORMAT_HOOK" "$1" + fi +} + +# +# this hook is for any things to do after the post; a good example for use +# would be to integrate git or another SCM; another is a notification script +# +# $1 is 'html' or 'gopher' +# + postformat() +{ if [ -x "$POSTFORMAT_HOOK" ]; then + "$POSTFORMAT_HOOK" "$1" + fi +} + +# dispatches formatting based on $GOPHERMODE; sets $_OUTPUT_TYPE +# for called functions to know for what $_OUTPUT_TYPE they're doing stuff + + format_main_html() +{ FINAL=$DIR/$1 + FINALNAME=$1 + RAW=$DIR/$2 + RAWNAME=$2 + preformat $_OUTPUT_TYPE # expecting 'html' + if [ ! -e "$RAW" ]; then + echo "$DATE" > "$RAW" # in RAW, line 1 is date + echo >> "$RAW" + echo "$TITLE" >> "$RAW" # in RAW, line 2 is title + echo >> "$RAW" + echo "--" >> "$RAW" + echo >> "$RAW" # this blank line is important + cat "$DRAFT" >> "$RAW" + fi + $OUTPUT_TOP + $FORMAT_FUNC + $OUTPUT_BOT + postformat $_OUTPUT_TYPE # expecting 'html' +} + + format_main_gopher() +{ gFINAL=$DIR/$1 + gFINALNAME=$1 + gRAW=$DIR/$2 + gRAWNAME=$2 + preformat $_OUTPUT_TYPE # expecting 'gopher' + if [ ! -e "$gRAW" ]; then + echo "$DATE" > "$gRAW" # in gRAW, line 1 is date + echo >> "$gRAW" + echo "$TITLE" >> "$gRAW" # in gRAW, line 2 is title + echo >> "$gRAW" + echo "--" >> "$gRAW" + echo >> "$gRAW" # this blank line is important + cat "$DRAFT" >> "$gRAW" + fi + $OUTPUT_TOP_GOPHER # NOTE: not set by default + $FORMAT_FUNC + $OUTPUT_BOT_GOPHER # NOTE not set by default + postformat $_OUTPUT_TYPE # expecting 'gopher' +} + + format_main() +{ if [ 2 != $GOPHERMODE ]; then + _OUTPUT_TYPE=html # tracks formatting type + format_main_html "$1" "$3" + fi + + if [ 0 != $GOPHERMODE ]; then + _OUTPUT_TYPE=gopher # tracks formatting type + format_main_gopher "$2" "$3" + fi + _OUTPUT_TYPE=none +} + + reformat_singleton() +{ if [ -e "$DIR/$1.$RAWEXT" ]; then + cat "$DIR/$1.$RAWEXT" > "$DRAFT" + format_main "$1.$FORMAT" "$1.$GOPHER_FORMAT" "$1.$RAWEXT" + fi +} + + reformat_all() +{ + for f in $(veels -d "$DIR" -r); do + # From: Randall R Schulz + FULLNAME="$f" + DIR=${FULLNAME%/*} + FILE=${FULLNAME##*/} + MAXBASE=${FILE%.*} + MINBASE=${FILE%%.*} + MAXSUF=${FILE#*.} + MINSUF=${FILE##*.} + _TITLE=$(echo $f | veecat -t) + echo "..reformatting '$_TITLE'" + reformat_singleton "$MAXBASE" + done +} + + list_newest_first() +{ COUNT=1 + for _RAW in $(veels -d "$DIR"); do + _TITLE=$(echo $_RAW | veecat -t) + _DATE=$(echo $_RAW | veecat -d) + printf "%4d) " "$COUNT" + echo $_DATE - $_TITLE + COUNT=$(expr $COUNT + 1) + done +} + + list_oldest_first() +{ COUNT=1 + for _RAW in $(veels -d "$DIR" -r); do + _TITLE=$(echo $_RAW | veecat -t) + _DATE=$(echo $_RAW | veecat -d) + printf "%4d) " "$COUNT" + echo $_DATE - $_TITLE + COUNT=$(expr $COUNT + 1) + done +} + + get_path2post() +{ + GOAL=$1 + COUNT=1 + for FILE in $(veels -d "$DIR"); do + FULLNAME=$FILE + DIR=${FULLNAME%/*} + FILE=${FULLNAME##*/} + MAXBASE=${FILE%.*} + if [ "$COUNT" -eq "$GOAL" ]; then + echo "$MAXBASE" + break + fi + COUNT=$(expr "$COUNT" + 1) + done +} + + purge_entries() +{ LEVEL=$1 + COUNT=0 + if [ ! -e "$INDEX" ]; then + echo "Can't find index, \"$INDEX\"" + die_cleanly + fi + for FILE in $(veels -d "$DIR"); do + FULLNAME=$FILE + DIR=${FULLNAME%/*} + FILE=${FULLNAME##*/} + MAXBASE=${FILE%.*} + ENTRY=$(grep "$MAXBASE" "$INDEX") + if [ -z "$ENTRY" ]; then + COUNT=$(expr "$COUNT" + 1) + if [ "$LEVEL" -eq 1 ]; then + echo "$DIR/$FILE (not really purged, use -P for realz)" + elif [ "$LEVEL" -eq 2 ]; then + echo "$DIR/$MAXBASE[.$RAWEXT,$FORMAT] (delebed)" + rm -f "$DIR/$MAXBASE"* + fi + fi + done + if [ "$LEVEL" -eq 1 ]; then + echo "use -P to remove all $COUNT entrie(s)" + elif [ "$LEVEL" -eq 2 ]; then + echo "removed $COUNT entrie(s)..." + fi +} + + die_cleanly() +{ if [ -e "$DRAFT" ]; then + rm -f "$DRAFT" + fi + exit 0 +} + +_POST2REFORMAT=0 +_REFORMATALL=0 +_PURGELEVEL=0 +_POST2EDIT=0 +SUMMARY= +MESSAGE= +SET_DEFAULT_FORMAT_FUNC= + +# get opts ! stdin append to anything passed in by -m +while getopts 'DgGf:m:t:T:c:d:i:IbB:hRr:lL:novx:X:Pps:u:U' option; do + case $option in + u) _CUSTOM_UMASK=$OPTARG + ;; + U) _CUSTOM_UMASK=0022 + ;; + D) set -x + echo Setting debug mode with, set -x + ;; + g) # Gopher mode 1: output .txt and update $GOPHERMAP along side of HTML + GOPHERMODE=1 + ;; + G) # Gopher mode 2: treat as gopher phlog only (skip HTML stuff) + GOPHERMODE=2 + ;; + i) INDEX=$OPTARG # specify INDEX to $OPTARG + ;; + I) INDEX="index.html" # force INDEX to index.html + ;; + d) if [ -d "$OPTARG" ]; then + cd "$OPTARG" + else + echo "$OPTARG" is not a directory! + die_cleanly + fi + ;; + r) _POST2REFORMAT=$OPTARG + ;; + R) _REFORMATALL=1 + ;; + b) LISTENSTDIN=1 + USE_EDITOR=0 + ;; + B) BOT_TPL=$OPTARG + ;; + f) SET_DEFAULT_FORMAT_FUNC=$OPTARG + ;; + c) MARGIN=$OPTARG + ;; + l) _POST2EDIT=1 + ;; + L) _POST2EDIT=$OPTARG + ;; + m) MESSAGE=$OPTARG + USE_EDITOR=0 + ;; + n) list_newest_first + die_cleanly + ;; + o) list_oldest_first + die_cleanly + ;; + s) SUMMARY=$OPTARG + ;; + t) TITLE=$OPTARG + ;; + T) TOP_TPL=$OPTARG + ;; + v) echo $VERSION + die_cleanly + ;; + p) _PURGELEVEL=1 + ;; + P) _PURGELEVEL=2 + ;; + h) usage | less + die_cleanly + ;; + x) PREFORMAT_HOOK=$OPTARG + ;; + ?) #usage | less + die_cleanly + ;; + esac +done + + post_opts() +{ + if [ -n "$_CUSTOM_UMASK" ]; then + umask "$_CUSTOM_UMASK" + fi + if [ $LISTENSTDIN -ne 1 ]; then + # brute check for umask 0022 if not using -b ($LISTENSTDIN -eq 1) + if [ $(umask) != "0022" ]; then + _default=yes + read -p "Would you like to temporarily set umask to 0022, to create files that are world readable [$_default]?" tmp_set_umask + if [ -z "$tmp_set_umask" ]; then + tmp_set_umask=$_default + fi + if [ "$tmp_set_umask" = "yes" ]; then + echo + umask 0022 && \ + echo OK. To avoid this message in the future use -U, set umask in your login environment, or set the _CUSTOM_UMASK variable in your ./.veerc. + fi + fi + else + echo Warning: umask should be set to 0022. Your files may not be visible to others. + fi + + if [ -e "$FORMAT_CUSTOM_DEFS" ]; then + . "$FORMAT_CUSTOM_DEFS" + fi + + if [ -n "$SET_DEFAULT_FORMAT_FUNC" ]; then + "$FORMAT_DISPATCHER" "$SET_DEFAULT_FORMAT_FUNC" # default is set_format_func + fi + + if [ "$_PURGELEVEL" -ge 1 ]; then + purge_entries "$_PURGELEVEL" + die_cleanly + fi + + if [ "$_POST2EDIT" -ge 1 ]; then + LATEST=$(get_path2post "$_POST2EDIT") + $EDITOR "$DIR/$LATEST.$RAWEXT" + _POST2REFORMAT=$_POST2EDIT + fi + + if [ "$_POST2REFORMAT" -ge 1 ]; then + LATEST=$(get_path2post "$_POST2REFORMAT") + reformat_singleton "$LATEST" + if [ 0 != $GOPHERMODE ]; then + default_update_gophermap + fi + die_cleanly + fi + + # if "-R", or reformat all, is set + if [ "$_REFORMATALL" -eq 1 ]; then + # future may yield seperate "rebuild reindex" functionality + reformat_all + if [ 0 != $GOPHERMODE ]; then + default_update_gophermap + fi + die_cleanly + fi + + # blocks vee -l (without the -r) from going on + if [ "$_POST2EDIT" -ge 1 ]; then + die_cleanly + fi + + # Batch message creation: -m and stdin + # handles -m + if [ -n "$MESSAGE" ]; then + echo "$MESSAGE" >> "$DRAFT" + fi + + if [ $LISTENSTDIN -eq 1 ]; then + OLDIFS=$IFS + IFS="" # ensures that leading spaces are retained + while read -r IN <&0 ; do # break after 1 sec of no stdin + echo "$IN" # echo's stdin back out so user can see + echo "$IN" >> "$DRAFT" + LISTENSTDIN=1 + USE_EDITOR=0 + done + fi +} + +# generates INDEX file if none exists + default_setup_html() +{ if [ ! -e "$INDEX" ]; then + echo + echo "...creating $INDEX" + echo "my vee index
" >> "$INDEX"
+   # header stuff
+    echo "" >> "$INDEX"
+    echo "" >> "$INDEX"
+    echo "" >> "$INDEX"
+   # footer stuff
+    echo "" >> "$INDEX"
+    echo "" >> "$INDEX"
+    echo "Powered by vee" >> "$INDEX"
+    echo "
" >> "$INDEX" + echo + fi +} + + default_setup_gophermap() +{ if [ ! -e "$GOPHERMAP" ]; then + echo + echo "...generating updated $GOPHERMAP" + echo $GOPHERMAP_HEADER > $GOPHERMAP + echo >> $GOPHERMAP + echo >> $GOPHERMAP + fi +} + + default_setup() +{ + if [ 2 != $GOPHERMODE ]; then + default_setup_html + fi + if [ 0 != $GOPHERMODE ]; then + default_setup_gophermap + fi +} + + use_editor() +{ if [ $USE_EDITOR -eq 1 ]; then + OK=0 + $EDITOR "$DRAFT" && OK=1 + if [ "$OK" -ne 1 ]; then + echo there has been a problem with your editor session + exit + fi + #else + #echo ...vi mode off + fi +} + +# ask for title if not set with -t and not in batch mode +# if in batch mode with no -t set, use default title below + get_title() +{ if [ -z "$TITLE" ]; then + TITLE=$DEFAULT_TITLE + fi +} + + read_config() +{ if [ -e ./.veerc ]; then + . ./.veerc + fi +} + +# this case statement may be overkill if "sort -t';' -nr -k2,2" works across platforms + sort_index() +{ if [ -e "$INDEX" ]; then + case $ARCH in + linux) sort -t';' +0f -1 +1nr "$INDEX" > ".$INDEX.$$.sorted" + ;; + freebsd) sort -t';' +0f -1 +1nr "$INDEX" > ".$INDEX.$$.sorted" + ;; + netbsd) sort -t';' +0f -1 +1nr "$INDEX" > ".$INDEX.$$.sorted" + ;; + macosx) # -k2,2 sorts by second field as delimted by -t';' - this may actually work + # for all platforms + sort -t';' -nr -k2,2 "$INDEX" > ".$INDEX.$$.sorted" + ;; + *) sort -t';' +0f -1 +1nr "$INDEX" > ".$INDEX.$$.sorted" + ;; + esac + mv ".$INDEX.$$.sorted" "$INDEX" # "rebuild $INDEX + fi +} + +#-- main program body +mkdir -p "$DIR" || echo "found $DIR ..." + +read_config # done after all options are read in, could look in -d before + # opts are processed though so opts could override defaults + # and config file .. yeah do that +post_opts # process options +"$CUSTOM_SETUP" # initialized indexes, can be defined in .veerc +get_title +use_editor + + main() +{ if [ -e "$DRAFT" ]; then + RAWFILE="$SEC.$$.$TIME.$RAWEXT" # uses process id, $$, assuming there will + # not be duplicate process ids within 1 sec of each other + format_main "$SEC.$$.$TIME.$FORMAT" "$SEC.$$.$TIME.$GOPHER_FORMAT" "$RAWFILE" + "$UPDATE_INDEX" "$FINAL" "$gFINAL" "$RAW" "$gRAW" "$TITLE" + sort_index + die_cleanly +else + echo Error! "$DRAFT" not found +fi +} + +main diff --git a/bin/vee-publish b/bin/vee-publish new file mode 100755 index 0000000..ac9dce1 --- /dev/null +++ b/bin/vee-publish @@ -0,0 +1,56 @@ +#!/bin/sh + +RSYNC=$(which rsync) + +if [ "$RSYNC" == "" ]; then + echo "No rsync installed." + exit 1 +fi + +usage() { + cat < | SSH server path +EOS +} + +STD_VEERC_PATH=~/.veerc + +VERBOSE=0 +SERVER= + +while getopts 'hs:v' opt +do + case $opt in + h) usage && exit 1 + ;; + + v) VERBOSE=1 + ;; + + s) SERVER=$OPTARG + ;; + + *) usage && exit 1 + ;; + esac +done + +if [ "$SERVER" == "" ]; then + echo "No server." + exit 1 +fi + +putstr() { + [[ $VERBOSE -eq 1 ]] && echo -e "[$(basename $0)]: $*" +} + +putstr "Reading veerc" +. $STD_VEERC_PATH || exit 1 + +putstr "Syncing $DIR/* -> $SERVER" +rsync -ptuvPzh --stats -e ssh $DIR/* $SERVER + +echo "Done." diff --git a/bin/vee-rebuild b/bin/vee-rebuild new file mode 100755 index 0000000..f86dfaa --- /dev/null +++ b/bin/vee-rebuild @@ -0,0 +1,126 @@ +#!/bin/sh + +GENDATE=$(date) +VEEDIR=./.vee +HTMLEXT=html + + die_error() +{ + echo "$1" + exit 1 +} + + die_cleanly() +{ + exit 0 +} + + usage() +{ + man vee-rebuild +} + + guess_arch() +{ case $(uname) in + Linux) ARCH='linux' + ;; + FreeBSD) ARCH='freebsd' + ;; + Darwin) ARCH='macosx' + ;; + *) ARCH='unknown' + ;; + esac +} + +ARCH='unknown' +guess_arch + + format_date() +{ case $ARCH in + linux) TSP2FORMATTED=$(date --date "$1" +%m/%d/%Y) + ;; + freebsd) TSP2FORMATTED=$(date -j -f "%a %b %e %H:%M:%S %Z %Y" "$1" +%m/%d/%Y) + ;; + macosx) TSP2FORMATTED=$(date -j -f "%a %b %e %H:%M:%S %Z %Y" "$1" +%m/%d/%Y) + ;; + *) # nothing + ;; + esac + echo $TSP2FORMATTED +} + + format_epoch() +{ case $ARCH in + linux) TSP2EPOCH=$(date --date "$1" +%s) + ;; + freebsd) TSP2EPOCH=$(date -j -f "%a %b %e %H:%M:%S %Z %Y" "$1" +%s) + ;; + macosx) TSP2EPOCH=$(date -j -f "%a %b %e %H:%M:%S %Z %Y" "$1" +%s) + ;; + *) # nothing + ;; + esac + echo $TSP2EPOCH +} + +while getopts 'd:h' option; do + case $option in + d) if [ -d "$OPTARG" ]; then + cd "$OPTARG" + else + echo "$OPTARG" is not a directory! + die_cleanly + fi + ;; + h) usage # some help page + die_cleanly + ;; + esac +done + +if [ ! -d "$VEEDIR" ]; then + echo "Can't find $VEEDIR!" + exit; +fi + +echo "" +echo "" +echo "" +echo "
"
+
+for f in $(veels); 
+do
+    # title is the 3rd line
+    TITLE=$(echo "$f" | veecat -t)
+
+    # full date string (not epoch) is the first line
+    DATE=$(echo "$f" | veecat -d)
+
+    # deal with with timezone info in a brutish way (seems like a TZ mismatch in data input will cause error)
+    TZ_SYS=$(date "+%Z")
+    DOW=$(echo "$DATE" | awk '{ print "$1" }')
+    MON=$(echo "$DATE" | awk '{ print "$2" }')
+    DOM=$(echo "$DATE" | awk '{ print "$3" }')
+    HMS=$(echo "$DATE" | awk '{ print "$4" }')
+    TZN=$(echo "$DATE" | awk '{ print "$5" }')
+    YR=$(echo "$DATE" | awk '{ print "$6" }')
+
+    # reformate date for indexing purposes (.raw files untouched)
+    #FORMATTED_DATE=$(date -j -f "%a %b %e %H:%M:%S %Z %Y" "$DATE" +%m/%d/%Y)
+    FORMATTED_DATE=$(format_date "$DATE")
+
+    # get epoch for purpose of adding reasonable post index numbers 
+    #EPOCH=$(date -j -f "%a %b %e %H:%M:%S %Z %Y" "$DATE" +%s)
+    EPOCH=$(format_epoch "$DATE")
+
+    # extract base name of .raw file so we can link to html file of same base
+    FILENAME=$(basename "$f")
+    BASENAME=${FILENAME%.*}
+    # output HTML index (can be modified to output in whatever format)
+    echo "$FORMATTED_DATE $TITLE"
+done
+
+echo ""
+echo 'Powered by vee'
+echo "
" diff --git a/bin/veecat b/bin/veecat new file mode 100755 index 0000000..8b5f9db --- /dev/null +++ b/bin/veecat @@ -0,0 +1,119 @@ +#!/bin/sh + +# This is a companion tool to vee that is used internally by vee; if +# you wish to write your own custom scripts to manage your posts, then +# then I suggest using this tool for extracting out the relevant bits +# you wish to use for your scripts (e.g., title (-t), date (-d), etc). + +# Usage: +# echo "path/to/*.raw" | veecat [-t | -d | -a ] # I know this is funky + +# preserve new lines +OLD_IFS=$IFS +IFS= + + die_error() +{ + echo "$1" + exit 1 +} + + die_cleanly() +{ + exit 0 +} + + read_config() +{ if [ -e ./.veerc ]; then + . ./.veerc + fi +} + + get_title() +{ + TITLE=$(head -n 3 "$1" | tail -n 1) + echo "$TITLE" +} + + get_date() +{ + DATE=$(head -n 1 "$1") + echo "$DATE" +} + + get_header() +{ + # get line one through line 5, the entire header w/o separator + echo $(cat "$1" | head -n 5) +} + + get_body() +{ + # figure out how many lones file is for $(tail) command + LC=$(wc -l "$1" | awk '{print "$1"}') + BC=$(($LC-6)) + $(cat "$1" | tail -n "$BC") + +} + + get_all() +{ + cat "$1" +} + + die_error() +{ + echo "$1" + exit 1 +} + + die_cleanly() +{ + exit 0 +} + +SHOWBODY=0 +SHOWTITLE=0 +SHOWDATE=0 +SHOWALL=0 + +while getopts 'abdt' option; do + case $option in + a) SHOWALL=1 + ;; + b) SHOWBODY=1 + ;; + d) SHOWDATE=1 + ;; + t) SHOWTITLE=1 + ;; + esac +done + +read_config + +# if -tdb detected, do the right thing and do a SHOWALL (i.e., -tbd == -a ) +if [ $SHOWTITLE -eq 1 ] && [ $SHOWDATE -eq 1 ] && [ $SHOWBODY -eq 1 ]; then + SHOWALL=1 +fi + +# kind of funky, but accepts the name of the .raw file via standard in +while read -r IN <&0 ; do + # make sure file exists, else just ignore line (more Unix-y this way) + if [ -e "$IN" ]; then + # assumes file is a proper *.raw , else GIGO + if [ $SHOWALL -eq 1 ]; then + echo $(get_all "$IN") + else + if [ $SHOWTITLE -eq 1 ]; then + echo $(get_title "$IN") + fi + if [ $SHOWDATE -eq 1 ]; then + echo $(get_date "$IN") + fi + if [ $SHOWBODY -eq 1 ]; then + echo $(get_body "$IN") + fi + fi + fi +done diff --git a/bin/veefind b/bin/veefind new file mode 100755 index 0000000..c9bf76e --- /dev/null +++ b/bin/veefind @@ -0,0 +1,96 @@ +#!/bin/sh + +DIR=.vee +FIND=`which find` + +SORT_NEW_FIRST='sort -t. -nr' +SORT_OLD_FIRST='sort -t. -n' +SORT="$SORT_NEW_FIRST" +STRIPEXT=0 +USEFIND=0 +FINDOPTS= +MAXDEPTH=1 + + die_error() +{ + echo "$1" + exit 1 +} + + die_cleanly() +{ + exit 0 +} + + usage() +{ + man veefind +} + +while getopts 'd:hF:M:rx' option; do + case $option in + d) if [ -d "$OPTARG" ]; then + cd "$OPTARG" + else + echo "$OPTARG" is not a directory! + die_cleanly + fi + ;; + F) USEFIND=1 #use find with custom opts + FINDOPTS="$OPTARG" + ;; + M) MAXDEPTH="$OPTARG" + ;; + r) SORT=$SORT_OLD_FIRST # list in reverse post order + ;; + x) STRIPEXT=1 #strip .raw from output + ;; + h) usage # some help page + die_cleanly + ;; + esac +done + + read_config() +{ if [ -e ./.veerc ]; then + . ./.veerc + fi +} + + get_sorted() +{ + $FIND $DIR -maxdepth $MAXDEPTH -name "*.raw" | $SORT +} + + get_title() +{ + TITLE=$(head -n 3 "$1" | tail -n 1) + echo "$TITLE" +} + + get_date() +{ + DATE=$(head -n 1 "$1") + echo "$DATE" +} + +#-- main program body + +#-- read config, $(pwd)/.veerc (happens after "-d" so it's consistent +#-- with how bin/vee does it) +read_config + +for f in $(get_sorted); +do + # title is the 3rd line + TITLE=$(get_title "$f") + + # full date string (not epoch) is the first line + DATE=$(get_date "$f") + + if [ 1 -eq $STRIPEXT ]; then + echo "${f%\.*}" + else + echo "$f" + fi +done diff --git a/bin/veels b/bin/veels new file mode 100755 index 0000000..29b553b --- /dev/null +++ b/bin/veels @@ -0,0 +1,87 @@ +#!/bin/sh + +# This is a companion tool to vee that is used internally by vee; if +# you plan on writing custom scripts to manage your posts, I do suggest +# using `veels` as the primary was of listing the files for iteration +# or for whatever you use it for. + +#Usage: +# veels [ -d dir/with/.raw/files ] [ -r ] [ -e raw|txt ] + +DIR=.vee +SORT_NEW_FIRST='sort -t. -nr' +SORT_OLD_FIRST='sort -t. -n' +SORT="$SORT_NEW_FIRST" +STRIPEXT=0 +USELS=0 +LSOPTS='-lat' +EXT=raw + + die_error() +{ + echo "$1" + exit 1 +} + + die_cleanly() +{ + exit 0 +} + +while getopts 'd:e:hlL:rx' option; do + case $option in + d) if [ -d "$OPTARG" ]; then + DIR="$OPTARG" + else + echo "$OPTARG" is not a directory! + die_cleanly + fi + ;; + e) EXT=$OPTARG + ;; + l) USELS=1 #use ls with default opts + ;; + L) USELS=1 #use ls with custom opts + LSOPTS="$OPTARG" + ;; + r) SORT=$SORT_OLD_FIRST # list in reverse post order + ;; + x) STRIPEXT=1 #strip .raw from output + ;; + h) usage # some help page + die_cleanly + ;; + esac +done + + read_config() +{ if [ -e ./.veerc ]; then + . ./.veerc + fi +} + + get_sorted() +{ + ls -1 ${DIR}/*.${EXT} | ${SORT} +} + + _ls () +{ + ls ${LSOPTS} ${1} +} + +#-- main program body + +read_config + +for f in $(get_sorted); do + if [ 1 -eq $USELS ]; then + _ls "$f" + else + if [ 1 -eq $STRIPEXT ]; then + echo "${f%\.*}" + else + echo "$f" + fi + fi +done diff --git a/custom-formatters/README b/custom-formatters/README new file mode 100644 index 0000000..677b0e8 --- /dev/null +++ b/custom-formatters/README @@ -0,0 +1,6 @@ +Using the 3rd party tool, 'pandoc', it's simple to have markdown to html +support. Since a lot of stuff inside of bin/vee adds HTML for you, markdown +being a useful source format is going require getting a lot of this stuff moved +out. + +Pull request accepted to add support for 'markdown' tool. diff --git a/custom-formatters/vee-custom-3rd-party.sh b/custom-formatters/vee-custom-3rd-party.sh new file mode 100644 index 0000000..d325a8d --- /dev/null +++ b/custom-formatters/vee-custom-3rd-party.sh @@ -0,0 +1,51 @@ +# Formatting options for 3rd party software + +# use the "par" formatting utility, no HTML is generated so you rely on
 to encapsulate
+ format_with_par72()
+{ 
+     PAR=`which par`;
+     if [ "$PAR" == "" ]; then
+       echo par is not installed
+       die_cleanly
+     else
+       cat ${RAW} | ${PAR} -w 72 >> ${FINAL}
+     fi
+}
+
+# uses pandoc, which has a lot of depenencies, but it an all-to-all converter
+ format_with_pandoc() # example implements the same as -f none
+{ 
+     PANDOC=`which pandoc`;
+     if [ "$PANDOC" == "" ]; then
+       echo pandoc is not installed
+       die_cleanly
+     else
+       cat ${RAW} | ${PANDOC} --from=markdown --to=html >> ${FINAL}
+     fi
+}
+
+# uses markdown, a markdown-to-html converter tool
+ format_with_mardown() # e
+{
+    MARKDOWN=`which markdown`;
+    if [ "$MARKDOWN" == "" ]; then
+        echo markdown is not installed
+        die_cleanly
+    else
+        cat ${RAW} | ${MARKDOWN} >> ${FINAL}
+    fi
+}
+
+ custom_set_format_func()
+{ case "$1" in
+    par72) FORMAT_FUNC=format_with_par72
+            ;;
+    pandoc) FORMAT_FUNC=format_with_pandoc
+            ;;
+    markdown) FORMAT_FUNC=format_with_markdown
+            ;;
+    *) echo "$1 bad format type" 
+       die_cleanly
+       ;;
+  esac 
+}
diff --git a/custom-formatters/vee-custom-utf8.sh b/custom-formatters/vee-custom-utf8.sh
new file mode 100644
index 0000000..b59eef7
--- /dev/null
+++ b/custom-formatters/vee-custom-utf8.sh
@@ -0,0 +1,75 @@
+#FORMAT_CUSTOM_DISPATCHER=custom_set_format_func
+#FORMAT_CUSTOM_DEFS=./vee-custom.sh 
+#UPDATE_INDEX=custom_update_index
+#OUTPUT_TOP=custom_output_top
+#OUTPUT_BOT=custom_output_bottom
+
+ format_with_null() # example implements the same as -f none
+{ cat ${RAW} >> ${FINAL}
+}
+
+ format_with_groff_utf8()
+{ #sed 1liner from http://sed.sourceforge.net/sed1line.txt
+  exe=`which groff-utf8 2> /dev/null || echo -1`
+  if [ "-1" != ${exe} ]; then
+    groff-utf8 -man -Tutf8 ${RAW} >> bla.raw
+    sed '/^$/N;/\n$/D' bla.raw >> ${FINAL}
+    rm bla.raw
+  else
+    echo "Warning: groff-utf8 not found, falling back to format_with_groff"
+    format_with_groff
+  fi
+}
+
+ custom_set_format_func()
+{ case "$1" in
+    null) FORMAT_FUNC=format_with_null
+            echo using $FORMAT_FUNC
+            ;;
+    groff-utf8)FORMAT_FUNC=format_with_groff_utf8
+             echo using $FORMAT_FUNC
+             ;;
+    *) echo "bad format type" 
+       die_cleanly
+       ;;
+  esac 
+}
+
+# formats post link on index page
+ custom_update_index()
+{ echo "${PUBLISHED}: ${TITLE}" >> ${INDEX}
+  if [ -n "${SUMMARY}" ]; then
+    SEC=`expr $SEC - 1`
+    echo "${SUMMARY}" >> ${INDEX}
+  fi
+}
+
+ custom_output_top()
+{ echo ${HEADERTXT} > ${FINAL}
+  if [ -e "${TOP_TPL}" ]; then
+     cat "${TOP_TPL}" >> ${FINAL}
+     echo "
"   >> ${FINAL}
+   else
+     echo ""  >> ${FINAL}
+     echo "" >> ${FINAL}
+     echo "${TITLE} - ${DATE}"  >> ${FINAL}
+     echo ""  >> ${FINAL}
+     echo "
"   >> ${FINAL}
+     echo "[index][raw][main]" >> ${FINAL}
+   fi
+   echo           >> ${FINAL}
+}
+
+ custom_output_bottom()
+{ echo          >> ${FINAL}
+  echo --       >> ${FINAL}
+  echo ${FOOTERTXT} >> ${FINAL}
+  if [ -e "${BOT_TPL}" ]; then
+    cat "${BOT_TPL}" >> ${FINAL}
+  else
+    echo "
" >> ${FINAL} + echo "" >> ${FINAL} + echo "" >> ${FINAL} + fi +} + diff --git a/dot.veerc b/dot.veerc new file mode 100644 index 0000000..66b27d5 --- /dev/null +++ b/dot.veerc @@ -0,0 +1,41 @@ +# Sample .veerc, used to override default variables... + +INDEX=index.html +HEADERTXT= # text or `cat some.header.txt` +FOOTERTXT="hijacked by .veerc!" +FORMAT_FUNC=format_with_groff # default formating + +# GopherMode - 1 = -g, 2 = -G +GOPHERMODE=0 +_CUSTOM_UMASK=0022 # needed for SDF, set per use with -U (force to 0022) or -u + +# gophermap header text and footer text - sorry didn't separate them out like was done +# for the HTML support (but these can be customized in a .veerc!) +GOPHERMAP_HEADER="Welcome to my Gophertunnel!" +GOPHERMAP_FOOTER="Carl Spackler: [preparing to dynamite the gopher tunnel] In the immortal words of Jean Paul Sartre, Au revoir, gopher." + +#EDITOR=vi +#FORMAT=html +#INDEX=vee.html +#DIR=.vee +#DRAFT=${DIR}/.vee.tmp.$$ +#DATE=`date` +#YEAR=`date "+%Y"` +#TIME=`date "+%Y-%m-%dT%H:%M:%S"` +#SEC=`date "+%s"` +#DEFAULT_TITLE="Entry #${SEC}"; +#TOP_TPL=./vee-top.tpl +#BOT_TPL=./vee-bottom.tpl +#PREFORMAT_HOOK=./my-pre-hook.sh # the filter is assumed to be executable, else it is ignored +#POSTFORMAT_HOOK=./my-post-hook.sh # not a filter, passes name of final file as argument $1 +#PUBLISHED=`date "+%m/%d/%Y"` # date formated for index page entry +#FORMAT_FUNC=format_with_groff +#FORMAT_DISPATCHER=default_set_format_func +#FORMAT_CUSTOM_DISPATCHER=custom_set_format_func +#FORMAT_CUSTOM_DEFS=./vee-custom.sh # see example in vee/sample-custom-format/ + +#GOPHER_FORMAT=txt # extension for files linked in gophermap +#GOPHERMAP=gophermap # pretty standard, so low chance of this needing to be changed +#OUTPUT_TOP_GOPHER= # may define a top "template" function for gopher posts +#OUTPUT_BOT_GOPHER= # may define a bottom "template" function for gopher posts + diff --git a/patches/applied-11.11.2007.patch b/patches/applied-11.11.2007.patch new file mode 100644 index 0000000..77c7c44 --- /dev/null +++ b/patches/applied-11.11.2007.patch @@ -0,0 +1,30 @@ +--- vee 2007-09-21 23:13:23.000000000 -0400 ++++ /usr/local/bin/vee 2007-11-10 21:36:42.000000000 -0500 +@@ -38,6 +38,7 @@ + OUTPUT_BOT=output_bottom + # define custom format file + FORMAT_CUSTOM_DEFS=./vee-custom.sh # see example in vee/sample-custom-format/ ++FORMAT_CUSTOM_SETUP=setup + + # + # vee is a zero configuration, commandline blog tool that +@@ -557,7 +558,7 @@ + } + + # generates INDEX file if none exists +- setup() ++default_setup() + { mkdir -p ${DIR} || echo ${DIR} exists... + if [ ! -e ${INDEX} ]; then + echo +@@ -577,6 +578,10 @@ + fi + } + ++setup() { ++$FORMAT_CUSTOM_SETUP ++} ++ + sort_index() + { #echo sorting ${INDEX} ... + #sort -t";" +0f -1 +1nr ${INDEX} > .${INDEX}.$$.sorted diff --git a/sample-hooks/vee-hook.pl b/sample-hooks/vee-hook.pl new file mode 100755 index 0000000..81bb21f --- /dev/null +++ b/sample-hooks/vee-hook.pl @@ -0,0 +1,22 @@ +#!/bin/env perl + +use strict; +use warnings; + +# toy filter that replaces USC with an img tag + +my $FORMAT_FUNC = $ARGV[0]; # name of format function is passed in + +while() { + chomp; + if ($_ =~ s/USC//g ) { + # argv[0] is the name of the formatting function + if ($FORMAT_FUNC =~ m/groff/) { + printf("'nf\n%s\n'fi\n",$_); + } else { + printf("%s\n",$_); + } + } else { + printf("%s\n",$_); + } +} diff --git a/sample-hooks/vee-hook.sh b/sample-hooks/vee-hook.sh new file mode 100755 index 0000000..504f7b2 --- /dev/null +++ b/sample-hooks/vee-hook.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# this filter is a null filter; meaning it spits out +# exactly what was passed in + +FORMAT_FUNC=$1 # the name of the format function used is passed in + +IFS="" # ensures that leading spaces are retained +while read -r IN <&0 ; do # break after 1 sec of no stdin + echo "${IN}" # echo's stdin back out so user can see +done diff --git a/sample-hooks/vee-hookmanager.pl b/sample-hooks/vee-hookmanager.pl new file mode 100755 index 0000000..24410e9 --- /dev/null +++ b/sample-hooks/vee-hookmanager.pl @@ -0,0 +1,34 @@ +#!/usr/bin/perl + +# helps facilitate the applications of multiple filters in-line +# set as teh main vee-filter, and it will apply the stream to the +# set filters in the order listed + +use strict; +use warnings; +$|++; + +# define filter dir here +my $FILTERDIR = "sample-filters/"; + +# add new filters to the list - note, they are run in top-down order +# warning - filters are not checked for existence first +my @FILTERS = ( + "$FILTERDIR/vee-filter.sh", + "$FILTERDIR/vee-filter.pl", + ,); + +# +# automated from here on out - do not touch +# +my $FILTERS = join("|",@FILTERS); +my $out = ""; +# loop over STDIN and capture qscript +while (<>) { + $out .= $_; +} +# open pipe to filters, execute +open(FILTER, "|$FILTERS"); + # send contents of qscript to filters + print FILTER $out; +close(FILTER);