source: main/trunk/greenstone2/perllib/cpan/Mojo/Loader.pm

Last change on this file was 32205, checked in by ak19, 6 years ago

First set of commits to do with implementing the new 'paged_html' output option of PDFPlugin that uses using xpdftools' new pdftohtml. So far tested only on Linux (64 bit), but things work there so I'm optimistically committing the changes since they work. 2. Committing the pre-built Linux binaries of XPDFtools for both 32 and 64 bit built by the XPDF group. 2. To use the correct bitness variant of xpdftools, setup.bash now exports the BITNESS env var, consulted by gsConvert.pl. 3. All the perl code changes to do with using xpdf tools' pdftohtml to generate paged_html and feed it in the desired form into GS(3): gsConvert.pl, PDFPlugin.pm and its parent ConvertBinaryPFile.pm have been modified to make it all work. xpdftools' pdftohtml generates a folder containing an html file and a screenshot for each page in a PDF (as well as an index.html linking to each page's html). However, we want a single html file that contains each individual 'page' html's content in a div, and need to do some further HTML style, attribute and structure modifications to massage the xpdftool output to what we want for GS. In order to parse and manipulate the HTML 'DOM' to do this, we're using the Mojo::DOM package that Dr Bainbridge found and which he's compiled up. Mojo::DOM is therefore also committed in this revision. Some further changes and some display fixes are required, but need to check with the others about that.

File size: 4.4 KB
Line 
1package Mojo::Loader;
2use Mojo::Base -strict;
3
4use Exporter 'import';
5use Mojo::Exception;
6use Mojo::File 'path';
7use Mojo::Util qw(b64_decode class_to_path);
8
9our @EXPORT_OK
10 = qw(data_section file_is_binary find_modules find_packages load_class);
11
12my (%BIN, %CACHE);
13
14sub data_section { $_[0] ? $_[1] ? _all($_[0])->{$_[1]} : _all($_[0]) : undef }
15
16sub file_is_binary { keys %{_all($_[0])} ? !!$BIN{$_[0]}{$_[1]} : undef }
17
18sub find_modules {
19 my $ns = shift;
20
21 my %modules;
22 for my $directory (@INC) {
23 next unless -d (my $path = path($directory, split(/::|'/, $ns)));
24 $modules{"${ns}::$_"}++
25 for $path->list->grep(qr/\.pm$/)->map('basename', '.pm')->each;
26 }
27
28 return sort keys %modules;
29}
30
31sub find_packages {
32 my $ns = shift;
33 no strict 'refs';
34 return sort map { /^(.+)::$/ ? "${ns}::$1" : () } keys %{"${ns}::"};
35}
36
37sub load_class {
38 my $class = shift;
39
40 # Invalid class name
41 return 1 if ($class || '') !~ /^\w(?:[\w:']*\w)?$/;
42
43 # Load if not already loaded
44 return undef if $class->can('new') || eval "require $class; 1";
45
46 # Does not exist
47 return 1 if $@ =~ /^Can't locate \Q@{[class_to_path $class]}\E in \@INC/;
48
49 # Real error
50 return Mojo::Exception->new($@)->inspect;
51}
52
53sub _all {
54 my $class = shift;
55
56 return $CACHE{$class} if $CACHE{$class};
57 local $.;
58 my $handle = do { no strict 'refs'; \*{"${class}::DATA"} };
59 return {} unless fileno $handle;
60 seek $handle, 0, 0;
61 my $data = join '', <$handle>;
62
63 # Ignore everything before __DATA__ (some versions seek to start of file)
64 $data =~ s/^.*\n__DATA__\r?\n/\n/s;
65
66 # Ignore everything after __END__
67 $data =~ s/\n__END__\r?\n.*$/\n/s;
68
69 # Split files
70 (undef, my @files) = split /^@@\s*(.+?)\s*\r?\n/m, $data;
71
72 # Find data
73 my $all = $CACHE{$class} = {};
74 while (@files) {
75 my ($name, $data) = splice @files, 0, 2;
76 $all->{$name} = $name =~ s/\s*\(\s*base64\s*\)$//
77 && ++$BIN{$class}{$name} ? b64_decode $data : $data;
78 }
79
80 return $all;
81}
82
831;
84
85=encoding utf8
86
87=head1 NAME
88
89Mojo::Loader - Load all kinds of things
90
91=head1 SYNOPSIS
92
93 use Mojo::Loader qw(data_section find_modules load_class);
94
95 # Find modules in a namespace
96 for my $module (find_modules 'Some::Namespace') {
97
98 # Load them safely
99 my $e = load_class $module;
100 warn qq{Loading "$module" failed: $e} and next if ref $e;
101
102 # And extract files from the DATA section
103 say data_section($module, 'some_file.txt');
104 }
105
106=head1 DESCRIPTION
107
108L<Mojo::Loader> is a class loader and plugin framework. Aside from finding
109modules and loading classes, it allows multiple files to be stored in the
110C<DATA> section of a class, which can then be accessed individually.
111
112 package Foo;
113
114 1;
115 __DATA__
116
117 @@ test.txt
118 This is the first file.
119
120 @@ test2.html (base64)
121 VGhpcyBpcyB0aGUgc2Vjb25kIGZpbGUu
122
123 @@ test
124 This is the
125 third file.
126
127Each file has a header starting with C<@@>, followed by the file name and
128optional instructions for decoding its content. Currently only the Base64
129encoding is supported, which can be quite convenient for the storage of binary
130data.
131
132=head1 FUNCTIONS
133
134L<Mojo::Loader> implements the following functions, which can be imported
135individually.
136
137=head2 data_section
138
139 my $all = data_section 'Foo::Bar';
140 my $index = data_section 'Foo::Bar', 'index.html';
141
142Extract embedded file from the C<DATA> section of a class, all files will be
143cached once they have been accessed for the first time.
144
145 # List embedded files
146 say for keys %{data_section 'Foo::Bar'};
147
148=head2 file_is_binary
149
150 my $bool = file_is_binary 'Foo::Bar', 'test.png';
151
152Check if embedded file from the C<DATA> section of a class was Base64 encoded.
153
154=head2 find_packages
155
156 my @pkgs = find_packages 'MyApp::Namespace';
157
158Search for packages in a namespace non-recursively.
159
160=head2 find_modules
161
162 my @modules = find_modules 'MyApp::Namespace';
163
164Search for modules in a namespace non-recursively.
165
166=head2 load_class
167
168 my $e = load_class 'Foo::Bar';
169
170Load a class and catch exceptions, returns a false value if loading was
171successful, a true value if the class was not found, or a L<Mojo::Exception>
172object if loading failed. Note that classes are checked for a C<new> method to
173see if they are already loaded, so trying to load the same class multiple times
174may yield different results.
175
176 # Handle exceptions
177 if (my $e = load_class 'Foo::Bar') {
178 die ref $e ? "Exception: $e" : 'Not found!';
179 }
180
181=head1 SEE ALSO
182
183L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
184
185=cut
Note: See TracBrowser for help on using the repository browser.