diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/stex/bin |
Initial commit
Diffstat (limited to 'macros/latex/contrib/stex/bin')
-rw-r--r-- | macros/latex/contrib/stex/bin/Modparse.pm | 189 | ||||
-rw-r--r-- | macros/latex/contrib/stex/bin/README | 50 | ||||
-rwxr-xr-x | macros/latex/contrib/stex/bin/checksum | 71 | ||||
-rwxr-xr-x | macros/latex/contrib/stex/bin/filedate | 45 | ||||
-rwxr-xr-x | macros/latex/contrib/stex/bin/installFonts.sh | 8 | ||||
-rwxr-xr-x | macros/latex/contrib/stex/bin/sms | 146 |
6 files changed, 509 insertions, 0 deletions
diff --git a/macros/latex/contrib/stex/bin/Modparse.pm b/macros/latex/contrib/stex/bin/Modparse.pm new file mode 100644 index 0000000000..2fd732b063 --- /dev/null +++ b/macros/latex/contrib/stex/bin/Modparse.pm @@ -0,0 +1,189 @@ +####################################################################################### +# A module for loading .tex files and feeding the data to the various applications. # +# Copyright (c) 2005, Ioan Sucan, released under the Gnu General Public License (GPL) # +# see http://www.gnu.org/copyleft/gpl.html # +# $URL: svn://kwarc.eecs.iu-bremen.de/repos/kwarc/projects/content/bin/Modparse.pm$ # +# $Date: 2005-09-26 12:44:28 -0500 (Mon, 26 Sep 2005) $ $Rev: 4243 $ # +####################################################################################### + +package Modparse; + +use File::Basename; +use File::Path; + +# if both snippath and snippathList are specified, +# snippathList is ignored ! + +# if a default snippath definition file is found +# (snippath.def) it is used if no snippath is given +# as argument; +sub new { + my ($class, %options) = @_; + + $options{recursion} = 1 unless defined $options{recursion}; + $options{requireStatus} = 'include|exclude' unless defined $options{requireStatus}; + $options{loadInputs} = 1 unless defined $options{loadInputs}; + $options{onlyModuleLines} = 0 unless defined $options{onlyModuleLines}; + + if ( !(%{$options{snippath}}) && (-e "snippath.def") ) { + open(SNIPPATHDEF, 'snippath.def'); + my @snlist = <SNIPPATHDEF>; + close(SNIPPATHDEF); + for (my $i = 0 ; $i <= $#snlist; $i++) { chomp($snlist[$i]); } + %{$options{snippath}} = @snlist; } + @{$options{snippathList}} = keys(%{$options{snippath}}) + if ($options{snippath} && %{$options{snippath}}); + $options{debug} = 0; + + bless(\%options, $class); } + +sub execute{ + my ($self, $file) = @_; + + local *run_event = sub { + my ($event, $arg) = @_; + if ($self->{$event}) { $self->{$event}($arg); } + }; + + local *go = sub { + my ($location, %param) = @_; + my ($tex, $path, @tex_data) = $self->readLocation($location); + return unless @tex_data; + my $NL = $#tex_data+1; + + $param{filename} = $tex; + $param{depth}++; + $param{filecount}++; + my $i = 0; + + $param{nextline} = sub { $tex_data[++$i]; }; + $param{prevline} = sub { $tex_data[--$i]; }; + $param{rewriteline}= sub { $tex_data[$i] = $_[0]; }; + + print "Processing $tex...\n" if $self->{verbose}; + run_event('onBeginFile', \%param); + + while ($i<$NL){ + $param{original} = $tex_data[$i]; + $_ = $tex_data[$i]; chomp; /([^%]*)((%.*)?)/; + ($param{tex}, $param{comment}) = ($1, $2); $_ = $1; + s/\s+//g; $param{simple_tex} = $_; + + if (/\\begin\{module\}(\[([^\]]*)\])?/) { + if ($param{in_module}) { + push(@{$param{module_stack}}, [$param{module_id}, $param{module_arg}]); } + $param{in_module} = 1; + $param{module_args} = $1 ? $2 : undef; + $param{module_id} = ($param{module_args} && + $param{module_args} =~ /id=([^\],]+)/) ? $1 : undef; + $param{module_nesting}++; + run_event('onBeginModule', \%param); } + + if (/\\end\{module\}/) { + run_event('onEndModule', \%param); + if ($#{$param{module_stack}} >= 0) { + ($param{module_id}, $param{module_args}) = @{pop(@{$param{module_stack}})}; + } else { + $param{in_module} = 0; + ($param{module_id}, $param{module_args}) = (undef, undef); } + $param{module_nesting}--; + } + + foreach my $srch_snippath(@{$self->{snippathList}}){ + $self->{snippath}{$srch_snippath} = $1 + if (/\\def\\$srch_snippath\#1\{([^\#]+)\#1\}$/); } + + if ($self->{follow} && (/\\((requiremodules(\[($self->{requireStatus})\])?)|input|include)\{([^\}]+)\}/)){ + my $req_filename = $5; my $req_spath = ''; my $command = $1; + my $is_require = ($command =~ /requiremodules/) ? 1 : 0; + if ($is_require || $self->{loadInputs}) { + foreach my $srch_snippath(@{$self->{snippathList}}){ + if ($req_filename =~ /\\$srch_snippath\{(.+)/){ + ($req_spath, $req_filename) = ($self->{snippath}{$srch_snippath}, $1); + last; }} + run_event('onRecurse', \%param); + if ($self->{recursion} || !$is_require) { + go($self->makeLocation($req_filename, $path, $req_spath), %param); } + } + } + run_event('onEveryLine', \%param) if ($param{in_module} || !$self->{onlyModuleLines}); + + last if (/\\end\{document\}/ && $self->{stopAtEnd}); + $i++; + } + run_event('onEndFile', \%param); + $param{depth}--; return; + }; + + my %param = (pack=>$self, perm=>$self->{_AUX_DATA}, depth=>0, filecount=>0, + in_module=>0, module_nesting=>0); + run_event('onBegin', \%param); + go($self->makeLocation($file), %param); + run_event('onEnd', \%param); + return; +} + + +# add a [.tex] extension to the filename +sub add_ext{ + my ($self, $fn, $ext) = @_; + $ext = '.tex' unless $ext; + $fn.=$ext if $fn !~ /\Q$ext\E$/; + $fn; } + +# as long as the extension is .tex, drop it +sub drop_ext{ + my ($self, $filename) = @_; + while ($filename =~ /\.tex$/){ + while ($filename !~ /\.$/ ) { chop($filename); } + chop($filename); } + $filename; } + +sub new_ext{ + my ($self, $filename, $ext) = @_; + $self->add_ext($self->drop_ext($filename), $ext); } + +# location = pointer to array of strings +# first element is filename; next are possible paths +sub makeLocation{ my $self = shift; return \@_; } + +# read a location into an array of strings +# aslo return filename and path to it (just in +# case some changes were made to it, like adding +# extension and/or relative paths) +sub readLocation{ + my ($self, $location) = @_; + + my ($filename, @paths) = @{$location}; + # try to add proper extension; + my $filename_ext = $self->new_ext($filename) unless -e $filename; + $filename = $filename_ext if $filename_ext && -e $filename_ext; + + # try search paths + if (! -e $filename){ + my $all_p = ''; + foreach my $p(@paths){ + $all_p .= $p; + $filename = $all_p.$filename and last if -e $all_p.$filename; + $filename = $p.$filename and last if -e $p.$filename; + if ($filename_ext){ + $filename = $all_p.$filename_ext and last if -e $all_p.$filename_ext; + $filename = $p.$filename_ext and last if -e $p.$filename_ext; } + }} + # don't do the same work too many times + foreach my $file(@{$self->{loadedFiles}}) + { return undef if $file eq $filename; } + + push(@{$self->{loadedFiles}}, $filename); + open(FIN, $filename) or die "Cannot open '$filename'\n"; + my @data = <FIN>; + close(FIN); + + # find path of current file + my $path = dirname($filename); + $path.='/' if ($path ne ''); + + return ($filename, $path, @data); +} + +1; diff --git a/macros/latex/contrib/stex/bin/README b/macros/latex/contrib/stex/bin/README new file mode 100644 index 0000000000..d548decafc --- /dev/null +++ b/macros/latex/contrib/stex/bin/README @@ -0,0 +1,50 @@ +This directory contains the binaries for sTeX. We have four utilities and a perl libray. +- sms generates sTeX module signatures +- filedate and checksum are for managing metadata in the + DTX files of the sTeX distribution +- installFonts.sty is for chinese font support. + +============== Details ================= + +sms + "genreate sTeX Module Signatures" + +Usage: + sms [options] + +Options: + --input <filename> .tex file to split; default stdin + --verbose verbose on + --stop stop when \end{document} is found, not at EOF + --help show help screen + +Generate .sms file from .tex file given at input; .sms files contain only the modules and +the macros defined within, no other text. + +Example usage: +./sms -i slides.tex -s + +Interpretation: "Generate the slides.sms file for slides.tex; Stop when \end{document} is found." + + +checksum + "enable, update, and disable checksums in DTX files" + +Usage: + checksum [options] + +Options: + -- disable disable the checksum by wrapping in \iffalse ... \fi + -- enable remove those again + -- update update to the correct checksum + + +filedate <input filename> <newdate> + +Purpose: + Update the dates for a \ProvidePackage invocation in a given .dtx source + +Example: + filedate omdoc.dtx + + diff --git a/macros/latex/contrib/stex/bin/checksum b/macros/latex/contrib/stex/bin/checksum new file mode 100755 index 0000000000..9f0e533a8d --- /dev/null +++ b/macros/latex/contrib/stex/bin/checksum @@ -0,0 +1,71 @@ +#!/usr/bin/perl -w +####################################################################################### +# A tool for updating .dtx files with a correspodning checksum counter # +# Copyright (c) 2010, Deyan Ginev, released under the Gnu General Public License (GPL)# +# see http://www.gnu.org/copyleft/gpl.html # +# $URL: https://svn.kwarc.info/repos/stex/trunk/bin/checksum$ # +####################################################################################### + +use strict; + +use Getopt::Long; +use Modparse; +use Pod::Usage; +use Cwd qw(abs_path); + +####### start of program ####### +my $mode = "update"; #Default is update +my $action = { "update" => \&update, "disable" => \&disable, "enable"=>\&enable }; +GetOptions("disable" => sub { $mode="disable"; }, + "enable" => sub { $mode="enable"; }, + "update" => sub { $mode="update"; }); + + +my ($path) = @ARGV; +$path = abs_path($path); +my ($volume,$dir,$file) = File::Spec->splitpath( $path ); +my @lines = `cd $dir; pdflatex "\\nonstopmode\\input{$file}"` if ($mode eq "update"); +my ($checksum) = map {$_=~/^\* The checksum should be (\d+)!/; $1;} grep ($_ =~ /^\* The checksum should be (\d+)!/,@lines) if @lines; +if (!$checksum) { +#One more possible error message: + ($checksum) = map {$_=~/^! Package doc Error: Checksum not passed \((\d+)<>(\d+)\)\./; $2;} grep ($_ =~ /^! Package doc Error: Checksum not passed \((\d+)<>(\d+)\)\./,@lines) if @lines; +} +open(IN,"<$path") or die "Cannot open DTX source: $path\n"; +@lines = (); +while (<IN>) { + push @lines, &{$$action{$mode}}($_,$checksum); +} +close(IN); +open(OUT,">$path") or die "Cannot write to DTX target: $path\n"; +print OUT join("",@lines); +close(OUT); +######### Subroutines ############ +sub update { + my $checksum=$_[1]; + $_[0]=~s/\\CheckSum\{\d*\}/\\CheckSum{$checksum}/ if $checksum; + $_[0]; +} + +sub disable { + $_[0]=~s/\\CheckSum\{(\d*)\}/\\iffalse\\CheckSum\{$1}\\fi/ unless $_[0]=~/\\iffalse\\CheckSum\{(\d*)\}\\fi/; + $_[0]; +} + +sub enable { + $_[0]=~s/\\iffalse\\CheckSum\{(\d*)\}\\fi/\\CheckSum{$1}/; + $_[0]; +} + + +__END__ + + +=head1 SYNOPSIS + +checksum <input filename> --update|enable|disable + +Purpose: + Update, enable or disable the \CheckSum macro for a given .dtx source + +Example: + checksum omd.dtx --update diff --git a/macros/latex/contrib/stex/bin/filedate b/macros/latex/contrib/stex/bin/filedate new file mode 100755 index 0000000000..af49b6550d --- /dev/null +++ b/macros/latex/contrib/stex/bin/filedate @@ -0,0 +1,45 @@ +#!/usr/bin/perl -w +####################################################################################### +# A tool for updating .dtx files with a given package date. # +# Copyright (c) 2010, Deyan Ginev, released under the Gnu General Public License (GPL)# +# see http://www.gnu.org/copyleft/gpl.html # +# $URL: https://svn.kwarc.info/repos/stex/trunk/bin/filedate$ # +####################################################################################### + +use strict; + +use Getopt::Long; +use Modparse; +use Pod::Usage; +use Cwd qw(abs_path); + +my ($file) = @ARGV; +my $date = `git log --format='%ai' $file`; +$date = substr($date, 0, index($date, ' ')); +$date =~ s/-/\//g; +$file = abs_path($file); +open(IN,"<$file"); +my @lines = (); +while (<IN>) { + if ($_ =~ /\\Provides(Package|Class)/) { + $_ =~ s/\[(.*?)\s/\[$date /; + } + push @lines, $_; +} +close(IN); +open(OUT,">$file"); +print OUT join("",@lines); +close(OUT); + +__END__ + + +=head1 SYNOPSIS + +filedate <input filename> <newdate> + +Purpose: + Update the dates for a \ProvidePackage invocation in a given .dtx source + +Example: + filedate omdoc.dtx diff --git a/macros/latex/contrib/stex/bin/installFonts.sh b/macros/latex/contrib/stex/bin/installFonts.sh new file mode 100755 index 0000000000..a9a6b1bb30 --- /dev/null +++ b/macros/latex/contrib/stex/bin/installFonts.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# execute as root (via sudo) +fontdir="$(dirname $0)/../lib/fonts" +mkdir -p /usr/share/fonts/opentype/Fandol +mkdir -p /usr/share/fonts/truetype/cwTeX +cp "${fontdir}/FandolFang-Regular.otf" /usr/share/fonts/opentype/Fandol/ +cp "${fontdir}/cwTeXQKai-Medium.ttf" /usr/share/fonts/truetype/cwTeX/ +exec fc-cache diff --git a/macros/latex/contrib/stex/bin/sms b/macros/latex/contrib/stex/bin/sms new file mode 100755 index 0000000000..5ea7a1afa9 --- /dev/null +++ b/macros/latex/contrib/stex/bin/sms @@ -0,0 +1,146 @@ +#!/usr/bin/perl -w +####################################################################################### +# A tool for creating STeX Module Signatures (SMS) files. # +# Copyright (c) 2005, Ioan Sucan; (c) 2010, Deyan Ginev, +# released under the Gnu General Public License (GPL) # +# see http://www.gnu.org/copyleft/gpl.html # +# $URL: svn://kwarc.eecs.iu-bremen.de/repos/kwarc/projects/content/bin/sms$ # +# $Date: 2006-10-22 20:01:47 +0200 (Sun, 22 Oct 2006) $ $Rev: 10669 $ # +####################################################################################### + +use strict; +use File::Spec::Functions qw(rel2abs); +use File::Basename; +use lib dirname(rel2abs($0)); #Assumption: Modparse is in the same folder as the sms binary. +use Getopt::Long; +use Modparse; +use Pod::Usage; + +my $input = "-", my $verbose=0, my $stop_at_end=0; my $follow=0; +my %arg_snippath; my @snippathList; + +# match {,} brackets that are not comments or special characters +sub match{ + my $data = shift; + my $b = 0, my $i = 0, my $ignore = 0 ; + foreach (split('',$data)){ + $i++; + if ($ignore == 1){ + $ignore = 0; + next; + } + if ($ignore == 2){ + next if $_ ne "\n"; + $ignore = 0; + next; + } + if ($_ eq "\\"){ + $ignore = 1; + next; + } + if ($_ eq '%'){ + $ignore = 2; + next; + } + $b++ if $_ eq '{'; + $b-- if $_ eq '}'; + return (substr($data,0,$i),substr($data,$i,length($data)-$i+1)) if !$b; + } + return ('',$data); +} + + +####### start of program ####### + +GetOptions("verbose" => sub { $verbose=1; }, + "stop" => sub { $stop_at_end=1; }, + "path=s" => \%arg_snippath, + "defpath=s" => \@snippathList, + "help" => sub { pod2usage(2)}, + "follow" => sub { $follow=1; }); + +$input = $ARGV[0] if ($#ARGV>=0); + +my $mp = Modparse->new(snippathList=>\@snippathList, + snippath=>\%arg_snippath, + stopAtEnd=>$stop_at_end, + verbose=>$verbose, + follow=>$follow, + recursion=>0, + onBeginFile=>sub { @{$_[0]->{'sms'.$_[0]->{depth}}}=(); }, + onBeginModule=>sub { push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original}); + @{$_[0]->{'sms'.$_[0]->{depth}}}[-1] =~ s/\n$/%\n/; }, + onEndModule=>sub { push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original}); + @{$_[0]->{'sms'.$_[0]->{depth}}}[-1] =~ s/\n$/%\n/ }, + onRecurse=>sub { + my $recurse = $_[0]->{original}; + $recurse =~ s/include/exclude/g; + push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $recurse); }, + onEndFile=>sub { + my $file = $_[0]->{pack}->new_ext($_[0]->{filename},'.sms'); + open(FOUT, ">$file") or die "Cannot write $file\n"; + print FOUT @{$_[0]->{'sms'.$_[0]->{depth}}}; + close(FOUT); + `touch $file` unless @{$_[0]->{'sms'.$_[0]->{depth}}}; + print "Wrote $file\n" if $verbose; }, + onEveryLine=>sub { + my @lines = @{$_[0]->{'sms'.$_[0]->{depth}}}; + if ($_[0]->{in_module}){ + push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original}) + if ($_[0]->{simple_tex} =~ /\\(symvariant|(sym|abbr|ell|key|listkey)def)\{([^\}]+)\}/ || + $_[0]->{simple_tex} =~ /\\symdef\[([^\]]+)\]/); + push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original}) + if ($_[0]->{simple_tex} =~ /\\(importmodule|gimport|adoptmodule)/); + if ($_[0]->{simple_tex} =~ /\\begin{importmodulevia}/) { + my $impvia = $_[0]->{original}; + $impvia =~ s/\\begin\{importmodulevia\}/\\importmodule/g; + push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $impvia); + } + push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original}) + if ($_[0]->{simple_tex} =~ /\\importOMDocmodule/); + push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original}) + if ($_[0]->{simple_tex} =~ /\\requiremodules/); + push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original}) + if ($_[0]->{simple_tex} =~ /\\requirepackage/); + if ((/\\STRlabel\{([^\}]+)\}(\{.*)/) || (/\\STRsemantics\[([^\]]+)\](\{.*)/)){ + my ($label, $line) = ($1, "$2 $_[0]->{comment}"); + my ($matched, $rest) = (undef, undef); + while (1) { + ($matched, $rest) = match($line); + last if $matched; + $line.=$_[0]->{nextline}(); } + $_[0]->{rewriteline}($rest) if $rest; + $line = "\\STRlabeldef{$label}$matched"; chomp($line); + map(push(@{$_[0]->{'sms'.$_[0]->{depth}}},"$_\n"),split("\n",$line)); + } + @{$_[0]->{'sms'.$_[0]->{depth}}}[-1] =~ s/\n$/%\n/ + if (@lines < @{$_[0]->{'sms'.$_[0]->{depth}}}); + }} ); + +$mp->execute($input); + +print "Done.\n" if $verbose; + + +__END__ + + +=head1 SYNOPSIS + +sms <input filename> [options] + +Options: + + --verbose verbose on + --stop stop when \end{document} is found; default is to go on + --follow demands following \input|include|require statements (default:off) + --path XXX=somePath specify the value of \XXX (some snippath) in case it is + not defined in the processed .tex file + --defpath XXX specify which \XXX (snippath definitions) to look for + --help this screen + +Purpose: + Generate .sms files (STeX Module Signatures) from .tex files + +Example: + sms slides.tex -v |