1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#!/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 %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)});
$input = $ARGV[0] if ($#ARGV>=0);
my $mp = Modparse->new(snippathList=>\@snippathList,
snippath=>\%arg_snippath,
stopAtEnd=>$stop_at_end,
verbose=>$verbose,
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} =~ /\\(sym|abbr|ell)def\{([^\}]+)\}/ ||
$_[0]->{simple_tex} =~ /\\symdef\[([^\]]+)\]/);
push(@{$_[0]->{'sms'.$_[0]->{depth}}}, $_[0]->{original})
if ($_[0]->{simple_tex} =~ /\\importmodule/);
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
--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
|