Simple Word Processing With Enscript
The Software
$EDITOR
enscript
a postscript viewer
pr (only to help with tabular data)
A list of the software sources and example files can be
found at the end of this page.
Introduction
Enscript will convert plain text files into PS
(PostScript) or other formats, such as HTML and RTF, and
can also send files directly to a printer. It is much
more advanced than plain lpr or lp, and also supports
special filters for highlighting source code.
It is useful for printing letters, or technical files, and
supports using mixed fonts, such as italic and bold fonts
for emphasis.
You may find it best to use real tabs in documents, set to
a small tabstop, rather than spaces. This makes it a bit
easier to align things like addresses to the right margin
without them wrapping off the edge to the next line. In
vim you would need to `set noexpandtab'.
Note: I've cut some long lines with a `\' for readability.
Method
The steps in enscript printing:
1. Edit a plain text file
2. Use enscript with `-o file.ps' to format and output text to PS
3. Preview output in a PostScript viewer
4. Repeat 1-3 until satisfied with the output
5. Repeat the enscript command omitting the `-o file.ps'
The last command will send the PS output to the printer.
The output can rival that of any GUI word processor. The
source documents are plain text, so they will be much
easier to use normal file operations like `grep' and
`find' etc. on.
Print Previewing
Any PostScript viewer will do.
Viewers for the framebuffer console:
fimgs/fim
fbgs/fbi
For X Windows:
gv
evince
(probably others)
Fim is `fbi improved'. The strange diagonal scrolling
that sometimes occurs in fbgs/fbi has been fixed. It also
supports scripting and a lot of customisation. When
viewing a file with fimgs, it is converted to png images
in a temporary directory using `ghostscript', and the
images are viewed in `fim'. The `fimgs' application
itself is a shell script.
Options
I won't go into all of enscript's options here - the
manual is very detailed. But here are a few of the most
common and useful options for word processing.
General Options
-e[char], --escapes[=char]
Allow escape codes. This allows us to set italic or
bold fonts, among other things. Vim refuses to add a
^@ via a key map, but ^_ (-e\037) works fine.
Default: ^@
-f font, --font=name
Main body font name and size.
Default: Courier10 or Courier7
-i num, --indent=num
Indent each line by num units of c (centimeters),
i (inches), l (characters), or p (PS points.)
Default: l
-M name, --media=name
Media - e.g. A4, letter etc.
Default: letter
--margins=left:right:top:bottom
Margins in PS points (usually 72 DPI.)
Default: none.
-o file, -p file, --output=file
Output to file.
Default: send to printer
-P name, --printer=name
Printer name to use. When adding printers in CUPS
it's helpful to use short, simple names to avoid too
much typing here - e.g. "Photosmart" or "BJ200".
Default: default printer.
-T num, --tabsize=num
Tabsize to use.
Default: 8
-w lang, --language=lang
Output language:
PostScript, HTML, OverStrike (for line printers and
`less'), RTF, ANSI (ANSI terminal control codes.)
Default: PostScript
--word-wrap
-X enc, --encoding=enc
Input encoding. The manual has a long list.
Default: latin1/88591.
-B, --no-header
Do not print page headers.
Options that may be useful for technical documents or source code:
-G, --fancy-header[=name]
Print a fancy header (very customisable)
-F name, --header-font=name
Font for headers.
-C[start_line], --line-numbers[=start_line]
-E[lang], --highlight[=lang]
Source code highlighter.
List of highlight filters included with enscript
1.6.6:
ada asm awk bash c changelog cpp csh delphi diff diffs
diffu elisp f90 fortran fortran_pp haskell html idl
inf java javascript ksh m4 mail makefile matlab nroff
objc outline pascal perl postscript pyrex python rfc
scheme sh skill sql states synopsys tcl tcsh tex vba
verilog vhdl vrml wmlscript zsh
-b header_string, --header=header_string
Use text string as header. Can use %Format escapes
described in the manual. E.G.:
enscript --header='$n %W Page $% of $=' *.c
--color[=bool]
--footer=footer_string
Similar to --header.
You can also add the most used settings to ~/.enscriptrc.
Aliasing Commands
That's a fair number of options to remember, but we can
use aliases to save typing and to avoid making typos.
Proportional font, suitable for most correspondence:
alias ep='enscript -e\037 -BM A4 --word-wrap -fTimes-Roman12 \
--margins=50:50:50:50 -T2'
Fixed-width font with a fancy header, suitable for source:
alias ep-mono='enscript -e\037 -GM A4 --word-wrap -fCourier12 \
--margins=50:50:50:50 -FCourier12 -T2'
Now all we need to do is `ep letter1.txt -o out.ps', but
see the vim key mappings below. Extra options can be added
to aliases on-the-fly.
Encodings
Enscript doesn't support UTF-8, so one of the supported
ISO-8859 or other encodings will need to be used.
This means we need to find a workaround for some
characters like UTF-8 bullets, and e.g. use something like
a `middle dot' instead.
Supported encodings from the man page:
88591, latin1 ISO-8859-1 (ISO Latin1) (enscript's default
encoding).
88592, latin2 ISO-8859-2 (ISO Latin2)
88593, latin3 ISO-8859-3 (ISO Latin3)
88594, latin4 ISO-8859-4 (ISO Latin4)
88595, cyrillic ISO-8859-5 (ISO Cyrillic)
88597, greek ISO-8859-7 (ISO Greek)
88599, latin5 ISO-8859-9 (ISO Latin5)
885910, latin6 ISO-8859-10 (ISO Latin6)
ascii 7-bit ascii
asciifise, asciifi, asciise 7-bit ascii with some
scandinavian (Finland, Sweden) extensions
asciidkno, asciidk, asciino 7-bit ascii with some
scandinavian (Denmark, Norway) extensions
ibmpc, pc, dos IBM PC charset
mac Mac charset
vms VMS multinational charset
hp8 HP Roman-8 charset
koi8 Adobe Standard Cyrillic Font KOI8 charset
ps, PS PostScript font's default encoding
pslatin1, ISOLatin1Encoding
PostScript interpreter's `ISOLatin1Encoding'
There is an application called `paps' that does a similar
task to enscript and supports UTF-8, however it doesn't
seem to support changing fonts within documents, nor any
of the advanced features of enscript. It would be useful
to create similar aliases or editor binds as I use here
with it, if a need for UTF-8 support arises.
Editing
The key is a good editor. Make sure that it can edit
plain text and has the ability to enter control/escape
codes. I use vim pretty much all the time so I've
included some of the settings and binds I use. I have
briefly used emacs, but wouldn't know how to do the same
in that.
We can get a good idea of the end result when previewing
by limiting the columns in vim to something roughly
corresponding to the hard copy. You need to adjust by
trial and error until it looks right. It helps to not
break lines, so we use `textwidth=0' and `linebreak',
which displays long lines as wrapped, but doesn't insert
newline characters:
" Stop lines breaking and limit the terminal width to 68
" characters.
set columns=68
set textwidth=0
set linebreak
set nolist
" No line numbering and small tab stops
set nonumber
set tabstop=2
set softtabstop=2
set shiftwidth=2
" Spell-checking:
hi SpellBad ctermfg=red cterm=Bold
setlocal spell
Using Emphasis
Escape codes in enscript begin with a `NUL', which are a
`^@' (literal Ctrl-@) in vim, or `\0' in C, a zero byte.
In vim this is done by pressing Ctrl-v in insert mode,
then pressing Ctrl-@. However, it seems that these can't
be entered automatically, e.g. via a keymap, as they get
transposed to newlines, but we can change `^@' to
something else and use enscript's `-e' flag to use that
instead.
The man page has a list of escape format codes near the
end, (see `man enscript | less -p "^SPECIAL ESCAPES"'),
and can also inject PostScript code. But we are most
interested in the code to change the font. The syntax is
`^@font{NEWFONTNAME}'.
To use an italic or bold font we simply have to switch to
that font before the word(s) we want emphasised, and then
switch back to the default font afterwards. E.G.:
This is ^@font{Times-Italic12}italic^@font{default} text.
(NOTE: These commands and binds may not display correctly
in my gopherhole yet. Compare with the real text.vim
linked below.)
We can make some helper mappings in vim to save typing:
" normal/command mode font maps
nmap <buffer> ,ii i^_font{Times-Italic12}<Esc>ea^_font{default}<Esc>
nmap <buffer> ,bb i^_font{Times-Bold12}<Esc>ea^_font{default}<Esc>
nmap <buffer> ,bi i^_font{Times-BoldItalic12}<Esc>ea^_font{default}<Esc>
nmap <buffer> ,cc i^_font{Courier11}<Esc>ea^_font{default}<Esc>
" visual select mode font maps
vmap <buffer> ,ii <Esc>`>a^_font{default}<Esc>`<i^_font{Times-Italic12}<Esc>
vmap <buffer> ,bb <Esc>`>a^_font{default}<Esc>`<i^_font{Times-Bold12}<Esc>
vmap <buffer> ,bi <Esc>`>a^_font{default}<Esc>`<i^_font{Times-BoldItalic12}<Esc>
vmap <buffer> ,cc <Esc>`>a^_font{default}<Esc>`<i^_font{Courier11}<Esc>
For the nmap maps, place the cursor on the first letter of
a word, press comma followed by `bb' for bold, or `ii' for
italic etc. The vmap visual mode maps work by selecting
text in visual mode and then using the same comma key
combinations.
Some maps not really connected with enscript, but might be
useful, that quote words or selected text with backticks
and single quotes:
nmap <buffer> ,`` i`<Esc>ea'<Esc>
vmap <buffer> ,`` <Esc>`>a'<Esc>`<i`<Esc>
" Insert dates
nmap ,dd "=strftime("%A, %-d %B %Y")<CR>p
" Output: Saturday, 4 January 2020
nmap ,du "=strftime("%a %_d %b %T UTC %Y")<CR>p
" Output: Sat 4 Jan 17:28:31 UTC 2020
nmap ,dt "=strftime("%a %-d %b %T %Z %Y")<CR>p
" Output: Sat 4 Jan 17:28:31 GMT 2020
This will insert a tab and a round bullet at the start of
the current line:
nmap <buffer> ,tt I<Tab>·<Tab><Esc>
Since enscript doesn't support the UTF-8 bullet symbols,
this is actually a `middle dot' from ISO-8559-1. It may
look like a small dot in the terminal, but it's much
larger when rendered in PostScript or printed out:
char dec col/row oct hex description
[·] 183 11/07 267 B7 MIDDLE DOT
More here:
http://www.columbia.edu/kermit/latin1.html and
http://www.columbia.edu/kermit/latin9.html
and a good reference and list:
https://en.wikipedia.org/wiki/ISO/IEC_8859
Map <leader> + <Tab> to `make' enscript:
nmap <buffer> <leader><tab> :silent make!<CR>
Either `makeprg' or `&mp' need to be set for `make' to
work:
let &mp = 'enscript -e\037 -MA4 --word-wrap --margins=50:50:50:50 \
-T4 -o %:r.ps; fimgs -r 240 %:r.ps'
The above sets the output file name to the same as the
edited text file name, but changes the extension to .ps,
and then loads the file in fimgs. The -r 240 flag is a
resolution.
Vim settings in an Autogroup
An example autogroup that sets up a make command and binds for
italic and bold. It's easier to add these commands to a
~/.vim/after/ftplugin/text.vim though, which I've linked to
below.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
augroup text
au!
autocmd BufRead *txt
\ let &mp = 'enscript -e\037 -DCollate -MA4 --word-wrap \
--margins=50:50:50:50 -T4 -o %:r.ps' |
\ nnoremap <leader><tab> :silent make!<CR> |
\ nnoremap ,ii :normal i^_font{Times-Italic12}<Esc>ea^_font{default}<Esc> |
\ nnoremap ,bb :normal i^_font{Times-Bold12}<Esc>ea^_font{default}<Esc> |
\ nnoremap ^[[34~ :call Print()<CR>
" The next lines can change the terminal column width if
" needed.
" autocmd ShellCmdPost *txt exec "!stty cols 103"
" if exists("##ExitPre")
" autocmd ExitPre *txt "!stty cols 114"
" endif
augroup END
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
A Template Script
Templates always makes writing easier, so here's an idea for
a script that copies a template, adds the date, and then
starts $EDITOR on it:
############################################################
#!/bin/sh
set -e
TEMP="$HOME/letters/templates/letter-template.txt"
LETTERDATE=$(date +"%A, %d %B %Y")
DATE=$(date +%Y-%m-%d-%S)
FNAME="$1-$DATE.txt"
cp -iv "$TEMP" "$FNAME"
sed -i "s#@DATE@#$LETTERDATE#g" "$FNAME"
$EDITOR "$FNAME"
############################################################
This takes the first argument to use as a prefix for the
file name and adds the date: prefix-YYYY-MM-DD-SS.txt
Fill the template with your name and address and
put @DATE@ where the date would normally go.
Headers
There are a few example header files that come with
enscript. They are written in the PostScript language.
Here is a simple example:
% -- code follows this line --
%HeaderHeight: 50
%Format: pagenumstr Re: Appointment on 19/12/2019, J Smith, ($%/$=)
/do_header { % print the header
gsave
d_header_x d_header_y translate
0 20 moveto
0.2 setgray
pagenumstr show
grestore
} def
To try it, copy the file to ~/.enscript/, use the -G
flag (instead of -B), or --fancy-header=standard-letter,
or add the following to ~/.enscriptrc:
DefaultFancyHeader: standard-letter
This will print:
Re: Appointment on 19/12/2019, J Smith, (1/4)
At the top of each page, where the numbers in parentheses
are page number/total pages, although the --header flag
can do simple headers like this inline. There are example
header files in /usr/share/enscript/ that show how to go
further, like add horizontal rules etc.
Tabular Data With PR
pr can paginate and columnise text, which can then be
piped to enscript, lp/lpr, or redirected to a new file.
A Few of The Options
-COLUMNS
Number of columns
-a, --across
Print across, then down
-l lines, --length=lines
Page length
Default: 66
-o margin, --indent=MARGIN
Number of characters to use for margin
Default: 0
-w width, --width=WIDTH
Width of page in characters
Default: 72
Data is entered in a single column, which pr will
columnise. E.G.:
% cat cols.txt:
one
two
three
four
five
six
% pr -a -3 -l 15 -w 35 cols.txt
Output:
2019-03-03 12:47 cols.txt Page 1
one two three
four five six
Software List:
You may have some or all of these available in your distro's
software repo.
enscript homepage:
https://www.gnu.org/software/enscript
fim (fbi improved) homepage:
http://www.nongnu.org/fbi-improved/
fbida (the original fbi) homepage:
https://www.kraxel.org/blog/linux/fbida/
ghostscript homepage:
https://ghostscript.com/
gv homepages?:
http://pages.cs.wisc.edu/~ghost/gv/gv.htm
https://sourceforge.net/projects/gnu-gv/
paps homepage:
https://github.com/dov/paps
pr is part of gnucore Utils:
https://www.gnu.org/software/coreutils/manual/html_node/pr-invocation.html
File List:
2022-05-27 04:37:42+01:00
|