Browse Source

initial commit

master
pifty 2 years ago
commit
f5bb0cadd4
  1. 4
      FORKING
  2. 30
      INSTALL
  3. 11
      LICENSE
  4. 207
      README
  5. 16
      bin/GOALS
  6. 919
      bin/vee
  7. 56
      bin/vee-publish
  8. 126
      bin/vee-rebuild
  9. 119
      bin/veecat
  10. 96
      bin/veefind
  11. 87
      bin/veels
  12. 6
      custom-formatters/README
  13. 51
      custom-formatters/vee-custom-3rd-party.sh
  14. 75
      custom-formatters/vee-custom-utf8.sh
  15. 41
      dot.veerc
  16. 30
      patches/applied-11.11.2007.patch
  17. 22
      sample-hooks/vee-hook.pl
  18. 11
      sample-hooks/vee-hook.sh
  19. 34
      sample-hooks/vee-hookmanager.pl

4
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!

30
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

11
LICENSE

@ -0,0 +1,11 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
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.

207
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 <octal> Temporarily set umask to <octal>
-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.

16
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.

919
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<br/>Copyright &copy; 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 <octal> Temporarily set umask to <octal> "
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 "<!-- ;$SEC; -->$PUBLISHED:<a href=\"$1\"> $3</a>" >> $INDEX
if [ -n "$SUMMARY" ]; then
SEC=$(expr "$SEC" - 1)
echo "<!-- ;$SEC; -->$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 "<!-- <?xml version=\"1.0\" encoding=\"UTF-8\" ?> --><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\">" >> "$FINAL"
echo "<meta http-equiv=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">" >> "$FINAL"
echo " <head><title>$TITLE - $DATE</title></head>" >> "$FINAL"
echo " <body>" >> "$FINAL"
echo " <pre>" >> "$FINAL"
echo "<a href=\"../$INDEX\">[index]</a><a href=\"./$RAWNAME\">[raw]</a><a href=\"../\">[main]</a>" >> "$FINAL"
fi
echo >> "$FINAL"
}
output_bottom()
{ echo >> "$FINAL"
echo -- >> "$FINAL"
echo "$FOOTERTXT" >> "$FINAL"
if [ -e "$BOT_TPL" ]; then
cat "$BOT_TPL" >> "$FINAL"
else
echo " </pre>" >> "$FINAL"
echo " </body>" >> "$FINAL"
echo "</html>" >> "$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 <rrschulz at cris dot com>
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 "<!-- ;10000000000000000000000000; open pre tag --><!-- <?xml version=\"1.0\" encoding=\"UTF-8\" ?> --><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>my vee index</title><meta http-equiv=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\"></head><body><pre>" >> "$INDEX"
# header stuff
echo "<!-- ;100000000000000000000000; fixed content -->" >> "$INDEX"
echo "<!-- ;10000000000000000000000; fixed content -->" >> "$INDEX"
echo "<!-- ;1000000000000000000000; fixed content -->" >> "$INDEX"
# footer stuff
echo "<!-- ;3; fixed content -->" >> "$INDEX"
echo "<!-- ;2; fixed content -->" >> "$INDEX"
echo "<!-- ;1; fixed content -->Powered by vee" >> "$INDEX"
echo "<!-- ;0; closing pre tag --></pre></body></html>" >> "$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

56
bin/vee-publish

@ -0,0 +1,56 @@
#!/bin/sh
RSYNC=$(which rsync)
if [ "$RSYNC" == "" ]; then
echo "No rsync installed."
exit 1
fi
usage() {
cat <<EOS
$(basename $0) [options]
-v | be verbose
-h | show this and exit
-s <server> | 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."

126
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 "<!-- ;1000000000000000000000000; initial HTML -->"
echo "<!-- ;100000000000000000000000; more HTML -->"
echo "<!-- ;10000000000000000000000; new index regenerated on $GENDATE -->"
echo "<!-- ;1000000000000000000000; pre tag --><pre>"
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 "<!-- ;$EPOCH; -->$FORMATTED_DATE <a href=$VEEDIR/$BASENAME.$HTMLEXT>$TITLE</a>"
done
echo "<!-- ;2; closing -->"
echo '<!-- ;1; closing -->Powered by vee'
echo "<!-- ;0; closing pre tag --></pre>"

119
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

96
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

87
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

6
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.

51
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 <pre> 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
}

75
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 "<!-- ;${SEC}; -->${PUBLISHED}:<a href=\"${DIR}/${SEC}.${TIME}.${FORMAT}\"> ${TITLE}</a>" >> ${INDEX}
if [ -n "${SUMMARY}" ]; then
SEC=`expr $SEC - 1`
echo "<!-- ;${SEC}; -->${SUMMARY}" >> ${INDEX}
fi
}
custom_output_top()
{ echo ${HEADERTXT} > ${FINAL}
if [ -e "${TOP_TPL}" ]; then
cat "${TOP_TPL}" >> ${FINAL}
echo "<pre>" >> ${FINAL}
else
echo "<!-- <?xml version=\"1.0\" encoding=\"UTF-8\" ?> --><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\">" >> ${FINAL}
echo "<meta http-equiv=\"Content-Type\" CONTENT=\"text/html; charset=UTF-8\">" >> ${FINAL}
echo "<head><title>${TITLE} - ${DATE}</title></head>" >> ${FINAL}
echo "<body>" >> ${FINAL}
echo "<pre>" >> ${FINAL}
echo "<a href=\"../${INDEX}\">[index]</a><a href=\"./${RAWNAME}\">[raw]</a><a href=\"../\">[main]</a>" >> ${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 "</pre>" >> ${FINAL}
echo "</body>" >> ${FINAL}
echo "</html>" >> ${FINAL}
fi
}

41
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 <octal>
# 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

30
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

22
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