pdf_paradise 0.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +933 -0
- data/bin/automatic_pdf_title +7 -0
- data/bin/burst_this_pdf_file +7 -0
- data/bin/combine_these_pdf_pages +7 -0
- data/bin/compress_via_hexapdf +7 -0
- data/bin/convert_markdown_to_pdf +7 -0
- data/bin/convert_pdf_to_text +7 -0
- data/bin/delete_first_page_of_this_pdf_file +7 -0
- data/bin/djvu_to_pdf +7 -0
- data/bin/merge_then_open +7 -0
- data/bin/n_pages +10 -0
- data/bin/open_main_pdf +7 -0
- data/bin/pdf_paradise +9 -0
- data/bin/rotate_pdf +7 -0
- data/bin/set_main_book +7 -0
- data/bin/set_title_of_this_pdf_file +15 -0
- data/doc/README.gen +871 -0
- data/doc/todo/todo.md +13 -0
- data/images/Logo_for_the_pdf_paradise_project.avif +0 -0
- data/lib/pdf_paradise/base/base.rb +344 -0
- data/lib/pdf_paradise/base/colours.rb +67 -0
- data/lib/pdf_paradise/colours/colours.rb +27 -0
- data/lib/pdf_paradise/commandline/commandline.rb +109 -0
- data/lib/pdf_paradise/commandline/help.rb +77 -0
- data/lib/pdf_paradise/commandline/menu.rb +173 -0
- data/lib/pdf_paradise/compress/compress_this_pdf_file.rb +108 -0
- data/lib/pdf_paradise/compress/compress_via_hexapdf.rb +27 -0
- data/lib/pdf_paradise/compress/compress_via_qpdf.rb +32 -0
- data/lib/pdf_paradise/constants/constants.rb +76 -0
- data/lib/pdf_paradise/convert_text_to_pdf.rb +94 -0
- data/lib/pdf_paradise/css/project.css +17 -0
- data/lib/pdf_paradise/fpdf/README.md +2 -0
- data/lib/pdf_paradise/fpdf/bookmark.rb +129 -0
- data/lib/pdf_paradise/fpdf/chinese.rb +454 -0
- data/lib/pdf_paradise/fpdf/fpdf.rb +1902 -0
- data/lib/pdf_paradise/fpdf/fpdf_eps.rb +138 -0
- data/lib/pdf_paradise/fpdf/makefont.rb +1794 -0
- data/lib/pdf_paradise/gui/README.md +6 -0
- data/lib/pdf_paradise/gui/fox/split_pdf_file.rb +77 -0
- data/lib/pdf_paradise/gui/gtk2/pdf_viewer/pdf_viewer.rb +34 -0
- data/lib/pdf_paradise/gui/gtk2/split_pdf_file/split_pdf_file.rb +34 -0
- data/lib/pdf_paradise/gui/gtk2/statistics_widget/statistics_widget.rb +34 -0
- data/lib/pdf_paradise/gui/gtk3/controller/controller.rb +214 -0
- data/lib/pdf_paradise/gui/gtk3/pdf_viewer/pdf_viewer.rb +34 -0
- data/lib/pdf_paradise/gui/gtk3/split_pdf_file/split_pdf_file.rb +34 -0
- data/lib/pdf_paradise/gui/jruby/delete_the_first_or_the_last_page_of_this_pdf_file/delete_the_first_or_the_last_page_of_this_pdf_file.rb +167 -0
- data/lib/pdf_paradise/gui/jruby/remove_the_first_page_of_this_pdf_file/remove_the_first_page_of_this_pdf_file.rb +103 -0
- data/lib/pdf_paradise/gui/libui/extract_all_images_from_this_pdf_file/extract_all_images_from_this_pdf_file.rb +223 -0
- data/lib/pdf_paradise/gui/libui/remove_the_first_page_of_this_pdf_file/remove_the_first_page_of_this_pdf_file.rb +267 -0
- data/lib/pdf_paradise/gui/libui/rotate_pdf_file/rotate_pdf_file.rb +219 -0
- data/lib/pdf_paradise/gui/libui/statistics_widget/statistics_widget.rb +233 -0
- data/lib/pdf_paradise/gui/shared_code/pdf_viewer/pdf_viewer.css +5 -0
- data/lib/pdf_paradise/gui/shared_code/pdf_viewer/pdf_viewer_module.rb +287 -0
- data/lib/pdf_paradise/gui/shared_code/remove_the_first_page_of_this_pdf_file_module/remove_the_first_page_of_this_pdf_file_module.rb +31 -0
- data/lib/pdf_paradise/gui/shared_code/split_pdf_file/split_pdf_file_module.rb +295 -0
- data/lib/pdf_paradise/gui/universal_widgets/convert_pdf_to_text/convert_pdf_to_text.rb +366 -0
- data/lib/pdf_paradise/gui/universal_widgets/delete_the_first_or_the_last_page_of_this_pdf_file/delete_the_first_or_the_last_page_of_this_pdf_file.rb +776 -0
- data/lib/pdf_paradise/gui/universal_widgets/statistics_widget/statistics_widget.rb +407 -0
- data/lib/pdf_paradise/gui/universal_widgets/to_pdf/to_pdf.rb +351 -0
- data/lib/pdf_paradise/hexapdf/001_rainbow_pattern_example.rb +0 -0
- data/lib/pdf_paradise/hexapdf/hexapdf.rb +123 -0
- data/lib/pdf_paradise/images/PDF_PARADISE_LOGO.png +0 -0
- data/lib/pdf_paradise/main_pdf/main_pdf.rb +474 -0
- data/lib/pdf_paradise/merge_pdf/menu.rb +63 -0
- data/lib/pdf_paradise/merge_pdf/merge_pdf.rb +307 -0
- data/lib/pdf_paradise/merge_pdf_namespace.rb +9 -0
- data/lib/pdf_paradise/merge_then_open/merge_then_open.rb +105 -0
- data/lib/pdf_paradise/prawn_addons/README.md +2 -0
- data/lib/pdf_paradise/prawn_addons/prawn_addons.rb +17 -0
- data/lib/pdf_paradise/project/project.rb +22 -0
- data/lib/pdf_paradise/remove_pdf_password.rb +391 -0
- data/lib/pdf_paradise/requires/batch_require_toplevel_files.rb +22 -0
- data/lib/pdf_paradise/requires/colours.rb +11 -0
- data/lib/pdf_paradise/requires/colours_and_esystem_and_save_file_and_fileutils_and_opn.rb +13 -0
- data/lib/pdf_paradise/requires/esystem_and_colours.rb +11 -0
- data/lib/pdf_paradise/requires/esystem_and_opn_and_colours.rb +10 -0
- data/lib/pdf_paradise/requires/require_the_whole_project.rb +30 -0
- data/lib/pdf_paradise/requires/require_utility_scripts.rb +9 -0
- data/lib/pdf_paradise/set_main_book.rb +156 -0
- data/lib/pdf_paradise/set_pdf_title.rb +220 -0
- data/lib/pdf_paradise/sinatra/embeddable_interface.rb +389 -0
- data/lib/pdf_paradise/toplevel_methods/convert_epub_to_pdf.rb +27 -0
- data/lib/pdf_paradise/toplevel_methods/convert_markdown_to_pdf.rb +45 -0
- data/lib/pdf_paradise/toplevel_methods/convert_ppt_to_pdf.rb +35 -0
- data/lib/pdf_paradise/toplevel_methods/e.rb +16 -0
- data/lib/pdf_paradise/toplevel_methods/esystem.rb +20 -0
- data/lib/pdf_paradise/toplevel_methods/misc.rb +228 -0
- data/lib/pdf_paradise/toplevel_methods/number_pages.rb +38 -0
- data/lib/pdf_paradise/toplevel_methods/opened_pdf_files.rb +221 -0
- data/lib/pdf_paradise/toplevel_methods/query_pdf_title.rb +201 -0
- data/lib/pdf_paradise/toplevel_methods/reduce_size_of_this_pdf_file.rb +46 -0
- data/lib/pdf_paradise/toplevel_methods/roebe.rb +17 -0
- data/lib/pdf_paradise/toplevel_methods/to_pdf.rb +12 -0
- data/lib/pdf_paradise/utility_scripts/README.md +3 -0
- data/lib/pdf_paradise/utility_scripts/automatic_pdf_title.rb +104 -0
- data/lib/pdf_paradise/utility_scripts/check_syntax_of_pdf_files.rb +106 -0
- data/lib/pdf_paradise/utility_scripts/combine_these_pdf_pages.rb +118 -0
- data/lib/pdf_paradise/utility_scripts/convert_pdf_to_text.rb +179 -0
- data/lib/pdf_paradise/utility_scripts/delete_last_page_of_this_pdf_file.rb +180 -0
- data/lib/pdf_paradise/utility_scripts/delete_the_first_page_of_this_pdf_file/delete_the_first_page_of_this_pdf_file.rb +429 -0
- data/lib/pdf_paradise/utility_scripts/delete_this_page_of_this_pdf_file.rb +356 -0
- data/lib/pdf_paradise/utility_scripts/djvu_to_pdf.rb +87 -0
- data/lib/pdf_paradise/utility_scripts/extract_all_images_from_this_pdf_file.rb +129 -0
- data/lib/pdf_paradise/utility_scripts/extract_pdf_page.rb +283 -0
- data/lib/pdf_paradise/utility_scripts/pdf_file_n_total_pages.rb +348 -0
- data/lib/pdf_paradise/utility_scripts/pdf_optimizer.rb +111 -0
- data/lib/pdf_paradise/utility_scripts/pdf_statistics.rb +148 -0
- data/lib/pdf_paradise/utility_scripts/pdf_to_html.rb +75 -0
- data/lib/pdf_paradise/utility_scripts/remove_images.rb +110 -0
- data/lib/pdf_paradise/utility_scripts/rotate_pdf_file.rb +303 -0
- data/lib/pdf_paradise/utility_scripts/split_pdf.rb +364 -0
- data/lib/pdf_paradise/utility_scripts/to_pdf.rb +130 -0
- data/lib/pdf_paradise/utility_scripts/to_qdf.rb +66 -0
- data/lib/pdf_paradise/version/version.rb +19 -0
- data/lib/pdf_paradise/www/README.md +2 -0
- data/lib/pdf_paradise/www/sinatra/app.rb +304 -0
- data/lib/pdf_paradise/yaml/working_on_these_pdf_files.yml +4 -0
- data/lib/pdf_paradise.rb +5 -0
- data/pdf_paradise.gemspec +61 -0
- data/test/fpdf/001_minimal_example.rb +12 -0
- data/test/fpdf/002.pdf +0 -0
- data/test/fpdf/002_header_and_footer_example.rb +64 -0
- data/test/fpdf/003.pdf +98 -0
- data/test/fpdf/003_justified_paragraphs.rb +96 -0
- data/test/fpdf/file1.md +3 -0
- data/test/fpdf/file2.md +3 -0
- data/test/fpdf/test.pdf +0 -0
- data/test/testing_pdf_paradise.rb +12 -0
- metadata +239 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# === PdfParadise::SetPdfTitle
|
|
6
|
+
#
|
|
7
|
+
# This class can be used to set a new title to any given .pdf file.
|
|
8
|
+
#
|
|
9
|
+
# A module-method also exists, on module PdfParadise.
|
|
10
|
+
#
|
|
11
|
+
# We will make use of the excellent perl library called "exiftool"
|
|
12
|
+
# for now. Perhaps at a later time, we will change to use something
|
|
13
|
+
# else rather than perl. But for now, I simply wanted to have one
|
|
14
|
+
# tool that works and move on.
|
|
15
|
+
#
|
|
16
|
+
# A typical usage example would be like this:
|
|
17
|
+
#
|
|
18
|
+
# exiftool -overwrite_original -Title="This is the Title now!" DONE_VO_06_Cell_Biology_Methods_Crystallography_How_to_make_a_car.pdf
|
|
19
|
+
#
|
|
20
|
+
# Usage example:
|
|
21
|
+
#
|
|
22
|
+
# PdfParadise::SetPdfTitle.new(ARGV)
|
|
23
|
+
#
|
|
24
|
+
# =========================================================================== #
|
|
25
|
+
# require 'pdf_paradise/set_pdf_title.rb'
|
|
26
|
+
# =========================================================================== #
|
|
27
|
+
require 'pdf_paradise/base/base.rb'
|
|
28
|
+
|
|
29
|
+
module PdfParadise
|
|
30
|
+
|
|
31
|
+
class SetPdfTitle < Base # === PdfParadise::SetPdfTitle
|
|
32
|
+
|
|
33
|
+
# ========================================================================= #
|
|
34
|
+
# === SHALL_WE_DELETE_THE_ORIGINAL_FILE
|
|
35
|
+
# ========================================================================= #
|
|
36
|
+
SHALL_WE_DELETE_THE_ORIGINAL_FILE = true
|
|
37
|
+
|
|
38
|
+
# ========================================================================= #
|
|
39
|
+
# === initialize
|
|
40
|
+
# ========================================================================= #
|
|
41
|
+
def initialize(
|
|
42
|
+
name_of_the_pdf_file = nil,
|
|
43
|
+
new_title_to_use = 'Default title',
|
|
44
|
+
run_already = true
|
|
45
|
+
)
|
|
46
|
+
reset
|
|
47
|
+
if name_of_the_pdf_file.is_a?(Array) and (name_of_the_pdf_file.size > 1)
|
|
48
|
+
new_title_to_use = name_of_the_pdf_file.last
|
|
49
|
+
if new_title_to_use.include? '--'
|
|
50
|
+
# =================================================================== #
|
|
51
|
+
# Assume this to be a commandline instruction then.
|
|
52
|
+
# =================================================================== #
|
|
53
|
+
case new_title_to_use # case tag
|
|
54
|
+
# =================================================================== #
|
|
55
|
+
# === --set-title=03 Stickstoff und Aminosäuren
|
|
56
|
+
# =================================================================== #
|
|
57
|
+
when /-?-?set(-|_)?title=(.+)$/
|
|
58
|
+
new_title_to_use = $2.to_s.dup
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
name_of_the_pdf_file = name_of_the_pdf_file.first
|
|
62
|
+
end
|
|
63
|
+
set_pdf_file(
|
|
64
|
+
name_of_the_pdf_file
|
|
65
|
+
)
|
|
66
|
+
set_title(new_title_to_use)
|
|
67
|
+
run if run_already
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# ========================================================================= #
|
|
71
|
+
# === reset (reset tag)
|
|
72
|
+
# ========================================================================= #
|
|
73
|
+
def reset
|
|
74
|
+
set_title # Set a default, being nil in this case.
|
|
75
|
+
# ======================================================================= #
|
|
76
|
+
# === @commandline_to_use
|
|
77
|
+
# ======================================================================= #
|
|
78
|
+
@commandline_to_use = 'exiftool'.dup # This will be our commandline.
|
|
79
|
+
# ======================================================================= #
|
|
80
|
+
# === Designate the charset that is to be used next
|
|
81
|
+
#
|
|
82
|
+
# Next, append the charset to be used. This is usually UTF-8.
|
|
83
|
+
# exiftool claims that iso-8859-1 is an invalid encoding, but latin
|
|
84
|
+
# is valid, according to exiftool..
|
|
85
|
+
# ======================================================================= #
|
|
86
|
+
@commandline_to_use << ' -charset UTF8'
|
|
87
|
+
# @commandline_to_use << ' -charset latin' # <- It works with latin.
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# ========================================================================= #
|
|
91
|
+
# === set_title (title tag)
|
|
92
|
+
#
|
|
93
|
+
# Assign the title that we will use for the given .pdf file at hand.
|
|
94
|
+
# ========================================================================= #
|
|
95
|
+
def set_title(i = :default)
|
|
96
|
+
if i == :default
|
|
97
|
+
i = nil
|
|
98
|
+
else
|
|
99
|
+
i = i.to_s
|
|
100
|
+
i = i.dup if i.frozen?
|
|
101
|
+
end
|
|
102
|
+
i = "-Title=\"#{i}\"" if i
|
|
103
|
+
@title = i
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# ========================================================================= #
|
|
107
|
+
# === set_pdf_file
|
|
108
|
+
# ========================================================================= #
|
|
109
|
+
def set_pdf_file(i)
|
|
110
|
+
i = i.first if i.is_a? Array
|
|
111
|
+
i = i.to_s # We need a String past this point.
|
|
112
|
+
i = i.dup if i.frozen?
|
|
113
|
+
@pdf_file = i
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# ========================================================================= #
|
|
117
|
+
# === set_input
|
|
118
|
+
# ========================================================================= #
|
|
119
|
+
def set_input(i = '')
|
|
120
|
+
i = i.first if i.is_a? Array
|
|
121
|
+
i = i.to_s.dup
|
|
122
|
+
@input = i
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# ========================================================================= #
|
|
126
|
+
# === input?
|
|
127
|
+
# ========================================================================= #
|
|
128
|
+
def input?
|
|
129
|
+
@input
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# ========================================================================= #
|
|
133
|
+
# === build_up_commandline_command
|
|
134
|
+
#
|
|
135
|
+
# Build up the main commandline to use here.
|
|
136
|
+
# ========================================================================= #
|
|
137
|
+
def build_up_commandline_command
|
|
138
|
+
if SHALL_WE_DELETE_THE_ORIGINAL_FILE
|
|
139
|
+
@commandline_to_use << ' -overwrite_original'
|
|
140
|
+
end
|
|
141
|
+
add_title_to_the_commandline
|
|
142
|
+
add_pdf_file_to_the_commandline
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# ========================================================================= #
|
|
146
|
+
# === add_pdf_file_to_the_commandline
|
|
147
|
+
# ========================================================================= #
|
|
148
|
+
def add_pdf_file_to_the_commandline
|
|
149
|
+
@commandline_to_use << " #{@pdf_file}"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# ========================================================================= #
|
|
153
|
+
# === pdf_file?
|
|
154
|
+
# ========================================================================= #
|
|
155
|
+
def pdf_file?
|
|
156
|
+
@pdf_file
|
|
157
|
+
end; alias this_file? pdf_file? # === this_file?
|
|
158
|
+
|
|
159
|
+
# ========================================================================= #
|
|
160
|
+
# === add_title_to_the_commandline
|
|
161
|
+
# ========================================================================= #
|
|
162
|
+
def add_title_to_the_commandline
|
|
163
|
+
@commandline_to_use << " #{@title}"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# ========================================================================= #
|
|
167
|
+
# === run_commandline_command
|
|
168
|
+
# ========================================================================= #
|
|
169
|
+
def run_commandline_command
|
|
170
|
+
# The following clause can lead to an infinite loop, so it was disabled
|
|
171
|
+
# as of May 2022. It may have to be re-evaluated at a later point.
|
|
172
|
+
# if is_on_roebe? and return_pwd.include?('/home/x/books')
|
|
173
|
+
# unless PdfParadise.respond_to? :automatic_pdf_title
|
|
174
|
+
# require 'pdf_paradise/toplevel_methods/automatic_pdf_title.rb'
|
|
175
|
+
# end
|
|
176
|
+
# PdfParadise.autotitle(this_file?)
|
|
177
|
+
# end
|
|
178
|
+
esystem(@commandline_to_use)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# ========================================================================= #
|
|
182
|
+
# === run (run tag)
|
|
183
|
+
# ========================================================================= #
|
|
184
|
+
def run
|
|
185
|
+
build_up_commandline_command
|
|
186
|
+
run_commandline_command
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# ========================================================================= #
|
|
190
|
+
# === PdfParadise::SetPdfTitle[]
|
|
191
|
+
# ========================================================================= #
|
|
192
|
+
def self.[](i = ARGV)
|
|
193
|
+
new(i)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# =========================================================================== #
|
|
199
|
+
# === PdfParadise.set_title_of_this_pdf_file
|
|
200
|
+
#
|
|
201
|
+
# You need to pass in two arguments to this module-method.
|
|
202
|
+
#
|
|
203
|
+
# The first argument is the path to the .pdf file in question that
|
|
204
|
+
# you want to manipulate - that is, to change the title of said
|
|
205
|
+
# .pdf file.
|
|
206
|
+
#
|
|
207
|
+
# The second argument is the new title of this .pdf file.
|
|
208
|
+
# =========================================================================== #
|
|
209
|
+
def self.set_title_of_this_pdf_file(
|
|
210
|
+
this_pdf_file,
|
|
211
|
+
this_title = ''
|
|
212
|
+
)
|
|
213
|
+
SetPdfTitle.new(this_pdf_file, this_title)
|
|
214
|
+
end; self.instance_eval { alias set_pdf_title set_title_of_this_pdf_file } # === PdfParadise.set_pdf_title
|
|
215
|
+
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
if __FILE__ == $PROGRAM_NAME
|
|
219
|
+
PdfParadise::SetPdfTitle.new(ARGV)
|
|
220
|
+
end # pdf_title foo.pdf "This is the new title"
|
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# === PdfParadise::EmbeddableInterface
|
|
6
|
+
#
|
|
7
|
+
# The code in this file can be used to "embed" the functionality of
|
|
8
|
+
# PdfParadise in web-applications, in particular in sinatra.
|
|
9
|
+
#
|
|
10
|
+
# This depends on the cyberweb project.
|
|
11
|
+
# =========================================================================== #
|
|
12
|
+
# require 'pdf_paradise/sinatra/embeddable_interface.rb'
|
|
13
|
+
# include PdfParadise::EmbeddableInterface
|
|
14
|
+
# PdfParadise::EmbeddableInterface.route_name?
|
|
15
|
+
# =========================================================================== #
|
|
16
|
+
module PdfParadise
|
|
17
|
+
|
|
18
|
+
module EmbeddableInterface # === PdfParadise::EmbeddableInterface
|
|
19
|
+
|
|
20
|
+
require 'pdf_paradise/constants/constants.rb'
|
|
21
|
+
require 'pdf_paradise/utility_scripts/delete_the_first_page_of_this_pdf_file/delete_the_first_page_of_this_pdf_file.rb'
|
|
22
|
+
|
|
23
|
+
begin
|
|
24
|
+
require 'cyberweb/sinatra/custom_extensions.rb'
|
|
25
|
+
include Cyberweb::Sinatra::CustomExtensions
|
|
26
|
+
rescue LoadError; end
|
|
27
|
+
|
|
28
|
+
begin
|
|
29
|
+
require 'cyberweb/web_images/web_images.rb'
|
|
30
|
+
rescue LoadError; end
|
|
31
|
+
|
|
32
|
+
begin
|
|
33
|
+
require 'html_tags'
|
|
34
|
+
include HtmlTags::BaseModule
|
|
35
|
+
rescue LoadError; end
|
|
36
|
+
|
|
37
|
+
require 'cyberweb/requires/require_the_html_template.rb'
|
|
38
|
+
|
|
39
|
+
# ========================================================================= #
|
|
40
|
+
# Designate a uniform CSS style to use:
|
|
41
|
+
# ========================================================================= #
|
|
42
|
+
USE_THIS_UNIFORM_CSS_STYLE = 'margin-left:3.5em; font-weight: bold;'
|
|
43
|
+
|
|
44
|
+
# ========================================================================= #
|
|
45
|
+
# === RARROW
|
|
46
|
+
# ========================================================================= #
|
|
47
|
+
RARROW = '→'
|
|
48
|
+
|
|
49
|
+
# ========================================================================= #
|
|
50
|
+
# === USE_THIS_PORT
|
|
51
|
+
#
|
|
52
|
+
# Note that this constant, for the port, is only in use when we run
|
|
53
|
+
# the sinatra-specific part of PdfParadise in a standalone manner.
|
|
54
|
+
#
|
|
55
|
+
# When we run from the main controller, which is part of the Roebe
|
|
56
|
+
# project, then this port is not relevant, as that main controller
|
|
57
|
+
# already handles that case.
|
|
58
|
+
# ========================================================================= #
|
|
59
|
+
USE_THIS_PORT = '5200'
|
|
60
|
+
|
|
61
|
+
# ========================================================================= #
|
|
62
|
+
# === @route_name
|
|
63
|
+
# ========================================================================= #
|
|
64
|
+
@route_name = ''.dup
|
|
65
|
+
|
|
66
|
+
# ========================================================================= #
|
|
67
|
+
# === PdfParadise::EmbeddableInterface.set_route_name
|
|
68
|
+
# ========================================================================= #
|
|
69
|
+
def self.set_route_name(i)
|
|
70
|
+
@route_name = i
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# ========================================================================= #
|
|
74
|
+
# === PdfParadise::EmbeddableInterface.route_name?
|
|
75
|
+
# ========================================================================= #
|
|
76
|
+
def self.route_name?
|
|
77
|
+
@route_name
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# ========================================================================= #
|
|
81
|
+
# === route_name?
|
|
82
|
+
# ========================================================================= #
|
|
83
|
+
def route_name?
|
|
84
|
+
::PdfParadise::EmbeddableInterface.route_name?
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# ========================================================================= #
|
|
88
|
+
# === sub_routes?
|
|
89
|
+
# ========================================================================= #
|
|
90
|
+
def sub_routes?
|
|
91
|
+
::PdfParadise::EmbeddableInterface.sub_routes?
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# ========================================================================= #
|
|
95
|
+
# === PdfParadise::EmbeddableInterface.sub_routes?
|
|
96
|
+
#
|
|
97
|
+
# List the available sub-routes that depend on the main route_name?
|
|
98
|
+
# defined above. All sub-routes must be defined here, because we
|
|
99
|
+
# may expose this Hash to other applications.
|
|
100
|
+
# ========================================================================= #
|
|
101
|
+
def self.sub_routes?
|
|
102
|
+
{
|
|
103
|
+
view: route_name?+'/view',
|
|
104
|
+
n_pdf_pages: route_name?+'/n_pdf_pages'
|
|
105
|
+
}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# ========================================================================= #
|
|
109
|
+
# === input_type_user_input
|
|
110
|
+
# ========================================================================= #
|
|
111
|
+
def input_type_user_input
|
|
112
|
+
'<input type="text" name="user_input" style="border:3px solid slateblue; padding: 4px">'
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# ========================================================================= #
|
|
116
|
+
# === input_type_submit
|
|
117
|
+
# ========================================================================= #
|
|
118
|
+
def input_type_submit(
|
|
119
|
+
text_to_use = 'Search'
|
|
120
|
+
)
|
|
121
|
+
'<input type="submit" name="user_input_submit" value="'+text_to_use+'" class="default_submit">'
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# ========================================================================= #
|
|
125
|
+
# === open_body (body tag)
|
|
126
|
+
# ========================================================================= #
|
|
127
|
+
def open_body
|
|
128
|
+
'<body>'
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
require 'pdf_paradise/version/version.rb'
|
|
132
|
+
# ========================================================================= #
|
|
133
|
+
# === return_paragraph_of_hyperlinks
|
|
134
|
+
# ========================================================================= #
|
|
135
|
+
def return_paragraph_of_hyperlinks
|
|
136
|
+
p(
|
|
137
|
+
'The following entry-points are available for the '\
|
|
138
|
+
'<b>PdfParadise project</b>: (Version: '+PdfParadise::VERSION+',
|
|
139
|
+
Last Update: '+PdfParadise::LAST_UPDATE+')
|
|
140
|
+
<br><br>'+
|
|
141
|
+
return_index_of_hyperlinks
|
|
142
|
+
)
|
|
143
|
+
end; alias footer return_paragraph_of_hyperlinks # === footer (footer tag)
|
|
144
|
+
|
|
145
|
+
# ========================================================================= #
|
|
146
|
+
# === return_view_string
|
|
147
|
+
# ========================================================================= #
|
|
148
|
+
def return_view_string
|
|
149
|
+
hash = PdfParadise::EmbeddableInterface.sub_routes?
|
|
150
|
+
h1('Pdf Options:', css_style: 'margin-left:0.25em;')+
|
|
151
|
+
p(
|
|
152
|
+
"The next link is to view all .pdf files at <b>"\
|
|
153
|
+
"#{PdfParadise.main_directory?}</b>"
|
|
154
|
+
)+
|
|
155
|
+
abr(hash[:view])
|
|
156
|
+
end; alias view? return_view_string # === view?
|
|
157
|
+
|
|
158
|
+
# ========================================================================= #
|
|
159
|
+
# === return_index_of_hyperlinks
|
|
160
|
+
#
|
|
161
|
+
# This method will bundle together the different indices containing the
|
|
162
|
+
# hyperlinks that will be shown on the root-directory.
|
|
163
|
+
# ========================================================================= #
|
|
164
|
+
def return_index_of_hyperlinks
|
|
165
|
+
# ======================================================================= #
|
|
166
|
+
# Obtain the hash that keeps track of all routes.
|
|
167
|
+
# ======================================================================= #
|
|
168
|
+
hash = PdfParadise::EmbeddableInterface.sub_routes?
|
|
169
|
+
|
|
170
|
+
if Object.const_defined? :WebObject
|
|
171
|
+
cat_image = Cyberweb.base64_image(:cat)
|
|
172
|
+
else
|
|
173
|
+
cat_image = ''
|
|
174
|
+
end
|
|
175
|
+
a('/', content: cat_image+' /',
|
|
176
|
+
css_style: USE_THIS_UNIFORM_CSS_STYLE)+
|
|
177
|
+
'<br>'+
|
|
178
|
+
a(hash[:view], content: cat_image+' /view',
|
|
179
|
+
css_style: USE_THIS_UNIFORM_CSS_STYLE)+
|
|
180
|
+
'<br>'+
|
|
181
|
+
a(hash[:n_pdf_pages], content: cat_image+' /n_pdf_pages',
|
|
182
|
+
css_style: USE_THIS_UNIFORM_CSS_STYLE)+
|
|
183
|
+
'<br>'+
|
|
184
|
+
a('/title', content: cat_image+' /title',
|
|
185
|
+
css_style: USE_THIS_UNIFORM_CSS_STYLE)+
|
|
186
|
+
'<br>'+
|
|
187
|
+
# ======================================================================= #
|
|
188
|
+
# Explain the autoconvert option a little bit:
|
|
189
|
+
# ======================================================================= #
|
|
190
|
+
p(
|
|
191
|
+
'Click on the <b>following link</b> to autoconvert all .pdf files '\
|
|
192
|
+
'in the directory called '\
|
|
193
|
+
'<b>'+PdfParadise.main_directory?.to_s+'</b>'
|
|
194
|
+
)+
|
|
195
|
+
a('/autoconvert', css_style: USE_THIS_UNIFORM_CSS_STYLE)+
|
|
196
|
+
'<br>'+
|
|
197
|
+
# return_div_showing_all_available_books_if_we_are_on_a_roebe_system+
|
|
198
|
+
return_div_for_manual_pdf_conversion+
|
|
199
|
+
return_div_for_removing_the_first_page_of_this_pdf_file
|
|
200
|
+
end; alias return_the_hyperlinks return_index_of_hyperlinks # === return_the_hyperlinks
|
|
201
|
+
|
|
202
|
+
# ========================================================================= #
|
|
203
|
+
# === return_div_showing_all_available_books_if_we_are_on_a_roebe_system
|
|
204
|
+
# ========================================================================= #
|
|
205
|
+
def return_div_showing_all_available_books_if_we_are_on_a_roebe_system
|
|
206
|
+
_ = ''.dup
|
|
207
|
+
if PdfParadise.is_on_roebe?
|
|
208
|
+
all_pdf_files = Dir['/home/x/books/**/*.pdf']
|
|
209
|
+
all_pdf_files.each {|this_pdf_file|
|
|
210
|
+
_ << this_pdf_file+"<br>"
|
|
211
|
+
}
|
|
212
|
+
end
|
|
213
|
+
return _
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# ========================================================================= #
|
|
217
|
+
# === return_div_for_manual_pdf_conversion
|
|
218
|
+
# ========================================================================= #
|
|
219
|
+
def return_div_for_manual_pdf_conversion
|
|
220
|
+
# ======================================================================= #
|
|
221
|
+
# Determine the main route for the upcoming action:
|
|
222
|
+
# ======================================================================= #
|
|
223
|
+
route_to_this_action = '/convert_single_pdf_file/'
|
|
224
|
+
# ======================================================================= #
|
|
225
|
+
# Add the <div> that contains the manual conversion functionality:
|
|
226
|
+
# ======================================================================= #
|
|
227
|
+
# ======================================================================= #
|
|
228
|
+
# Explain how to convert just an individual file instead:
|
|
229
|
+
# ======================================================================= #
|
|
230
|
+
p("If you merely wish to convert a single .pdf file, you can use "\
|
|
231
|
+
"the following form for this:\n")+
|
|
232
|
+
div(css_style: 'padding: 0.2em') {
|
|
233
|
+
p(
|
|
234
|
+
'<b>Enter the name of the .pdf file that you wish to convert:</b>', css_style: 'padding:0.75em'
|
|
235
|
+
)+
|
|
236
|
+
form(action: route_to_this_action,
|
|
237
|
+
id: 'convert_single_pdf_file',
|
|
238
|
+
css_style: 'margin-left:2em; margin-top:2px') {
|
|
239
|
+
'<input type="text" name="user_input" style="border:3px solid slateblue; padding: 4px"><br>'\
|
|
240
|
+
'<b>Select a file</b>: <input type="file" name="this_file"><br>'\
|
|
241
|
+
'<input type="submit" name="user_input_submit" '\
|
|
242
|
+
'value="Click here to convert the .pdf file" style="2px dotted royalblue; '\
|
|
243
|
+
'color: white; background-color: olive; font-size: 1.50em;
|
|
244
|
+
margin:4px; padding: 4px; border: 1px solid black">'
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# ========================================================================= #
|
|
250
|
+
# === close_html
|
|
251
|
+
# ========================================================================= #
|
|
252
|
+
def close_html
|
|
253
|
+
'</html>'
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# ========================================================================= #
|
|
257
|
+
# === open_html
|
|
258
|
+
# ========================================================================= #
|
|
259
|
+
def open_html
|
|
260
|
+
'<html>'
|
|
261
|
+
end; alias html_start open_html # === html_start
|
|
262
|
+
|
|
263
|
+
# ========================================================================= #
|
|
264
|
+
# === return_full_title
|
|
265
|
+
# ========================================================================= #
|
|
266
|
+
def return_full_title
|
|
267
|
+
'<title>PDF-based operations</title>'
|
|
268
|
+
end; alias default_title return_full_title # === default_title
|
|
269
|
+
|
|
270
|
+
# ========================================================================= #
|
|
271
|
+
# === close_body
|
|
272
|
+
# ========================================================================= #
|
|
273
|
+
def close_body
|
|
274
|
+
'</body>'
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# =========================================================================== #
|
|
278
|
+
# === return_n_pdf_pages
|
|
279
|
+
# =========================================================================== #
|
|
280
|
+
def return_n_pdf_pages
|
|
281
|
+
route_to_this_action = sub_routes?[:n_pdf_pages]
|
|
282
|
+
html_start_then_title+
|
|
283
|
+
p('Provide the path to a .pdf file:')+
|
|
284
|
+
form(action: route_to_this_action,
|
|
285
|
+
id: route_to_this_action.delete('/'),
|
|
286
|
+
css_style: 'margin-left:2em; margin-top:2px') {
|
|
287
|
+
input_type_user_input+
|
|
288
|
+
br+
|
|
289
|
+
input_type_submit('Submit')
|
|
290
|
+
}
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# ========================================================================= #
|
|
294
|
+
# === return_link_to_root
|
|
295
|
+
# ========================================================================= #
|
|
296
|
+
def return_link_to_root
|
|
297
|
+
abr(
|
|
298
|
+
'/',
|
|
299
|
+
content: :self,
|
|
300
|
+
css_style: USE_THIS_UNIFORM_CSS_STYLE
|
|
301
|
+
)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# ========================================================================= #
|
|
305
|
+
# === html_start_then_title
|
|
306
|
+
# ========================================================================= #
|
|
307
|
+
def html_start_then_title
|
|
308
|
+
html_start+
|
|
309
|
+
default_title
|
|
310
|
+
end; alias html_then_title html_start_then_title # === html_then_title
|
|
311
|
+
|
|
312
|
+
# ========================================================================= #
|
|
313
|
+
# === return_root_string (root tag)
|
|
314
|
+
# ========================================================================= #
|
|
315
|
+
def return_root_string
|
|
316
|
+
html_then_title+
|
|
317
|
+
return_CSS_rules_to_use+
|
|
318
|
+
open_body+
|
|
319
|
+
return_paragraph_of_hyperlinks+
|
|
320
|
+
close_body+
|
|
321
|
+
close_html
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# ========================================================================= #
|
|
325
|
+
# === return_CSS_rules_to_use
|
|
326
|
+
# ========================================================================= #
|
|
327
|
+
def return_CSS_rules_to_use
|
|
328
|
+
'<style>
|
|
329
|
+
body {
|
|
330
|
+
margin: 0.25em;
|
|
331
|
+
padding: 15px;
|
|
332
|
+
font-size: larger;
|
|
333
|
+
}
|
|
334
|
+
a {
|
|
335
|
+
text-decoration: none;
|
|
336
|
+
}
|
|
337
|
+
a:hover {
|
|
338
|
+
text-decoration: underline;
|
|
339
|
+
}
|
|
340
|
+
</style>'
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
# ========================================================================= #
|
|
344
|
+
# === return_div_for_removing_the_first_page_of_this_pdf_file
|
|
345
|
+
# ========================================================================= #
|
|
346
|
+
def return_div_for_removing_the_first_page_of_this_pdf_file
|
|
347
|
+
# ======================================================================= #
|
|
348
|
+
# Determine the main route for the upcoming action:
|
|
349
|
+
# ======================================================================= #
|
|
350
|
+
route_to_this_action = '/remove_the_first_page_of_this_pdf_file/'
|
|
351
|
+
# ======================================================================= #
|
|
352
|
+
# Add the <div> that contains the manual conversion functionality:
|
|
353
|
+
# ======================================================================= #
|
|
354
|
+
# ======================================================================= #
|
|
355
|
+
# Explain how to convert just an individual file instead:
|
|
356
|
+
# ======================================================================= #
|
|
357
|
+
div(css_style: 'padding: 0.2em') {
|
|
358
|
+
p(
|
|
359
|
+
'<b>Enter the name of the .pdf file whose first page should be removed:</b>',
|
|
360
|
+
css_style: 'padding:0.75em'
|
|
361
|
+
)+
|
|
362
|
+
form(action: route_to_this_action,
|
|
363
|
+
id: 'remove_the_first_page_of_this_pdf_file',
|
|
364
|
+
css_style: 'margin-left:2em; margin-top:2px') {
|
|
365
|
+
'<input type="text" name="user_input" style="border:3px solid slateblue; padding: 4px"><br>'\
|
|
366
|
+
'<b>Select a file</b>: <input type="file" name="this_file"><br>'\
|
|
367
|
+
'<input type="submit" name="user_input_submit" '\
|
|
368
|
+
'value="Click here to remove the first page of this .pdf file" style="2px dotted royalblue; '\
|
|
369
|
+
'color: white; background-color: olive; font-size: 1.50em;
|
|
370
|
+
margin:4px; padding: 4px; border: 1px solid black">'
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
# =========================================================================== #
|
|
378
|
+
# === PdfParadise.embeddable_interface
|
|
379
|
+
#
|
|
380
|
+
# This method can be used to "embed" a fake-object that implements the
|
|
381
|
+
# module defined above.
|
|
382
|
+
# =========================================================================== #
|
|
383
|
+
def self.embeddable_interface
|
|
384
|
+
object = Object.new
|
|
385
|
+
object.extend(PdfParadise::EmbeddableInterface)
|
|
386
|
+
return object
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
module PdfParadise
|
|
6
|
+
|
|
7
|
+
require 'pdf_paradise/toplevel_methods/esystem.rb'
|
|
8
|
+
|
|
9
|
+
# ========================================================================= #
|
|
10
|
+
# === PdfParadise.convert_epub_to_pdf
|
|
11
|
+
#
|
|
12
|
+
# This method allows us to convert an .epub file to .pdf format, if
|
|
13
|
+
# pandoc is available.
|
|
14
|
+
# ========================================================================= #
|
|
15
|
+
def self.convert_epub_to_pdf(i)
|
|
16
|
+
i = [i].flatten.compact
|
|
17
|
+
i.each {|entry|
|
|
18
|
+
_ = 'pandoc -s -t latex --toc --chapters --latex-engine=lualatex '+entry+' -o '+entry+'.pdf'
|
|
19
|
+
esystem _
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if __FILE__ == $PROGRAM_NAME
|
|
26
|
+
PdfParadise.convert_epub_to_pdf(ARGV)
|
|
27
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/ruby -w
|
|
2
|
+
# Encoding: UTF-8
|
|
3
|
+
# frozen_string_literal: true
|
|
4
|
+
# =========================================================================== #
|
|
5
|
+
# require 'pdf_paradise/toplevel_methods/convert_markdown_to_pdf.rb'
|
|
6
|
+
# =========================================================================== #
|
|
7
|
+
module PdfParadise
|
|
8
|
+
|
|
9
|
+
require 'pdf_paradise/toplevel_methods/e.rb'
|
|
10
|
+
|
|
11
|
+
# ========================================================================= #
|
|
12
|
+
# === PdfParadise.convert_markdown_to_pdf
|
|
13
|
+
#
|
|
14
|
+
# This method can be used to convert a markdown .md file into a .pdf
|
|
15
|
+
# file.
|
|
16
|
+
#
|
|
17
|
+
# This functionality depends on kramdown, and kramdown-pdf-converter.
|
|
18
|
+
# ========================================================================= #
|
|
19
|
+
def self.convert_markdown_to_pdf(
|
|
20
|
+
this_markdown_file
|
|
21
|
+
)
|
|
22
|
+
require 'kramdown'
|
|
23
|
+
require 'kramdown/converter/pdf'
|
|
24
|
+
begin
|
|
25
|
+
require 'save_file'
|
|
26
|
+
rescue LoadError; end
|
|
27
|
+
require 'colours'
|
|
28
|
+
[this_markdown_file].flatten.compact.each {|markdown_file|
|
|
29
|
+
if File.exist? markdown_file
|
|
30
|
+
text = File.read(markdown_file)
|
|
31
|
+
dataset = Kramdown::Document.new(text).to_pdf
|
|
32
|
+
target = markdown_file.sub(/#{File.extname(markdown_file)}$/,'')+'.pdf'
|
|
33
|
+
e 'Storing into the file `'+Colours.sfile(target)+'`.'
|
|
34
|
+
SaveFile.write_what_into(dataset, target)
|
|
35
|
+
else
|
|
36
|
+
e 'No file exists at '+Colours.sfile(markdown_file)+'.'
|
|
37
|
+
end
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
if __FILE__ == $PROGRAM_NAME
|
|
44
|
+
PdfParadise.convert_markdown_to_pdf(ARGV)
|
|
45
|
+
end # convert_markdown_to_pdf
|