diff options
author | EuAndreh <eu@euandre.org> | 2025-04-30 17:17:39 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2025-04-30 17:17:39 -0300 |
commit | 40eb0452fd7689d1c40e4d53c1473fd42195cc49 (patch) | |
tree | f474c92f572c0fa2590e88e88d74b1a6c2767336 | |
parent | Import existing Perl code (diff) | |
download | eslaides-40eb0452fd7689d1c40e4d53c1473fd42195cc49.tar.gz eslaides-40eb0452fd7689d1c40e4d53c1473fd42195cc49.tar.xz |
src/eslaides: (Mostly) migrate to POSIX sh
Diffstat (limited to '')
-rwxr-xr-x | src/eslaides | 787 |
1 files changed, 336 insertions, 451 deletions
diff --git a/src/eslaides b/src/eslaides index d80977a..34b4e5e 100755 --- a/src/eslaides +++ b/src/eslaides @@ -1,413 +1,365 @@ -#!/usr/bin/env perl - -use v5.34; -use warnings; -use feature 'signatures'; -no warnings ('experimental::signatures'); -use Getopt::Std (); -use JSON (); - - -sub usage($fh) { - print $fh <<~'EOF' - Usage: - eslaides [-c CONFIG] [FILE] - eslaides -h - EOF -} - -sub help($fh) { - print $fh <<~'EOF' - - - Options: - -h, --help show this message - -c CONFIG use configuration from CONFIG - - - Emit PostScript slideshow file from input "*.slides" content. - If FILE is not given, get data from STDIN. - - - Examples: +#!/bin/sh +set -euo pipefail - Generate PostScript for "keynote.slides", using config - from "eslaides.json": - - $ eslaides -c eslaides.json keynote.slides > keynote.ps - - - Generate final PDF in a pipeline: - - $ eslaides kn.slides | ps2pdf - > kn.pdf - EOF -} - - -for (@ARGV) { - last if $_ eq '--'; - if ($_ eq '--help') { - usage *STDOUT; - help *STDOUT; - exit; - } -} -my %opts; -if (!Getopt::Std::getopts('c:h', \%opts)) { - usage *STDERR; - exit 2; +usage() { + cat <<-'EOF' + Usage: eslaides [-c CONFIG] [FILE] + EOF } -if ($opts{h}) { - usage *STDOUT; - help *STDOUT; - exit; -} +CONFIG= +while getopts 'c:' flag; do + case "$flag" in + (c) + CONFIG="$OPTARG" + ;; + (*) + usage >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) -sub load_json($fname) { - my $str = do { - open my $fh, $fname or die "Failed opening \"$fname\""; - local $/; - <$fh>; - }; - return %{JSON::decode_json($str)}; -} +## Defaults -my %DEFAULT_CONFIG = ( - 'fonts-reencoding' => 'ISOLatin1Encoding', +fonts_reencoding='ISOLatin1Encoding' +fonts_reencoding_list='Helvetica Times Times-Italic Courier' - 'header-height' => 75, - 'header-color' => '0 0 0', - 'background-color' => '1 1 1', - 'line-color' => '0 0 0', +header_height=75 +header_color='0 0 0' +background_color='1 1 1' +line_color='0 0 0' - 'frontpage-font-family' => 'Helvetica', - 'frontpage-font-size' => 60, - 'frontpage-font-color' => '0.5 0.5 0.9', +frontpage_font_family='Helvetica' +frontpage_font_size=60 +frontpage_font_color='0.5 0.5 0.9' - 'author-font-family' => 'Times-Italic', - 'author-font-size' => 40, - 'author-font-color' => '0 0 0', +author_font_family='Times-Italic' +author_font_size=40 +author_font_color='0 0 0' - 'title-font-family' => 'Helvetica', - 'title-font-size' => 40, - 'title-font-color' => '0.5 0.5 0.9', +title_font_family='Helvetica' +title_font_size=40 +title_font_color='0.5 0.5 0.9' - 'main-font-family' => 'Courier', - 'main-font-size' => 30, - 'main-font-color' => '0 0 0', +main_font_family='Courier' +main_font_size=30 +main_font_color='0 0 0' - 'code-font-family' => 'Courier', - 'code-font-size' => 18, - 'code-font-color' => '0 0 0', +code_font_family='Courier' +code_font_size=18 +code_font_color='0 0 0' - 'tiny-font-family' => 'Times', - 'tiny-font-size' => 18, - 'tiny-font-color' => '0 0 0', -); +tiny_font_family='Times' +tiny_font_size=18 +tiny_font_color='0 0 0' -my %c = ( - %DEFAULT_CONFIG, - $opts{c} ? load_json($opts{c}) : (), -); +if [ -n "$CONFIG" ]; then + . ./"$CONFIG" +fi -sub preamble() { - my %fonts = (); - for (keys %c) { - next if !/.*-font-family$/; - $fonts{$c{$_}} = 1; - } - my $fonts_reencoding = ''; - $fonts_reencoding .= "/$_ /$_ reencode\n" for (keys %fonts); - - print <<~EOF; - %!PS-Adobe-3.0 - %%DocumentMedia: SLIDE 842 595 0 () () - %%EndComments - %%BeginDefaults - %%PageMedia: SLIDE - %%EndDefaults - << /PageSize [842 595] /ImagingBBox null >> setpagedevice - - /reencode { - exch - findfont - dup length dict - begin - { - 1 index /FID ne - { def } - { pop pop } - ifelse - } forall - /Encoding $c{'fonts-reencoding'} def - currentdict - end - definefont pop - } def - $fonts_reencoding - - /headerheight $c{'header-height'} def - - /frontfontsz $c{'frontpage-font-size'} def - /authorfontsz $c{'author-font-size'} def - /titlefontsz $c{'title-font-size'} def - /mainfontsz $c{'main-font-size'} def - /codefontsz $c{'code-font-size'} def - /tinyfontsz $c{'tiny-font-size'} def - - /titlefont /$c{'title-font-family'} findfont titlefontsz scalefont def - /mainfont /$c{'main-font-family'} findfont mainfontsz scalefont def - /codefont /$c{'code-font-family'} findfont codefontsz scalefont def - /tinyfont /$c{'tiny-font-family'} findfont tinyfontsz scalefont def - /frontfont /$c{'frontpage-font-family'} findfont frontfontsz scalefont def - /authorfont /$c{'author-font-family'} findfont authorfontsz scalefont def - /authorfonttwo /Times findfont authorfontsz scalefont def - - - /pagewidth 842 def - /pageheight 595 def - /leftmargin 30 def - /topmargin 595 def - - /pad 10 def - - /titlefonth titlefontsz pad add def - /mainfonth mainfontsz pad add def - /codefonth codefontsz pad add def - /tinyfonth tinyfontsz pad add def - /frontfonth frontfontsz pad add def - /authorfonth authorfontsz pad add def - - /headermargin - pageheight headerheight titlefonth sub 2 div titlefontsz add sub - def - /rightmargin pagewidth leftmargin sub def - /tbtop topmargin def - /ypos topmargin def - - /xcur { currentpoint pop } def - /ycur { currentpoint exch pop } def - - /wordbreak ( ) def - /linewrap { - /proc exch def - /linelength exch def - /textstring exch def - /breakwidth wordbreak stringwidth pop def - /curwidth 0 def - /lastwordbreak 0 def - /startchar 0 def - /restoftext textstring def - { - restoftext wordbreak search - { - /nextword exch def pop - /restoftext exch def - /wordwidth nextword stringwidth pop def - curwidth wordwidth add linelength gt - { - textstring startchar - lastwordbreak startchar sub - getinterval proc - /startchar lastwordbreak def - /curwidth wordwidth breakwidth add def - } - { - /curwidth curwidth wordwidth add - breakwidth add def - } ifelse - /lastwordbreak lastwordbreak - nextword length add 1 add def - } - { - pop exit - } ifelse - } loop - /lastchar textstring length def - textstring startchar lastchar startchar sub - getinterval proc - } def - - /line { - $c{'line-color'} setrgbcolor - 0.5 setlinewidth - leftmargin ypos moveto - rightmargin ypos lineto - stroke - } def - - /center { - dup - /str exch def - /sw str stringwidth pop def - /xpos pagewidth sw sub 2 div xcur sub def - xpos 0 rmoveto - } def - - /objcenter { - pagewidth exch sub 2 div 0 translate - } def - - /s { - /tbtop topmargin def - /ypos topmargin def - $c{'background-color'} setrgbcolor - 0 setlinewidth - newpath - 0 pageheight moveto - pagewidth pageheight lineto - pagewidth 0 lineto - 0 0 lineto - closepath - fill - stroke - } def - - /l { - /h exch def - /ypos ypos h sub def - leftmargin ypos moveto - } def - - /title { - frontfonth l - frontfont setfont - $c{'frontpage-font-color'} setrgbcolor - { pagewidth leftmargin 2 mul sub } - { frontfonth l center show } - linewrap - frontfonth 2 div l - frontfonth l - } def - - /author { - authorfont setfont - $c{'author-font-color'} setrgbcolor - { pagewidth leftmargin 2 mul sub } - { authorfonth l center show } - linewrap - } def - - /authortwo { - authorfonttwo setfont - $c{'author-font-color'} setrgbcolor - { pagewidth leftmargin 2 mul sub } - { authorfonth l center show } - linewrap - } def - - /header { - /ypos pageheight headerheight sub def - $c{'header-color'} setrgbcolor - 0 setlinewidth - newpath - 0 pageheight moveto - pagewidth pageheight lineto - pagewidth ypos lineto - 0 ypos lineto - closepath - fill - stroke - leftmargin headermargin moveto - titlefont setfont - $c{'title-font-color'} setrgbcolor - center show - leftmargin ypos moveto - } def - - /n { - mainfont setfont - $c{'main-font-color'} setrgbcolor - { pagewidth leftmargin 2 mul sub } - { mainfonth l show } - linewrap - } def - - /cn { - codefont setfont - $c{'code-font-color'} setrgbcolor - { pagewidth leftmargin 2 mul sub } - { codefonth l show } - linewrap - } def - - /tn { - tinyfont setfont - $c{'tiny-font-color'} setrgbcolor - { pagewidth leftmargin 2 mul sub } - { tinyfonth l show } - linewrap - } def - - /is { - /level1 save def - /showpage {} def - } def - - /ie { - level1 restore - } def - - /bs { - /tbtop ypos def - } def - - /be { - /tm tbtop pad sub def - /bm ypos pad sub def - newpath - leftmargin 10 sub tm moveto - rightmargin tm lineto - rightmargin bm lineto - leftmargin 10 sub bm lineto - closepath - $c{'line-color'} setrgbcolor - 0.5 setlinewidth - stroke - } def - EOF -} -sub postamble() { - print <<~'EOF'; +postamble() { + cat <<-'EOF' showpage %%EOF - EOF + EOF } -sub img($fname) { - if (!($fname=~/\.ps$/)) { - print STDERR `convert '$fname' '$fname.ps'`; - die if $?; - $fname = $fname . '.ps'; - } - open (my $fh, "<", $fname) or die "Cannot open image file \"$fname\""; - print "is\n"; - my $s; - for ($s=""; <$fh>; $s.=$_) { - if ($_=~/%%BoundingBox: -?\d+ -?\d+ (-?\d+) -?\d+/) { - print "$1 objcenter\n"; - last; +preamble() { + doreencoding= + for f in $fonts_reencoding_list; do + doreencoding="$doreencoding +/$f /$f reencode" + done + cat <<EOF +%!PS-Adobe-3.0 +%%DocumentMedia: SLIDE 842 595 0 () () +%%EndComments +%%BeginDefaults +%%PageMedia: SLIDE +%%EndDefaults +<< /PageSize [842 595] /ImagingBBox null >> setpagedevice + +/reencode { + exch + findfont + dup length dict + begin + { + 1 index /FID ne + { def } + { pop pop } + ifelse + } forall + /Encoding $fonts_reencoding def + currentdict + end + definefont pop +} def + +$doreencoding + + +/headerheight $header_height def + +/frontfontsz $frontpage_font_size def +/authorfontsz $author_font_size def +/titlefontsz $title_font_size def +/mainfontsz $main_font_size def +/codefontsz $code_font_size def +/tinyfontsz $tiny_font_size def + +/titlefont /$title_font_family findfont titlefontsz scalefont def +/mainfont /$main_font_family findfont mainfontsz scalefont def +/codefont /$code_font_family findfont codefontsz scalefont def +/tinyfont /$tiny_font_family findfont tinyfontsz scalefont def +/frontfont /$frontpage_font_family findfont frontfontsz scalefont def +/authorfont /$author_font_family findfont authorfontsz scalefont def +/authorfonttwo /Times findfont authorfontsz scalefont def + + +/pagewidth 842 def +/pageheight 595 def +/leftmargin 30 def +/topmargin 595 def + +/pad 10 def + +/titlefonth titlefontsz pad add def +/mainfonth mainfontsz pad add def +/codefonth codefontsz pad add def +/tinyfonth tinyfontsz pad add def +/frontfonth frontfontsz pad add def +/authorfonth authorfontsz pad add def + +/headermargin + pageheight headerheight titlefonth sub 2 div titlefontsz add sub +def +/rightmargin pagewidth leftmargin sub def +/tbtop topmargin def +/ypos topmargin def + +/xcur { currentpoint pop } def +/ycur { currentpoint exch pop } def + +/wordbreak ( ) def +/linewrap { + /proc exch def + /linelength exch def + /textstring exch def + /breakwidth wordbreak stringwidth pop def + /curwidth 0 def + /lastwordbreak 0 def + /startchar 0 def + /restoftext textstring def + { + restoftext wordbreak search + { + /nextword exch def pop + /restoftext exch def + /wordwidth nextword stringwidth pop def + curwidth wordwidth add linelength gt + { + textstring startchar + lastwordbreak startchar sub + getinterval proc + /startchar lastwordbreak def + /curwidth wordwidth breakwidth add def + } + { + /curwidth curwidth wordwidth add + breakwidth add def + } ifelse + /lastwordbreak lastwordbreak + nextword length add 1 add def } - } - print "%%BeginDocument: $fname\n$s",<$fh>,"\n\n%%EndDocument\nie\n"; - close $fh; + { + pop exit + } ifelse + } loop + /lastchar textstring length def + textstring startchar lastchar startchar sub + getinterval proc +} def + +/line { + $line_color setrgbcolor + 0.5 setlinewidth + leftmargin ypos moveto + rightmargin ypos lineto + stroke +} def + +/center { + dup + /str exch def + /sw str stringwidth pop def + /xpos pagewidth sw sub 2 div xcur sub def + xpos 0 rmoveto +} def + +/objcenter { + pagewidth exch sub 2 div 0 translate +} def + +/s { + /tbtop topmargin def + /ypos topmargin def + $background_color setrgbcolor + 0 setlinewidth + newpath + 0 pageheight moveto + pagewidth pageheight lineto + pagewidth 0 lineto + 0 0 lineto + closepath + fill + stroke +} def + +/l { + /h exch def + /ypos ypos h sub def + leftmargin ypos moveto +} def + +/title { + frontfonth l + frontfont setfont + $frontpage_font_color setrgbcolor + { pagewidth leftmargin 2 mul sub } + { frontfonth l center show } + linewrap + frontfonth 2 div l + frontfonth l +} def + +/author { + authorfont setfont + $author_font_color setrgbcolor + { pagewidth leftmargin 2 mul sub } + { authorfonth l center show } + linewrap +} def + +/authortwo { + authorfonttwo setfont + $author_font_color setrgbcolor + { pagewidth leftmargin 2 mul sub } + { authorfonth l center show } + linewrap +} def + +/header { + /ypos pageheight headerheight sub def + $header_color setrgbcolor + 0 setlinewidth + newpath + 0 pageheight moveto + pagewidth pageheight lineto + pagewidth ypos lineto + 0 ypos lineto + closepath + fill + stroke + leftmargin headermargin moveto + titlefont setfont + $title_font_color setrgbcolor + center show + leftmargin ypos moveto +} def + +/n { + mainfont setfont + $main_font_color setrgbcolor + { pagewidth leftmargin 2 mul sub } + { mainfonth l show } + linewrap +} def + +/cn { + codefont setfont + $code_font_color setrgbcolor + { pagewidth leftmargin 2 mul sub } + { codefonth l show } + linewrap +} def + +/tn { + tinyfont setfont + $tiny_font_color setrgbcolor + { pagewidth leftmargin 2 mul sub } + { tinyfonth l show } + linewrap +} def + +/is { + /level1 save def + /showpage {} def +} def + +/ie { + level1 restore +} def + +/bs { + /tbtop ypos def +} def + +/be { + /tm tbtop pad sub def + /bm ypos pad sub def + newpath + leftmargin 10 sub tm moveto + rightmargin tm lineto + rightmargin bm lineto + leftmargin 10 sub bm lineto + closepath + $line_color setrgbcolor + 0.5 setlinewidth + stroke +} def +EOF } +emitline() { + sed -e 's|(|\\(|g' -e 's|)|\\)|g' | + awk ' + BEGIN { + pages = 1 + code = 0 + } + + /^$/ { next } + /^%/ { next } + + /^\.$/ { printf "() n\n"; next } + /^# / { printf "(%s) title\n", substr($0, 3); next } + /^## / { printf "(%s) header\n", substr($0, 4); next } + /^@/ { printf "(%s) authortwo\n", substr($0, 2); next } + /^_/ { printf "(%s) tn\n", substr($0, 2); next } + + /^---$/ { + printf "showpage\n" + printf "%%%%Page: %s %s\n", pages, pages + printf "s\n" + pages++ + next + } -my $pages = 1; -my $code = 0; -my $bgimg = ""; + { printf "(%s) n\n", $0 } + ' -sub emit_line { + cat <<-'FIXME' > /dev/null s/[\r\n]+//g; s/([^^])\\/$1\\\\/g; s/(\(|\))/\\$1/g; @@ -415,20 +367,7 @@ sub emit_line { print "be\n"; $code = 0; }; - - /^%/ && return; - /^$/ && return; - - /^---$/ && do { - print "showpage\n"; - print "%%Page: $pages $pages\n"; - print "s\n"; - if ($bgimg ne "") { - img $bgimg; - } - $pages++; - return; - }; + bgimg = "" /^\t(.*)/ && do { if (!$code) { print "bs\n"; @@ -437,65 +376,11 @@ sub emit_line { print "($1) cn\n"; return; }; - /^#([^#].*)$/ && do { - print "($1) title\n"; - return; - }; - /^##(.*)/ && do { - print "($1) header\n"; - return; - }; - /^\.+$/ && do { - print "() n\n" x length; - return; - }; - /^@([^@].*)/ && do { - print "($1) authortwo\n"; - return; - }; - /^@@(.*)/ && do { - print "($1) author\n"; - return; - }; - /^\[(.*)\]/ && do { - img $1; - return; - }; - /^\{(.*)\}/ && do { - $bgimg = $1; - return; - }; - /^_(.*)/ && do { - print "($1) tn\n"; - return; - }; s/^\\//; print "($_) n\n"; + FIXME } - -sub main() { - preamble; - emit_line while (<>); - postamble; -} - -main; - - -__END__ - -=head1 eslaides - -eslaides - generate PostScript slideshows from input "*.slides" text files - -=head1 SYNOPSYS - -eslaides [FILE] - -eslaides -h - -=cut - -# FIXME: Verdana not working -# FIXME: authorfonttwo +preamble +cat "${1:--}" | emitline +postamble |