jekyll_asciidoctor_pdf 0.0.15 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.adoc +56 -5
- data/lib/jekyll_asciidoctor_pdf/adoc.rb +125 -0
- data/lib/jekyll_asciidoctor_pdf/commands.rb +136 -187
- data/lib/jekyll_asciidoctor_pdf/logger.rb +11 -0
- data/lib/jekyll_asciidoctor_pdf/permalink.rb +18 -0
- data/lib/jekyll_asciidoctor_pdf/sidebar.rb +174 -0
- data/lib/jekyll_asciidoctor_pdf/version.rb +1 -1
- metadata +6 -3
- data/lib/jekyll_asciidoctor_pdf/tree.rb +0 -71
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09550c635149441d709366d60bf401788a4bb529ebeeb02fb5375019a0c42df4'
|
4
|
+
data.tar.gz: 872489f640ae593e3c4b0d52cbe0e66a89dbaa0bc8554789605ecdc4d7319bdf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '092973c75f4944a59174674ffc09bbe7e4244cdf96734c19b3cb7aa81b56f727cc7f8649ff0b08c78c7af0b1db796524da08a4d0354bd37793f2475bb9499179'
|
7
|
+
data.tar.gz: b22030fa3a38f441788823c881c759f772f51ff872847040cea7f4c27c90235bc682dc6ffc7bb01da8ddca236987b772b640640b977df8f2b4fbd0dd3cb094c5
|
data/README.adoc
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
:gem-name: jekyll_asciidoctor_pdf
|
3
3
|
:gh-branch: master
|
4
4
|
:badge-style: flat
|
5
|
-
:release-version: 0.
|
5
|
+
:release-version: 0.1.2
|
6
6
|
|
7
7
|
image:https://img.shields.io/gem/v/{gem-name}.svg?style={badge-style}[Gem Version, link="https://rubygems.org/gems/{gem-name}"]
|
8
8
|
image:https://travis-ci.com/NetAppDocs/jekyll-asciidoctor-pdf.svg?token=jmKxRqiJdAgY6ceg7i2d&branch=master["Build Status", link="https://travis-ci.com/NetAppDocs/jekyll-asciidoctor-pdf"]
|
@@ -43,6 +43,7 @@ require 'rake_jekyll_asciidoctor_pdf'
|
|
43
43
|
|
44
44
|
RakeJekyllAsciidoctorPdf::BuildTask.new('buildAll') do |t|
|
45
45
|
t.jekyll_config_file = '_config.yml'
|
46
|
+
t.fullsite_title = ENV['PRODUCT_NAME']
|
46
47
|
end
|
47
48
|
----
|
48
49
|
|
@@ -55,13 +56,11 @@ end
|
|
55
56
|
[source,ruby]
|
56
57
|
----
|
57
58
|
jap_config:
|
58
|
-
|
59
|
+
sidebar_path: '_data/sidebars/'
|
59
60
|
output_path: 'pdfs'
|
60
61
|
source_path: '.'
|
61
|
-
assets_list: ['media']
|
62
62
|
exclude_list: []
|
63
63
|
fullsite:
|
64
|
-
title: "Main Title"
|
65
64
|
subtitle: "Subtitle"
|
66
65
|
authors: "Author1, Author2"
|
67
66
|
revision: "Revision Date"
|
@@ -89,10 +88,62 @@ A basic directory structure usually looks something like this:
|
|
89
88
|
└── *.adoc # all asciidoc files are in the root level
|
90
89
|
```
|
91
90
|
|
91
|
+
A complex directory structure could be like this
|
92
|
+
|
93
|
+
```
|
94
|
+
.
|
95
|
+
├── _config.yml
|
96
|
+
├── _data
|
97
|
+
│ ├── sidebar1
|
98
|
+
│ │ ...
|
99
|
+
│ └── sidebarN.yml
|
100
|
+
├── sidebar1_source
|
101
|
+
│ ├── media
|
102
|
+
│ ├── *.adoc # all asciidoc files are in the root level
|
103
|
+
| ...
|
104
|
+
├── sidebarN_source
|
105
|
+
│ ├── media
|
106
|
+
│ ├── *.adoc # all asciidoc files are in the root level
|
107
|
+
└── pdfs # this folder will be created by rake_jekyll_asciidoctor_pdf
|
108
|
+
├── pages/
|
109
|
+
├── sidebar1/
|
110
|
+
├── ...
|
111
|
+
├── sidebarN/
|
112
|
+
└── fullsite/
|
113
|
+
|
114
|
+
```
|
115
|
+
|
116
|
+
|
92
117
|
|
93
118
|
== Usage
|
94
119
|
|
95
120
|
$ bundle exec rake buildAll
|
96
121
|
|
122
|
+
== Known Limitations
|
123
|
+
* Mp4 is not supported
|
124
|
+
* Gif files need prawn-gmagick
|
125
|
+
* Absolute URL not supported in the sidebar.yml
|
126
|
+
* Problems with image labels like that
|
127
|
+
* Problems with interal *links:*
|
128
|
+
* Unicode characters are not supported by AsciiDocPdf (e.i. ✓)
|
129
|
+
|
130
|
+
[source,asciidoc]
|
131
|
+
----
|
132
|
+
//image:diagram_networking_cloud.png[service, a] not working, shoud be like this
|
133
|
+
image:diagram_networking_cloud.png["service, a"]
|
134
|
+
----
|
97
135
|
|
98
|
-
|
136
|
+
|
137
|
+
== ToDo List ==
|
138
|
+
|
139
|
+
* [x] Remove front matter from original files
|
140
|
+
* [x] Generate a combined file with each item in the sidebar.yml
|
141
|
+
* [x] Allow to customize PDF using a theme of AsciiDoctor-PDF
|
142
|
+
* [ ] Remove header attribuites in the original files
|
143
|
+
* [x] Increase 1 level each time we combine a child in the sidebar
|
144
|
+
* [x] Generate a PDF for each section
|
145
|
+
* [ ] Support multiple sidebar.yml like HCI (Partial)
|
146
|
+
* [x] Support basic recursion over directories
|
147
|
+
|
148
|
+
|
149
|
+
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'asciidoctor-pdf'
|
4
|
+
require 'asciidoctor'
|
5
|
+
|
6
|
+
# Do not touch, this REGEXP is taken from Jekyll source code
|
7
|
+
YAML_FRONT_MATTER_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
|
8
|
+
|
9
|
+
module JekyllAsciidoctorPdf
|
10
|
+
class ADoc
|
11
|
+
##
|
12
|
+
# Generate a PDF of an individual page
|
13
|
+
#
|
14
|
+
# - Remove the jekyll frontmatter
|
15
|
+
# - Execute the convert process
|
16
|
+
# - Let the caller to collect information from the front_matter and from the file itself
|
17
|
+
#
|
18
|
+
def self.generatePdf(title, file, output_path, parameters, cover_page, theme_pdf)
|
19
|
+
|
20
|
+
#filename = SafeYAML.load_file(file)
|
21
|
+
front_matter = {}
|
22
|
+
|
23
|
+
content = File.read(file)
|
24
|
+
if content =~ YAML_FRONT_MATTER_REGEXP
|
25
|
+
#content = $POSTMATCH
|
26
|
+
front_matter = SafeYAML.load(Regexp.last_match(1))
|
27
|
+
end
|
28
|
+
|
29
|
+
stream_adoc = content.gsub(YAML_FRONT_MATTER_REGEXP, '')
|
30
|
+
|
31
|
+
filename = File.basename(file,'.*') + '.pdf'
|
32
|
+
filename_path = output_path
|
33
|
+
subtitle = 'Page'
|
34
|
+
base_path = File.dirname(file)
|
35
|
+
|
36
|
+
generateBookTypePdf(filename, filename_path, title, subtitle, base_path, stream_adoc, parameters, cover_page, theme_pdf)
|
37
|
+
|
38
|
+
yield(front_matter, stream_adoc) if block_given?
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
##
|
43
|
+
# We abstract the call to Asciidoctor to convert Stream => PDF
|
44
|
+
#
|
45
|
+
# Arguments:
|
46
|
+
# - filename: name of the output file (should include extension e.i. name.pdf)
|
47
|
+
# - filename_path: output path for the filename
|
48
|
+
# - title: title of the cover page
|
49
|
+
# - subtitle: subtitle of the cover page
|
50
|
+
# - base_path: this is the root path to execture the convert process (relative :imagedir attribute use that path)
|
51
|
+
# - stream_adoc: the Asciidoc file as string
|
52
|
+
# - parameters: configuration from YAML file
|
53
|
+
# - cover_page: absolute image for the cover page
|
54
|
+
# - theme_pdf: absolute YAML file with the theme configuration of Asciidoctor-pdf
|
55
|
+
#
|
56
|
+
# NOTE:
|
57
|
+
# * We set the mode to :unsafe, due to the error "image has illegal reference to ancestor of jail;"
|
58
|
+
# e.i :imagedirs: ../media
|
59
|
+
#
|
60
|
+
# * We allow to read external files with the attribute 'allow-uri-read' => ''
|
61
|
+
# e.i image:http://example.org/image.png
|
62
|
+
# (we may want to block this feature is too expensive)
|
63
|
+
#
|
64
|
+
def self.generateBookTypePdf(filename, filename_path, title, subtitle, base_path, stream_adoc, parameters, cover_page, theme_pdf)
|
65
|
+
|
66
|
+
Asciidoctor.convert(
|
67
|
+
getFullsiteTemplate(title, subtitle, stream_adoc, parameters, cover_page, theme_pdf),
|
68
|
+
backend: 'pdf',
|
69
|
+
doctype: 'book',
|
70
|
+
to_file: filename,
|
71
|
+
to_dir: filename_path,
|
72
|
+
mkdirs: true,
|
73
|
+
safe: :unsafe,
|
74
|
+
attributes: { 'allow-uri-read' => '' },
|
75
|
+
base_dir: base_path
|
76
|
+
);
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Basic Template for the fullsite pdf
|
81
|
+
#
|
82
|
+
# TODO: Add more configuracion
|
83
|
+
#
|
84
|
+
def self.getFullsiteTemplate(title, subtitle, fullsite, parameters, cover_page, theme_pdf)
|
85
|
+
fullsite_config = parameters['fullsite']
|
86
|
+
|
87
|
+
authors = fullsite_config['authors']
|
88
|
+
revision = fullsite_config['revision']
|
89
|
+
|
90
|
+
text = <<~TEXT
|
91
|
+
= #{title} : #{subtitle}
|
92
|
+
#{authors}
|
93
|
+
#{revision}
|
94
|
+
:doctype: book
|
95
|
+
:experimental:
|
96
|
+
:reproducible:
|
97
|
+
:icons: font
|
98
|
+
:listing-caption: Listing
|
99
|
+
:sectnums:
|
100
|
+
:imagesdir: ./media/
|
101
|
+
:toc:
|
102
|
+
:toclevels: 2
|
103
|
+
ifeval::["{asciidoctor-version}" < "1.5.7"]
|
104
|
+
:legacy-footnoteref:
|
105
|
+
endif::[]
|
106
|
+
ifdef::backend-pdf[]
|
107
|
+
:pdf-theme: #{theme_pdf}
|
108
|
+
:title-page:
|
109
|
+
:title-page-background-image: image:#{cover_page}[fit=none,pdfwidth=100%,position=top]
|
110
|
+
:source-highlighter: rouge
|
111
|
+
endif::[]
|
112
|
+
:chapter-label:
|
113
|
+
|
114
|
+
:leveloffset: +1
|
115
|
+
#{fullsite}
|
116
|
+
:leveloffset: -1
|
117
|
+
TEXT
|
118
|
+
|
119
|
+
return text
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
@@ -6,11 +6,10 @@ require 'yaml'
|
|
6
6
|
require 'fileutils'
|
7
7
|
require 'asciidoctor-pdf'
|
8
8
|
require 'asciidoctor'
|
9
|
-
require 'jekyll_asciidoctor_pdf/
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
YAML_FRONT_MATTER_REGEXP = /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m
|
9
|
+
require 'jekyll_asciidoctor_pdf/adoc'
|
10
|
+
require 'jekyll_asciidoctor_pdf/logger'
|
11
|
+
require 'jekyll_asciidoctor_pdf/sidebar'
|
12
|
+
require 'jekyll_asciidoctor_pdf/permalink'
|
14
13
|
|
15
14
|
|
16
15
|
module JekyllAsciidoctorPdf
|
@@ -56,34 +55,35 @@ module JekyllAsciidoctorPdf
|
|
56
55
|
attr_accessor :description
|
57
56
|
|
58
57
|
attr_accessor :parameters
|
58
|
+
attr_accessor :permalinks
|
59
59
|
|
60
|
-
attr_reader :absolute_temp_path
|
61
60
|
attr_reader :absolute_working_path
|
62
61
|
attr_reader :absolute_source_path
|
63
|
-
attr_reader :absolute_assets_list
|
64
62
|
attr_reader :absolute_config_file
|
65
|
-
attr_reader :
|
63
|
+
attr_reader :absolute_sidebar_path
|
66
64
|
attr_reader :absolute_output_path
|
67
65
|
|
68
|
-
attr_reader :
|
66
|
+
attr_reader :absolute_cover_page
|
67
|
+
attr_reader :absolute_theme_pdf
|
68
|
+
|
69
69
|
attr_reader :quiet
|
70
70
|
|
71
71
|
callable_attr :jekyll_config_file, '_config.yml'
|
72
72
|
|
73
|
+
callable_attr :fullsite_title, 'NetApp'
|
74
|
+
|
75
|
+
|
76
|
+
##
|
77
|
+
#
|
73
78
|
def initialize(name = :build_pdf)
|
74
79
|
@name = name
|
75
80
|
@description = 'Generate PDF files for each *.adoc in the source_list '
|
76
81
|
|
77
82
|
@absolute_working_path = Dir.pwd
|
78
|
-
@absolute_temp_path = Dir.mktmpdir
|
79
|
-
|
80
|
-
@quiet = { verbose: true }
|
81
83
|
|
82
|
-
|
83
|
-
#file = File.readlink(file) if File.symlink?(file)
|
84
|
-
#@base_dir = File.dirname(file)
|
84
|
+
@permalinks = Hash.new
|
85
85
|
|
86
|
-
|
86
|
+
@quiet = { verbose: true }
|
87
87
|
|
88
88
|
yield self if block_given?
|
89
89
|
|
@@ -92,15 +92,10 @@ module JekyllAsciidoctorPdf
|
|
92
92
|
do_jekyll_config_ok? do |t|
|
93
93
|
@absolute_source_path = File.join(@absolute_working_path, @parameters['source_path']);
|
94
94
|
@absolute_output_path = File.join(@absolute_working_path, @parameters['output_path']);
|
95
|
-
@
|
95
|
+
@absolute_sidebar_path = File.join(@absolute_working_path, @parameters['sidebar_path']);
|
96
|
+
@absolute_cover_page = File.join(@absolute_output_path, 'assets','cover_page_background.jpg');
|
97
|
+
@absolute_theme_pdf = File.join(@absolute_output_path, 'assets','pdf-theme.yml');
|
96
98
|
|
97
|
-
files = []
|
98
|
-
FileList[@parameters['assets_list']].each do |file|
|
99
|
-
files << File.join(@absolute_working_path,file)
|
100
|
-
end
|
101
|
-
|
102
|
-
@absolute_assets_list = files
|
103
|
-
|
104
99
|
define_task!
|
105
100
|
end
|
106
101
|
end
|
@@ -119,34 +114,17 @@ module JekyllAsciidoctorPdf
|
|
119
114
|
clean
|
120
115
|
end
|
121
116
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
task :generateTempFiles => [ :clean ] do
|
126
|
-
generate_temp_files
|
127
|
-
end
|
128
|
-
|
129
|
-
desc "Generating PDFs files for each page"
|
130
|
-
task :generatePdf => [:clean, :generateTempFiles] do
|
131
|
-
generate_pdf
|
132
|
-
end
|
133
|
-
|
134
|
-
desc "Generate the fullsite.adoc file"
|
135
|
-
file 'fullsite.adoc' => ['generateTempFiles'] do
|
136
|
-
|
137
|
-
generate_fullsite_adoc
|
138
|
-
end
|
139
|
-
|
140
|
-
desc "Generate the fullsite.pdf file"
|
141
|
-
file 'fullsite.pdf' => 'fullsite.adoc' do
|
142
|
-
|
143
|
-
generate_fullsite_pdf
|
117
|
+
desc "Initialize files & directories"
|
118
|
+
task :init => [ :clean ] do
|
119
|
+
init
|
144
120
|
end
|
145
121
|
|
146
122
|
|
147
123
|
desc description
|
148
|
-
task name.to_sym => [:
|
149
|
-
|
124
|
+
task name.to_sym => [:clean, :init] do
|
125
|
+
generate_individual_pdf
|
126
|
+
generate_fullsite_adoc
|
127
|
+
undo_init
|
150
128
|
end
|
151
129
|
|
152
130
|
|
@@ -165,9 +143,8 @@ module JekyllAsciidoctorPdf
|
|
165
143
|
@parameters = config['jap_config']
|
166
144
|
|
167
145
|
assert_key(@parameters, 'source_path' , "Expected key 'jap_config.source_path' to exist, but does not")
|
168
|
-
assert_key(@parameters, 'assets_list' , "Expected key 'jap_config.assets_list' to exist, but does not")
|
169
146
|
assert_key(@parameters, 'output_path' , "Expected key 'jap_config.output_path' to exist, but does not")
|
170
|
-
assert_key(@parameters, '
|
147
|
+
assert_key(@parameters, 'sidebar_path', "Expected key 'jap_config.sidebar_path' to exist, but does not")
|
171
148
|
|
172
149
|
yield
|
173
150
|
end
|
@@ -180,120 +157,138 @@ module JekyllAsciidoctorPdf
|
|
180
157
|
end
|
181
158
|
|
182
159
|
|
160
|
+
##
|
161
|
+
# Only to debug
|
162
|
+
#
|
183
163
|
def print_variables
|
184
164
|
output("Current directory: " + absolute_working_path)
|
185
165
|
output("Jekyll Config File: " + absolute_config_file)
|
186
166
|
output("Source directory: " + absolute_source_path)
|
187
|
-
output("
|
188
|
-
output("Temporary directory: " + absolute_temp_path)
|
167
|
+
output("Sidebar directory: " + absolute_sidebar_path)
|
189
168
|
output("Building directory: " + absolute_output_path)
|
190
169
|
end
|
191
170
|
|
171
|
+
##
|
172
|
+
#
|
173
|
+
#
|
192
174
|
def clean
|
193
|
-
|
194
|
-
output("Removing files & ouput directories ...")
|
175
|
+
output("Removing files & output directories ...")
|
195
176
|
rm_rf(absolute_output_path, quiet)
|
196
|
-
mkdir_p(absolute_output_path, quiet)
|
197
|
-
mkdir_p(output_pages,quiet)
|
198
177
|
end
|
199
178
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
output("
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
FileList[absolute_assets_list].each do |file|
|
209
|
-
cp_r(file, temp_pages, quiet)
|
210
|
-
end
|
179
|
+
##
|
180
|
+
#
|
181
|
+
#
|
182
|
+
def init
|
183
|
+
output("Initialize files & output directories ...")
|
184
|
+
output_fullsite = File.join(absolute_output_path, '/fullsite')
|
185
|
+
output_pages = File.join(absolute_output_path, '/pages')
|
186
|
+
output_assets = File.join(absolute_output_path, '/assets')
|
211
187
|
|
212
|
-
|
213
|
-
|
188
|
+
mkdir_p(absolute_output_path, quiet)
|
189
|
+
mkdir_p(output_pages,quiet)
|
190
|
+
mkdir_p(output_assets,quiet)
|
191
|
+
mkdir_p(output_fullsite,quiet)
|
214
192
|
|
215
|
-
|
216
|
-
|
193
|
+
fullsite_config = parameters['fullsite']
|
194
|
+
background_image = File.join(absolute_working_path, fullsite_config['background_image'])
|
195
|
+
cp_r(background_image, absolute_cover_page, quiet)
|
217
196
|
|
218
|
-
|
219
|
-
if content =~ YAML_FRONT_MATTER_REGEXP
|
220
|
-
#content = $POSTMATCH
|
221
|
-
front_matter = SafeYAML.load(Regexp.last_match(1))
|
222
|
-
end
|
197
|
+
File.open(absolute_theme_pdf, "w") { |file| file.write(getPdfTheme() ) }
|
223
198
|
|
224
|
-
|
225
|
-
|
226
|
-
if front_matter.key?('permalink')
|
227
|
-
output = File.join(temp_links, front_matter['permalink'] + '.adoc')
|
228
|
-
else
|
229
|
-
output = File.join(temp_links, File.basename(file))
|
230
|
-
end
|
231
|
-
# Write the auxiliary file for combine later in the full pdf file
|
232
|
-
File.write(output, result)
|
199
|
+
end
|
233
200
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
201
|
+
##
|
202
|
+
#
|
203
|
+
#
|
204
|
+
def undo_init
|
205
|
+
output("Removing auxiliaries files & directories ...")
|
206
|
+
output_assets = File.join(absolute_output_path, '/assets')
|
207
|
+
rm_rf(output_assets, quiet)
|
238
208
|
end
|
239
209
|
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
210
|
+
##
|
211
|
+
# Loop over each AsciiDoctor file recursively
|
212
|
+
#
|
213
|
+
# Steps:
|
214
|
+
#
|
215
|
+
# 1. Read the file
|
216
|
+
# 2. Remove jekyll fronmatter
|
217
|
+
# 3. Generate a PDF with the content and put it in <output>/pages/[<subfolder>]/<filename>.pdf
|
218
|
+
# 4. Get the 'permalink' and add the content to a hash to be used by sidebar process
|
219
|
+
#
|
220
|
+
# Warning: We should keep the original directory structure to avoid name collisions
|
221
|
+
#
|
222
|
+
def generate_individual_pdf
|
244
223
|
|
245
|
-
FileList[temp_pages + "/*.adoc"].each do |file|
|
246
|
-
Asciidoctor.convert_file file, backend: 'pdf', doctype: 'article', to_dir: pdf_pages , mkdirs: true, safe: :safe
|
247
|
-
end
|
248
|
-
end
|
249
224
|
|
250
|
-
|
225
|
+
output("Generating content for each individual pages")
|
251
226
|
|
252
|
-
|
253
|
-
toc = YAML.load_file(absolute_sidebar_file)
|
227
|
+
pdf_pages = File.join(absolute_output_path, '/pages')
|
254
228
|
|
255
|
-
|
229
|
+
cd absolute_source_path
|
230
|
+
FileList["**/*.adoc"].each do |file|
|
256
231
|
|
257
|
-
|
232
|
+
output_path = File.join(pdf_pages,File.dirname(file))
|
233
|
+
mkdir_p_if_not_exist(output_path)
|
258
234
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
235
|
+
JekyllAsciidoctorPdf::ADoc.generatePdf(fullsite_title, file,pdf_pages, parameters, absolute_cover_page, absolute_theme_pdf ) do |front_matter, stream_adoc|
|
236
|
+
if front_matter.key?('permalink')
|
237
|
+
name = File.join('/', front_matter['permalink'])
|
238
|
+
data = PermalinkData.new(front_matter['sidebar'], stream_adoc, file)
|
239
|
+
permalinks[name] = data
|
240
|
+
end
|
241
|
+
end
|
263
242
|
|
264
|
-
temp_links = File.join(absolute_temp_path, '/links')
|
265
|
-
output = File.join(absolute_temp_path,'fullsite.adoc')
|
266
|
-
File.write(output, Tree.updateContent(tree, temp_links))
|
267
243
|
|
268
|
-
|
244
|
+
end
|
269
245
|
|
270
246
|
end
|
271
247
|
|
272
|
-
def generate_fullsite_pdf
|
273
248
|
|
274
|
-
|
275
|
-
|
276
|
-
|
249
|
+
##
|
250
|
+
# Loop over each YAML file in the sidebar_path
|
251
|
+
#
|
252
|
+
# Steps:
|
253
|
+
# - Execute generateContent to create all sections and one file with the whole content of the sitebar
|
254
|
+
#
|
255
|
+
# Output directories:
|
256
|
+
#
|
257
|
+
# <output_path>
|
258
|
+
# |__ <sidebar>/<section>.pdf -> Section output
|
259
|
+
# |__ fullsite/fullsite_<sidebar>.pdf -> whole sidebar content (a.k.a. fullsite PDF)
|
260
|
+
#
|
261
|
+
def generate_fullsite_adoc
|
277
262
|
|
278
|
-
fullsite_config = parameters['fullsite']
|
279
|
-
background_image = File.join(absolute_working_path, fullsite_config['background_image'])
|
280
|
-
output_background_image = File.join(absolute_temp_path, '/media', 'cover_page_background.jpg')
|
281
|
-
cp_r(background_image, output_background_image, quiet)
|
282
263
|
|
264
|
+
FileList[absolute_sidebar_path + "*.yml"].each do |file|
|
265
|
+
output("Generating content for " + File.basename(file))
|
266
|
+
|
267
|
+
name = File.basename(file).ext('')
|
283
268
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
269
|
+
JekyllAsciidoctorPdf::SidebarYAML.new(
|
270
|
+
fullsite_title,
|
271
|
+
name,
|
272
|
+
file,
|
273
|
+
permalinks,
|
274
|
+
parameters,
|
275
|
+
absolute_output_path,
|
276
|
+
absolute_source_path,
|
277
|
+
absolute_cover_page,
|
278
|
+
absolute_theme_pdf
|
279
|
+
)
|
290
280
|
|
291
|
-
|
292
|
-
cp_r('fullsite_template.pdf',absolute_output_path, quiet)
|
293
|
-
output("Full site PDF generated in [ " + output +" ]")
|
281
|
+
#cd absolute_working_path
|
294
282
|
|
283
|
+
#sidebar.generatePdf()
|
284
|
+
|
285
|
+
end
|
295
286
|
end
|
296
287
|
|
288
|
+
|
289
|
+
##
|
290
|
+
# Assert function
|
291
|
+
#
|
297
292
|
def assert(condition, message)
|
298
293
|
if not condition
|
299
294
|
output(message)
|
@@ -301,74 +296,28 @@ module JekyllAsciidoctorPdf
|
|
301
296
|
end
|
302
297
|
end
|
303
298
|
|
304
|
-
|
305
|
-
#
|
306
|
-
|
307
|
-
|
299
|
+
##
|
300
|
+
# Create a directory only if its necessary
|
301
|
+
#
|
302
|
+
def mkdir_p_if_not_exist(dir)
|
303
|
+
mkdir_p(dir, quiet) unless File.exists?(dir)
|
308
304
|
end
|
309
305
|
|
310
|
-
def getFullsiteTemplate()
|
311
|
-
fullsite_config = parameters['fullsite']
|
312
|
-
|
313
|
-
title = fullsite_config['title']
|
314
|
-
subtitle = fullsite_config['subtitle']
|
315
|
-
authors = fullsite_config['authors']
|
316
|
-
revision = fullsite_config['revision']
|
317
|
-
#background_image = fullsite_config['background_image']
|
318
|
-
|
319
|
-
text = <<~TEXT
|
320
|
-
= #{title} : #{subtitle}
|
321
|
-
#{authors}
|
322
|
-
#{revision}
|
323
|
-
:doctype: book
|
324
|
-
:experimental:
|
325
|
-
:reproducible:
|
326
|
-
:icons: font
|
327
|
-
:listing-caption: Listing
|
328
|
-
:sectnums:
|
329
|
-
:imagesdir: ./media/
|
330
|
-
:toc:
|
331
|
-
:toclevels: 2
|
332
|
-
ifeval::["{asciidoctor-version}" < "1.5.7"]
|
333
|
-
:legacy-footnoteref:
|
334
|
-
endif::[]
|
335
|
-
ifdef::backend-pdf[]
|
336
|
-
:pdf-theme: pdf-theme.yml
|
337
|
-
:title-page:
|
338
|
-
:title-page-background-image: image:cover_page_background.jpg[fit=none,pdfwidth=100%,position=top]
|
339
|
-
:source-highlighter: rouge
|
340
|
-
//:rouge-style: github
|
341
|
-
endif::[]
|
342
|
-
:chapter-label:
|
343
|
-
|
344
|
-
:leveloffset: +1
|
345
|
-
include::fullsite.adoc[]
|
346
|
-
:leveloffset: -1
|
347
|
-
TEXT
|
348
|
-
|
349
|
-
return text
|
350
|
-
end
|
351
306
|
|
307
|
+
|
308
|
+
##
|
309
|
+
# Load the asciidoctor-pdf theme from the jekyll _config.yml
|
310
|
+
#
|
352
311
|
def getPdfTheme()
|
353
312
|
return parameters['pdf_theme'].to_yaml
|
354
313
|
end
|
355
314
|
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
else
|
362
|
-
if child['url'].downcase.start_with?('http:') or child['url'].downcase.start_with?('https:')
|
363
|
-
output("Absolute links are not supported!")
|
364
|
-
else
|
365
|
-
root_node.add_child(Tree::Node.new(child['title'],child['url'], '', false))
|
366
|
-
end
|
367
|
-
end
|
368
|
-
end
|
315
|
+
def output(string)
|
316
|
+
puts ' * ' + string
|
317
|
+
end
|
318
|
+
|
319
|
+
|
369
320
|
|
370
|
-
return root_node
|
371
|
-
end
|
372
321
|
|
373
322
|
end
|
374
323
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
module JekyllAsciidoctorPdf
|
3
|
+
|
4
|
+
##
|
5
|
+
# Abstract structure for a hash dictionary
|
6
|
+
#
|
7
|
+
# We use to create a dictionary of all permalinks a its content (without frontmatter)
|
8
|
+
#
|
9
|
+
class PermalinkData
|
10
|
+
attr_reader :sidebar, :content, :filename
|
11
|
+
def initialize(sidebar, content, filename)
|
12
|
+
@sidebar = sidebar
|
13
|
+
@content = content
|
14
|
+
@filename = filename
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
require 'tmpdir'
|
4
|
+
|
5
|
+
require 'yaml'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'asciidoctor-pdf'
|
8
|
+
require 'asciidoctor'
|
9
|
+
|
10
|
+
require 'jekyll_asciidoctor_pdf/logger'
|
11
|
+
|
12
|
+
|
13
|
+
module JekyllAsciidoctorPdf
|
14
|
+
##
|
15
|
+
# General Tree Data Structure
|
16
|
+
#
|
17
|
+
class SidebarEntry
|
18
|
+
attr_reader :children, :content, :page, :title, :root
|
19
|
+
|
20
|
+
def initialize(title, page, content, root)
|
21
|
+
@children = []
|
22
|
+
@root = root
|
23
|
+
@page = page
|
24
|
+
@title = title
|
25
|
+
@content = content
|
26
|
+
end
|
27
|
+
|
28
|
+
def add_content(content)
|
29
|
+
@content << "\n"
|
30
|
+
@content << content
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_child(child)
|
34
|
+
@children << child
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
##
|
41
|
+
# Data Structure that hold the information of an specific sidebar and generate content with that
|
42
|
+
#
|
43
|
+
# TODO:
|
44
|
+
# In order to generalize the directory structure we need to
|
45
|
+
#
|
46
|
+
# - add a base_path with the relative path root of all *.adoc files
|
47
|
+
# - add a prefix_permanlink to get that front_matter.permalink = prefix_permalink + sidebar.url
|
48
|
+
#
|
49
|
+
class SidebarYAML
|
50
|
+
|
51
|
+
attr_reader :title, :name, :file, :permalinks, :parameters, :section_output_path, :sidebar_output_path, :base_path, :cover_page, :theme_pdf
|
52
|
+
|
53
|
+
|
54
|
+
def initialize(title, name, file, permalinks, parameters, output_path, base_path, cover_page, theme_pdf )
|
55
|
+
@title = title
|
56
|
+
@name = name
|
57
|
+
@file = file
|
58
|
+
@permalinks = permalinks
|
59
|
+
@parameters = parameters
|
60
|
+
@base_path = base_path
|
61
|
+
@cover_page = cover_page
|
62
|
+
@theme_pdf = theme_pdf
|
63
|
+
|
64
|
+
@section_output_path = File.join(output_path,name)
|
65
|
+
@sidebar_output_path = File.join(output_path,'/fullsite')
|
66
|
+
|
67
|
+
FileUtils::mkdir_p(section_output_path)
|
68
|
+
FileUtils::mkdir_p(sidebar_output_path)
|
69
|
+
|
70
|
+
toc = YAML.load_file(file)
|
71
|
+
loadAndProcess('Root', toc['entries'], true)
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
##
|
78
|
+
# We always call this function with a section or the whole sidebar (in a branch of the Tree Structure)
|
79
|
+
#
|
80
|
+
#
|
81
|
+
def loadAndProcess(name, children, root)
|
82
|
+
output("- Process " + name)
|
83
|
+
node = JekyllAsciidoctorPdf::SidebarEntry.new(name, '','',root)
|
84
|
+
|
85
|
+
# In the section level, we will display the title
|
86
|
+
# and increase the section level for the content
|
87
|
+
if not root
|
88
|
+
node.add_content("= " + node.title + "\n")
|
89
|
+
node.add_content(":leveloffset: +1 \n")
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Loop over the children
|
94
|
+
#
|
95
|
+
# Case 1:
|
96
|
+
# - We are in a section (handled by recursion over the tree)
|
97
|
+
# - Add the content in the 'node' (father) and continue
|
98
|
+
# Case 2:
|
99
|
+
# - We are in a leaf
|
100
|
+
# - Avoid absolute URL or not found permalink
|
101
|
+
# - Add the content in the 'node' (father) and continue
|
102
|
+
#
|
103
|
+
children.each do |child|
|
104
|
+
page = child['url']
|
105
|
+
title = child['title']
|
106
|
+
entries = child['entries']
|
107
|
+
|
108
|
+
if child.key?('entries')
|
109
|
+
##
|
110
|
+
# We are in a section
|
111
|
+
#
|
112
|
+
ret = loadAndProcess(title, entries,false)
|
113
|
+
node.add_child(ret)
|
114
|
+
node.add_content(ret.content)
|
115
|
+
else
|
116
|
+
##
|
117
|
+
# We are in a leaf of the tree
|
118
|
+
#
|
119
|
+
if page.downcase.start_with?('http:') or page.downcase.start_with?('https:')
|
120
|
+
# We ignore absolute links
|
121
|
+
output("Absolute links are not supported!")
|
122
|
+
else
|
123
|
+
if permalinks.key?(page)
|
124
|
+
# We have the content
|
125
|
+
node.add_child(JekyllAsciidoctorPdf::SidebarEntry.new(title,page, permalinks[page].content, false))
|
126
|
+
node.add_content(permalinks[page].content)
|
127
|
+
else
|
128
|
+
# We don't have the content
|
129
|
+
node.add_child(JekyllAsciidoctorPdf::SidebarEntry.new(title,page, "= Page not found "+ page + "\n", false))
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# We need to generate the content for the whole section or the whole sidebar
|
137
|
+
if not root
|
138
|
+
# This is a section
|
139
|
+
node.add_content(":leveloffset: -1 \n")
|
140
|
+
filename = node.title.gsub(/[^0-9A-Z]/i, '_') + '.pdf'
|
141
|
+
|
142
|
+
JekyllAsciidoctorPdf::ADoc.generateBookTypePdf(filename, section_output_path, title, node.title, base_path, node.content, parameters, cover_page, theme_pdf)
|
143
|
+
else
|
144
|
+
# This is the root of the sidebar
|
145
|
+
subtitle = 'Docs'
|
146
|
+
filename = File.basename(file).ext('.pdf')
|
147
|
+
filename_path = sidebar_output_path
|
148
|
+
|
149
|
+
JekyllAsciidoctorPdf::ADoc.generateBookTypePdf(filename, filename_path, title, subtitle, base_path, node.content, parameters, cover_page, theme_pdf)
|
150
|
+
end
|
151
|
+
|
152
|
+
return node
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# Print a tree structure
|
158
|
+
#
|
159
|
+
def self.printTree(tree, level)
|
160
|
+
puts str = ("-" * level) + tree.title
|
161
|
+
if tree.children.length > 0
|
162
|
+
tree.children.map { |child| printTree(child, level + 1) }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def output(string)
|
167
|
+
puts ' * ' + string
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll_asciidoctor_pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guido Genzone
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -124,8 +124,11 @@ files:
|
|
124
124
|
- bin/setup
|
125
125
|
- jekyll_asciidoctor_pdf.gemspec
|
126
126
|
- lib/jekyll_asciidoctor_pdf.rb
|
127
|
+
- lib/jekyll_asciidoctor_pdf/adoc.rb
|
127
128
|
- lib/jekyll_asciidoctor_pdf/commands.rb
|
128
|
-
- lib/jekyll_asciidoctor_pdf/
|
129
|
+
- lib/jekyll_asciidoctor_pdf/logger.rb
|
130
|
+
- lib/jekyll_asciidoctor_pdf/permalink.rb
|
131
|
+
- lib/jekyll_asciidoctor_pdf/sidebar.rb
|
129
132
|
- lib/jekyll_asciidoctor_pdf/version.rb
|
130
133
|
homepage: https://rubygems.org/gems/jekyll_asciidoctor_pdf
|
131
134
|
licenses:
|
@@ -1,71 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
module Tree
|
5
|
-
|
6
|
-
class Node
|
7
|
-
attr_reader :children, :content, :page, :title, :root
|
8
|
-
|
9
|
-
def initialize(title, page, content, root)
|
10
|
-
@children = []
|
11
|
-
@root = root
|
12
|
-
@page = page
|
13
|
-
@title = title
|
14
|
-
@content = content
|
15
|
-
end
|
16
|
-
|
17
|
-
def add_content(content)
|
18
|
-
@content << "\n"
|
19
|
-
@content << content
|
20
|
-
end
|
21
|
-
|
22
|
-
def add_child(child)
|
23
|
-
@children << child
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
def traverse_subtree(&block)
|
28
|
-
node_queue = [self] # Step 1
|
29
|
-
until node_queue.empty? # Step 2
|
30
|
-
node = node_queue.shift # Step 3
|
31
|
-
yield node # Step 4
|
32
|
-
node_queue = node.children.concat(node_queue) # Step 5
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.updateContent(tree, temp_dir)
|
39
|
-
if tree.page.length > 0
|
40
|
-
file = File.join(temp_dir, tree.page + '.adoc')
|
41
|
-
tree.add_content(File.read(file))
|
42
|
-
else
|
43
|
-
if not tree.root
|
44
|
-
tree.add_content("= " + tree.title)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
if not tree.root
|
49
|
-
tree.add_content(":leveloffset: +1 \n")
|
50
|
-
end
|
51
|
-
|
52
|
-
if tree.children.length > 0
|
53
|
-
tree.children.map { |child| tree.add_content(updateContent(child, temp_dir)) }
|
54
|
-
end
|
55
|
-
|
56
|
-
if not tree.root
|
57
|
-
tree.add_content(":leveloffset: -1 \n")
|
58
|
-
end
|
59
|
-
return tree.content
|
60
|
-
end
|
61
|
-
def self.printTree(tree, level)
|
62
|
-
puts str = ("-" * level) + tree.title
|
63
|
-
if tree.children.length > 0
|
64
|
-
tree.children.map { |child| printTree(child, level + 1) }
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
|
-
|