
| Current Path : /bin/X11/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : //bin/X11/pamphletangler |
#!/usr/bin/perl -w
=head1 NAME
pamphletangler - Extract code bits from LaTeX pamphlet files.
=cut
=head1 SYNOPSIS
B<pamphletangler> [OPTION...] I<FILE> I<CHUNKNAME>
=cut
=head1 DESCRIPTION
The clojure pamphlet system is a system based on the clojure literate
system. In the clojure's pamphlet system you have your main LaTeX file, which
can be compiled regularly. This file contains documentation and source code
(just like in other forms of literate programming). This code snippets are
wrapped in the 'chunk' environment, hence they can be recognized by the tangler
in order to extract them. Chunks can be included inside each other by the
'getchunk' command (which will be typesetted acordingly). Finally, you run your
LaTeX file through the tangler and get your desired chunk of code.
=cut
=head1 OPTIONS
=over 29
=item -L, --line=linetext
If set, this text will be inserted after jumps of lines, changing the string
inside "changetext" for the line number. This is used so that error report
refers to pamphlet line number instead of output line number
=item -C, --change=changetext
Defaults to "{}" this is the text that will be replaced with the line number if
the linetext option is specified
=item -?, --help
Give this help list
=item --usage
Give a short usage message
=item --man
Print manual page
=item -V, --version
Print program version
=back
=head1 LICENSE
Copyright (C) 2019 Ernesto Lanchares Sanchez.
The clojure-pamphlet tagler is free software; you can redistribute
it and/or modify it under the terms of the GNU Lesser General
Public License as published by the Free Software Foundation;
either version 3 of the License, or (at your option) any later
version.
The clojure-pamphlet tangler is distributed in the hope that it
will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, see
L<http://www.gnu.org/licenses/>.
=head1 AUTHOR
Ernesto Lanchares <e.lancha98@gmail.com>
=head1 BUGS
Report bugs to e.lancha98@gmail.com
=cut
use strict;
use warnings;
use Getopt::Long;
use Pod::Usage qw(pod2usage);
use vars qw/$VERSION/;
BEGIN { $VERSION = '1.3' }
my $linetext = "";
my $changetext = "{}";
my $filename;
my $chunkname;
OPTS: {
GetOptions(
'usage' => sub { pod2usage( -verbose => 99, -sections => [ qw(SYNOPSIS) ]); },
'help|?' => sub { pod2usage( -verbose => 99, -sections => [ qw(SYNOPSIS DESCRIPTION OPTIONS BUGS) ]); },
'man' => sub { pod2usage( -verbose => 2) },
'version|V' => sub { print "$VERSION\n"; exit; },
'line|L=s' => \$linetext,
'change|C=s' => \$changetext
);
pod2usage( -message => "[ERROR]: Invalid number of arguments." )
if scalar(@ARGV) != 2;
$filename = shift;
$chunkname = shift;
}
open(my $file, "<", $filename) or die "Can't open $filename: $!";
my $file_contents = do { local $/; <$file> };
my %codeblocks;
while ($file_contents =~ /\\begin\{chunk\}\{([\w.]+)\}[\s\h\t]*\n?(.*?)\n?[\s\t\h]*\\end\{chunk\}/sg) {
$codeblocks{$1} = { source => $2, printing => undef };
}
open($file, "<", $filename) or die "Can't open $filename: $!";
my $index = 1;
while (my $line = <$file>) {
while ($line =~ /\\begin\{chunk\}\{([\w.]+)\}/g) {
$codeblocks{$1}{line} = $index+1;
}
$index++;
}
sub printchunk {
my ($chunk, $indent) = @_;
die "Chunk $chunk not found." if (!exists($codeblocks{$chunk}));
die "Cyclic reference found: $chunk" if $codeblocks{$chunk}{printing};
$codeblocks{$chunk}{printing} = 1;
my $localines = 1;
print $linetext =~ s/$changetext/$codeblocks{$chunk}{line}/gr, "\n";
foreach my $line (split(/\n/, $codeblocks{$chunk}{source})) {
if ($line =~ /([\s\t\h]*)\\getchunk\{([\w.]+)\}/) {
eval {
printchunk($2, $1); #$1 contains indent and $2 contains chunkname
print $linetext =~ s/$changetext/@{[$codeblocks{$chunk}{line} + $localines]}/gr, "\n";
1;
} or do {
if (rindex($@, "Cyclic reference found:", 0) == 0) {
$@ =~ /(.+?)( at .*)/s;
die "$1 <- $chunk";
}
die $@;
}
} else {
print $indent, $line, "\n";
}
$localines++;
}
$codeblocks{$chunk}{printing} = undef;
return 0;
}
printchunk($chunkname, "");