summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/stex/bin
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/stex/bin
Initial commit
Diffstat (limited to 'macros/latex/contrib/stex/bin')
-rw-r--r--macros/latex/contrib/stex/bin/Modparse.pm189
-rw-r--r--macros/latex/contrib/stex/bin/README50
-rwxr-xr-xmacros/latex/contrib/stex/bin/checksum71
-rwxr-xr-xmacros/latex/contrib/stex/bin/filedate45
-rwxr-xr-xmacros/latex/contrib/stex/bin/installFonts.sh8
-rwxr-xr-xmacros/latex/contrib/stex/bin/sms146
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