ffnpdf 0.0.3 → 0.0.4
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.
- data/README.md +8 -2
- data/lib/ffnpdf.rb +1 -0
- data/lib/ffnpdf/chapter.rb +71 -0
- data/lib/ffnpdf/story.rb +14 -49
- data/lib/ffnpdf/version.rb +1 -1
- data/release_notes.md +5 -0
- data/spec/ffnpdf/chapter_spec.rb +4 -0
- data/spec/ffnpdf_spec.rb +1 -1
- metadata +19 -16
data/README.md
CHANGED
@@ -52,7 +52,7 @@ This command
|
|
52
52
|
* combines all `.md` files to a single file, `combined.md`, in alphabetical order
|
53
53
|
* converts `combined.md` to `combined.pdf` while using both the template and variables file
|
54
54
|
|
55
|
-
###
|
55
|
+
### Convert
|
56
56
|
|
57
57
|
ffnpdf convert [STORY_ID]
|
58
58
|
|
@@ -60,8 +60,14 @@ This command does only the second step of the Build i.e. converts `combined.md`
|
|
60
60
|
|
61
61
|
## Known Issues
|
62
62
|
|
63
|
-
**Line following a horizontal line (
|
63
|
+
**Line following a horizontal line (\<hr\>) is missing**
|
64
64
|
|
65
65
|
This is a problem with FF.net's rendering of stories, especially in older ones.
|
66
66
|
|
67
67
|
At the moment, the only fix is to manually edit the `.md` files to add the missing lines.
|
68
|
+
|
69
|
+
**Page numbering in bookmark is incorrect for stories with long Table of Contents**
|
70
|
+
|
71
|
+
It's a tradeoff between wrong numbering in the Table of Contents or in the bookmarks. I chose the latter.
|
72
|
+
|
73
|
+
I still don't know the root cause, though.
|
data/lib/ffnpdf.rb
CHANGED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Ffnpdf
|
6
|
+
class Chapter
|
7
|
+
|
8
|
+
attr_accessor :story_url, :chapter, :doc
|
9
|
+
|
10
|
+
def initialize(story_url, chapter)
|
11
|
+
self.story_url = story_url
|
12
|
+
self.chapter = chapter
|
13
|
+
end
|
14
|
+
|
15
|
+
def pull_and_convert
|
16
|
+
pull_chapter
|
17
|
+
convert_to_md
|
18
|
+
end
|
19
|
+
|
20
|
+
def pull_chapter
|
21
|
+
puts "pulling chapter #{chapter}"
|
22
|
+
pull = HTTParty.get(story_url)
|
23
|
+
self.doc = Nokogiri::HTML(pull.body)
|
24
|
+
content = doc.css(".storytext")[0].inner_html
|
25
|
+
content = content.gsub(/<div class.*?\/div>/m, "")
|
26
|
+
content = content.gsub(/<hr.*>/, "<hr/><p>")
|
27
|
+
puts "saving as #{padded_ch}.html"
|
28
|
+
tempfile = File.new("#{padded_ch}.html", "w")
|
29
|
+
tempfile.puts(content)
|
30
|
+
tempfile.close
|
31
|
+
end
|
32
|
+
|
33
|
+
def convert_to_md
|
34
|
+
puts "converting #{padded_ch}.html to #{padded_ch}.md"
|
35
|
+
Converter.exec("pandoc #{padded_ch}.html -o #{padded_ch}.md")
|
36
|
+
|
37
|
+
if chapter ==1 or chapter_title
|
38
|
+
tempfile = File.new("#{padded_ch}.temp", "w")
|
39
|
+
if chapter == 1
|
40
|
+
tempfile.puts "\\pagenumbering{arabic}"
|
41
|
+
tempfile.puts "\\setcounter{page}{1}"
|
42
|
+
tempfile.puts
|
43
|
+
end
|
44
|
+
|
45
|
+
if (chapter_title)
|
46
|
+
tempfile.puts "\#\# #{chapter_title}"
|
47
|
+
tempfile.puts
|
48
|
+
end
|
49
|
+
IO.foreach("#{padded_ch}.md") do |line|
|
50
|
+
tempfile.puts line
|
51
|
+
end
|
52
|
+
tempfile.close
|
53
|
+
FileUtils.rm("#{padded_ch}.md")
|
54
|
+
File.rename("#{padded_ch}.temp", "#{padded_ch}.md")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def padded_ch
|
59
|
+
"%04d" % chapter
|
60
|
+
end
|
61
|
+
|
62
|
+
def chapter_title
|
63
|
+
if doc.xpath('//form//select[@name="chapter"]/option').count > 1
|
64
|
+
doc.xpath('//form//select[@name="chapter"]/option')[chapter - 1].text.gsub(/^[\d]*?\. /, "")
|
65
|
+
else
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
data/lib/ffnpdf/story.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'httparty'
|
2
2
|
require 'nokogiri'
|
3
3
|
require 'fileutils'
|
4
|
-
require 'open3'
|
5
4
|
|
6
5
|
module Ffnpdf
|
7
6
|
class Story
|
@@ -67,43 +66,23 @@ module Ffnpdf
|
|
67
66
|
FileUtils.mkdir_p @story_id
|
68
67
|
Dir.chdir @story_id
|
69
68
|
|
70
|
-
|
71
|
-
|
72
|
-
pull = HTTParty.get(story_url)
|
73
|
-
doc = Nokogiri::HTML(pull.body)
|
74
|
-
doc.css(".storytext")[0].children.each do |paragraph|
|
75
|
-
if /^<(p|hr|i|b)/.match paragraph.to_s
|
76
|
-
tempfile.puts paragraph
|
77
|
-
end
|
78
|
-
end
|
79
|
-
tempfile.close
|
69
|
+
chapter1 = Chapter.new(story_url, 1)
|
70
|
+
chapter1.pull_and_convert
|
80
71
|
|
81
|
-
|
72
|
+
doc = chapter1.doc
|
82
73
|
|
83
74
|
title = doc.xpath("//div/div/b")[0].text
|
84
75
|
author = doc.xpath("//div/table//a[not(@title or @onclick)]")[0].text
|
85
76
|
|
86
77
|
generate_template(title, author, get_doc_date(doc))
|
87
78
|
generate_variables_file
|
88
|
-
generate_title_page
|
79
|
+
generate_title_page(chapter1.chapter_title)
|
89
80
|
|
90
81
|
chapters = doc.xpath('//form//select[@name="chapter"]/option').count
|
91
|
-
if chapters > 1
|
92
|
-
append_header_to_ch1
|
93
82
|
|
83
|
+
if chapters > 1
|
94
84
|
(2..chapters).each do |chapter|
|
95
|
-
|
96
|
-
tempfile = File.new("temp.html", "w")
|
97
|
-
tempfile.puts "<h2>Chapter #{chapter}</h2>"
|
98
|
-
pull = HTTParty.get("#{story_url}#{chapter}/")
|
99
|
-
doc = Nokogiri::HTML(pull.body)
|
100
|
-
doc.css(".storytext")[0].children.each do |paragraph|
|
101
|
-
if /^<(p|hr|i|b)/.match paragraph.to_s
|
102
|
-
tempfile.puts paragraph
|
103
|
-
end
|
104
|
-
end
|
105
|
-
tempfile.close
|
106
|
-
Converter.exec("pandoc temp.html -o #{"%04d" % chapter}.md")
|
85
|
+
Chapter.new("#{story_url}#{chapter}/", chapter).pull_and_convert
|
107
86
|
end
|
108
87
|
end
|
109
88
|
Dir.chdir "../"
|
@@ -126,7 +105,6 @@ module Ffnpdf
|
|
126
105
|
% Shamelessly ripped off from https://github.com/karlseguin/the-little-mongodb-book
|
127
106
|
\\documentclass[$fontsize$,$columns$]{book}
|
128
107
|
\\usepackage{fullpage}
|
129
|
-
\\usepackage{changepage}
|
130
108
|
\\usepackage{fontspec,xltxtra,xunicode}
|
131
109
|
\\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
|
132
110
|
\\setmainfont{$mainfont$}
|
@@ -138,7 +116,7 @@ module Ffnpdf
|
|
138
116
|
\\linespread{1.2}
|
139
117
|
|
140
118
|
\\usepackage{listings}
|
141
|
-
\\usepackage[dvipsnames,usenames]{
|
119
|
+
\\usepackage[dvipsnames,usenames]{xcolor}
|
142
120
|
|
143
121
|
$if(fancy-enums)$
|
144
122
|
\\usepackage{enumerate}
|
@@ -171,31 +149,18 @@ $body$
|
|
171
149
|
variables.close
|
172
150
|
end
|
173
151
|
|
174
|
-
def generate_title_page
|
152
|
+
def generate_title_page(has_toc = true)
|
175
153
|
title_page = File.new("0000.md", "w")
|
176
|
-
|
177
|
-
|
154
|
+
title = "\\maketitle\n"
|
155
|
+
if has_toc
|
156
|
+
title += <<-CONTENTS
|
178
157
|
\\pagenumbering{roman}
|
179
158
|
\\tableofcontents
|
180
159
|
|
181
|
-
|
182
|
-
title_page.puts(contents)
|
183
|
-
title_page.close
|
184
|
-
end
|
185
|
-
|
186
|
-
def append_header_to_ch1
|
187
|
-
chapter1 = File.new("0001.temp", "w")
|
188
|
-
chapter1.puts "\\pagenumbering{arabic}"
|
189
|
-
chapter1.puts "\\setcounter{page}{1}"
|
190
|
-
chapter1.puts
|
191
|
-
chapter1.puts "\#\# Chapter 1"
|
192
|
-
chapter1.puts
|
193
|
-
IO.foreach("0001.md") do |line|
|
194
|
-
chapter1.puts line
|
160
|
+
CONTENTS
|
195
161
|
end
|
196
|
-
|
197
|
-
|
198
|
-
File.rename("0001.temp", "0001.md")
|
162
|
+
title_page.puts(title)
|
163
|
+
title_page.close
|
199
164
|
end
|
200
165
|
|
201
166
|
def build_story
|
data/lib/ffnpdf/version.rb
CHANGED
data/release_notes.md
ADDED
data/spec/ffnpdf_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffnpdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &69050000 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *69050000
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: test_notifier
|
27
|
-
requirement: &
|
27
|
+
requirement: &69049700 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *69049700
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: autotest
|
38
|
-
requirement: &
|
38
|
+
requirement: &69049490 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *69049490
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: nokogiri
|
49
|
-
requirement: &
|
49
|
+
requirement: &69049040 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *69049040
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: httparty
|
60
|
-
requirement: &
|
60
|
+
requirement: &69048540 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *69048540
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: nokogiri
|
71
|
-
requirement: &
|
71
|
+
requirement: &69048190 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *69048190
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: httparty
|
82
|
-
requirement: &
|
82
|
+
requirement: &69047890 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *69047890
|
91
91
|
description: Scrapes a story off FF.net, converts it to Markdown, and turns it to
|
92
92
|
PDF with LaTeX
|
93
93
|
email:
|
@@ -106,10 +106,13 @@ files:
|
|
106
106
|
- bin/ffnpdf
|
107
107
|
- ffnpdf.gemspec
|
108
108
|
- lib/ffnpdf.rb
|
109
|
+
- lib/ffnpdf/chapter.rb
|
109
110
|
- lib/ffnpdf/converter.rb
|
110
111
|
- lib/ffnpdf/exec.rb
|
111
112
|
- lib/ffnpdf/story.rb
|
112
113
|
- lib/ffnpdf/version.rb
|
114
|
+
- release_notes.md
|
115
|
+
- spec/ffnpdf/chapter_spec.rb
|
113
116
|
- spec/ffnpdf/converter_spec.rb
|
114
117
|
- spec/ffnpdf/exec_spec.rb
|
115
118
|
- spec/ffnpdf/story_spec.rb
|