#!/bin/bash

# Bash typewriter simulator.

# Runs on any relatively recent Linux system.
# Not tested on anything else.

# This is a 'pure typing' environment. Like a typewriter,
# you can't backspace, can't edit, can only type. This is
# supposed to increase creative writing quality and output, 
# though your mileage definitely may vary. The ideas are that

# (1) you have no choice but to keep typing and
# (2) you type less junk when you know you can't erase it.

# That's the theory, anyhow. But the fact is that this is a
# dead simple typing environment (it's certainly not an editor
# as such) that will run on just about any modern Linux system.

# Usage: bashwriter filename

# 'filename' is the input/output file and is required.
# The program is exited by pressing ctrl-C or ctrl-Z.

# Typing: this is like a typewriter. You have to do a carriage
# return at the end of a line. A real typewriter has a backspace
# key, tab key, etc., but this one doesn't because we can't simulate
# overstrikes on a terminal and we don't want to bother with coding
# stuff like tab settings.

# Additional features are not anticipated; they would not be in
# keeping with this bare minimalist approach. So no typing sounds,
# color changes, choice of fonts, etc. You can do some of that stuff
# by setting up a bash profile. Call it a 'typing' profile if you 
# want and put a command on your menu to call this program with that
# profile. Black type on a creamy white background and a fixed-width
# typewriter font would be in keeping with the theme.

# On Gnome, this works nicely with a profile called 'typing' which
# is set to use Dark Courier 16 point, black on white colors, 
# assuming 'bashwriter' in located in /usr/local/bin. Put this in a
# file, say 'typing' and copy 'typing' to /usr/local/bin or wherever.

# gnome-terminal --window-with-profile=typing --full-screen --hide-menubar -x /usr/local/bin/bashwriter $1

# Then 'typing filename' will give you what you want. Well, maybe.

# If you are foolish enough to think this script is any good, 
# consider the fact that another fellow wrote an excellent typewriter 
# simulator in about 20 lines of HTML. Now *that* is good!

# Comments, bugs, changes to: bashwriter@bobnewell.net
# Note that this is not a promise of performance.

# The script is Copyright (C) 2011 by Futrezo Software Systems, a division
# of Mr. Fred Investments. A free, unlimited, non-exclusive license
# to use the script in any legal manner is granted. You may use it,
# change it, create derivative works, sell it, give it away, or do
# anything you like as long as it is lawful, but you may not take
# ownership of the original script from us.

# No warranties are provided, nor is any form of liability accepted.
# No support is offered or provided.

# 2011/11/24 0.02 Thanksgiving Day release.
#                 Cleaned up a few things.
#                 Fixed up quoting of $tfile.
#                 Probably as 'final' as it's going to get.
#                 (Famous last words.)
# 2011/11/23 0.01 Bob Newell, Honolulu, Hawai`i. 
#                 Initial coding.

function fish {
# Program termination function, as in 'go fish'.
	IFS=$saveifs
	reset
	exit 0
}

version="0.02 of 24 Nov 2011"

saveifs=$IFS
IFS=""

# The size of the preserved text on the screen. This helps
# mimic typewriter-like scrolling up. Right now it's hardwired.
# It should really be based on the screen height but $LINES doesn't
# seem to work within a bash script.

tailsize=10

tfile=$1

echo "BASHWRITER typewriter simulator, version $version."

# Test for specification of file.
if [[ "$tfile" == "" ]]
then
	echo "No typewriter file specified."
	exit 1
fi

# Test existence of file. If not, try to create.
if [[ ! -f "$tfile" ]]
then
	touch "$tfile" 2>/dev/null
	if [[ $? -ne 0 ]]
	then
		echo "Cannot create typewriter file $tfile."
		exit 1
	fi
fi

# See if the file is writable.
if [[ ! -w "$tfile" ]]
then
	echo "Typewriter file $tfile cannot be opened for writing."
	exit 1
fi

# Clear screen and put initial lines up.
clear
tail -$tailsize "$tfile" 2>/dev/null

# Traps follow. 'fish' is a closeout routine which resets 
# the console, etc.

trap fish QUIT
trap fish INT
trap fish HUP
trap fish TSTP

C=""

# Remember: we have to ctrl-C out of the program.

while [[ 1 -eq 1 ]]; 
do

# Read one character at a time, no escape sequences, no screen echo.

	read -n 1 -s -r C
	if [[ $C != "" ]]
	then

# Process anything but carriage return, which comes through as "".
# Then test printable, ignore if not. This gets rid of backspace etc.
# If the char is usable, echo to the file and to the screen.
# This requires POSIX which any relatively recent Linux system will have.

		if [[ $C == [[:print:]] ]]
		then
			echo -n $C >>"$tfile"
			echo -n $C
		fi
	else

# Carriage return was evidently typed, triggering a scroll up.

		echo "" >>"$tfile"
		clear
		tail -$tailsize "$tfile"
	fi
done

############################# end bashwriter #########################