ffnpdf 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .*.sw[a-z]
6
+ *.un~
7
+ Session.vim
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format nested
2
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ffnpdf.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # FFNPDF
2
+
3
+ Just scratched an coding itch I've had for quite some time.
4
+
5
+ This gem scrapes stories from FanFiction.net and generates LaTeX PDFs. Polished turds, anyone?
6
+
7
+ ## Installation
8
+
9
+ To install this stupid gem:
10
+
11
+ gem install ffnpdf
12
+
13
+ It also requires [pandoc](http://johnmacfarlane.net/pandoc/) as well as a bunch of extra stuff related to LaTeX/XeTeX. In Ubuntu, you can install this using the following command:
14
+
15
+ sudo apt-get install pandoc texlive-latex-extra texlive-xetex
16
+
17
+ It also uses [DejaVu Fonts](http://dejavu-fonts.org/wiki/Main_Page) as the default font. This font family is installed by default in Ubuntu.
18
+
19
+ ## Usage
20
+
21
+ The basic command only requires the story's story ID.
22
+
23
+ ffnpdf [STORY_ID]
24
+
25
+ This will scrape FFN for the story, convert the chapters into markdown, combine all chapters into a single file, and converts it into PDF, all inside the `STORY_ID` folder.
26
+
27
+ ## Additional Commands
28
+
29
+ Since you may want to do your own edits to the fics (e.g. remove authors notes, correct chapter headers) there are additional commands that allow you to perform individual steps of the process.
30
+
31
+ ### Pull
32
+
33
+ ffnpdf pull [STORY_ID]
34
+
35
+ This command
36
+
37
+ * creates the `STORY_ID` folder
38
+ * pulls chapters and converts them to Markdown
39
+ * creates template and variables (config) file
40
+
41
+ The markdown files are numbered from `0001.md` onwards. A title section, `0000.md`, is also created.
42
+
43
+ The `xetex.template` file is obviously the XeTeX template, while the `variables.txt` defines the [template variables section](http://johnmacfarlane.net/pandoc/README.html#general-writer-options) used when generating the PDF. Both can be modified to affect the result of running both `ffnpdf build` and `ffnpdf convert`.
44
+
45
+
46
+ ### Build
47
+
48
+ ffnpdf build [STORY_ID]
49
+
50
+ This command
51
+
52
+ * combines all `.md` files to a single file, `combined.md`, in alphabetical order
53
+ * converts `combined.md` to `combined.pdf` while using both the template and variables file
54
+
55
+ ### Build
56
+
57
+ ffnpdf convert [STORY_ID]
58
+
59
+ This command does only the second step of the Build i.e. converts `combined.md` to `combined.pdf`.
60
+
61
+ ## Troubleshooting
62
+
63
+ **Table of Contents don't match the actual pages of the chapters.**
64
+
65
+ [This is a LaTeX issue](http://tex.stackexchange.com/a/30946). Just rerun the `ffnpdf convert` command to rebuild the PDF.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1 @@
1
+ Autotest.add_discovery { "rspec2" }
data/bin/ffnpdf ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
+ require 'ffnpdf'
4
+
5
+ Ffnpdf::Exec.new(ARGV)
data/ffnpdf.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ffnpdf/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ffnpdf"
7
+ s.version = Ffnpdf::VERSION
8
+ s.authors = ["Bryan Bibat"]
9
+ s.email = ["bry@bryanbibat.net"]
10
+ s.homepage = "https://github.com/bryanbibat/ffnpdf"
11
+ s.summary = %q{PDF generator for FF.net stories}
12
+ s.description = %q{Scrapes a story off FF.net, converts it to Markdown, and turns it to PDF with LaTeX}
13
+
14
+ s.rubyforge_project = "ffnpdf"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rspec"
23
+ s.add_development_dependency "test_notifier"
24
+ s.add_development_dependency "autotest"
25
+ s.add_development_dependency "nokogiri"
26
+ s.add_development_dependency "httparty"
27
+ s.add_runtime_dependency "nokogiri"
28
+ s.add_runtime_dependency "httparty"
29
+ end
data/lib/ffnpdf.rb ADDED
@@ -0,0 +1,8 @@
1
+ require "ffnpdf/version"
2
+ require "ffnpdf/exec"
3
+ require "ffnpdf/story"
4
+ require "ffnpdf/converter"
5
+
6
+ module Ffnpdf
7
+ # Your code goes here...
8
+ end
@@ -0,0 +1,16 @@
1
+ module Ffnpdf
2
+ class Converter
3
+ def self.exec(command)
4
+ `#{command}`
5
+ end
6
+
7
+ def self.convert_to_pdf(story_id)
8
+ Dir.chdir story_id
9
+
10
+ command = "markdown2pdf --xetex --template=xetex.template --toc #{IO.readlines("variables.txt")[0].strip} combined.md"
11
+ Converter.exec(command)
12
+
13
+ Dir.chdir "../"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,57 @@
1
+ module Ffnpdf
2
+ class Exec
3
+ def initialize(argv)
4
+ invalid = false
5
+ if argv.size == 0
6
+ invalid = true
7
+ elsif /^[\d]+$/.match argv[0]
8
+ story = Ffnpdf::Story.new(argv[0])
9
+ if story.check_story
10
+ story.pull_story
11
+ story.build_story
12
+ else
13
+ $stderr.puts story.error
14
+ end
15
+ elsif argv[0] == "pull" and /^[\d]+$/.match argv[1]
16
+ story = Ffnpdf::Story.new(argv[1])
17
+ if story.check_story
18
+ story.pull_story
19
+ else
20
+ $stderr.puts story.error
21
+ end
22
+ elsif argv[0] == "build" and /^[\d]+$/.match argv[1]
23
+ story = Ffnpdf::Story.new(argv[1])
24
+ if story.check_story_dir
25
+ story.build_story
26
+ else
27
+ $stderr.puts story.error
28
+ end
29
+ elsif argv[0] == "convert" and /^[\d]+$/.match argv[1]
30
+ story = Ffnpdf::Story.new(argv[1])
31
+ if story.check_story_dir
32
+ story.convert_to_pdf
33
+ else
34
+ $stderr.puts story.error
35
+ end
36
+ else
37
+ invalid = true
38
+ end
39
+
40
+ if invalid
41
+ $stderr.puts <<-MSG
42
+ Usage
43
+ ffnpdf [STORY_ID]
44
+ ffnpdf [COMMAND] [STORY_ID]
45
+
46
+ Description
47
+ Scrapes story from FanFiction.net and generates pdf at STORY_ID/ folder.
48
+
49
+ The following commands are available
50
+ pull scrapes story and puts the markdown and template files at STORY_ID/ folder
51
+ build compiles *.md files at STORY_ID/ into a single pdf
52
+ convert converts STORY_ID/combined.md to pdf using the template files
53
+ MSG
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,218 @@
1
+ require 'httparty'
2
+ require 'nokogiri'
3
+ require 'fileutils'
4
+ require 'open3'
5
+
6
+ module Ffnpdf
7
+ class Story
8
+ FFN_URL = "http://www.fanfiction.net/"
9
+
10
+ attr_accessor :custom_url, :error
11
+
12
+ def initialize(story_id)
13
+ @story_id = story_id
14
+ end
15
+
16
+ def check_story_id
17
+ unless /^[\d]*$/.match @story_id
18
+ @error = "Story ID is invalid"
19
+ return false
20
+ end
21
+ true
22
+ end
23
+
24
+ def check_story
25
+ return false unless check_story_id
26
+
27
+ test_pull = HTTParty.get(story_url)
28
+ unless test_pull.code == 200
29
+ @error = "Story does not exist (#{story_url})"
30
+ return false
31
+ end
32
+
33
+ unless Nokogiri::HTML(test_pull.body).css(".storytext")
34
+ @error = "Story does not exist (#{story_url})"
35
+ return false
36
+ end
37
+
38
+ true
39
+ end
40
+
41
+ def check_story_dir
42
+ return false unless check_story_id
43
+
44
+ unless File.directory?(@story_id)
45
+ @error = "Story folder does not exist (#{@story_id}/)"
46
+ return false
47
+ end
48
+
49
+ unless chapter_mds.count > 0
50
+ @error = "Story folder does not have markdown files (#{@story_id}/)"
51
+ return false
52
+ end
53
+
54
+ true
55
+ end
56
+
57
+ def chapter_mds
58
+ Dir["#{@story_id}/*"].grep(/.md$/).reject { |x| /combined.md$/.match x }.sort
59
+ end
60
+
61
+ def story_url
62
+ custom_url ? "#{@custom_url}s/#{@story_id}/" : "#{FFN_URL}s/#{@story_id}/"
63
+ end
64
+
65
+ def pull_story
66
+ return unless check_story
67
+ FileUtils.mkdir_p @story_id
68
+ Dir.chdir @story_id
69
+
70
+ tempfile = File.new("temp.html", "w")
71
+ pull = HTTParty.get(story_url)
72
+ doc = Nokogiri::HTML(pull.body)
73
+ doc.css(".storytext")[0].children.each do |paragraph|
74
+ if /^<(p|hr|i|b)/.match paragraph.to_s
75
+ tempfile.puts paragraph
76
+ end
77
+ end
78
+ tempfile.close
79
+
80
+ Converter.exec 'pandoc temp.html -o 0001.md'
81
+
82
+ title = doc.xpath("//div/div/b")[0].text
83
+ author = doc.xpath("//div/table//a[not(@title or @onclick)]")[0].text
84
+
85
+ generate_template(title, author, get_doc_date(doc))
86
+ generate_variables_file
87
+ generate_title_page
88
+
89
+ chapters = doc.xpath('//form//select[@name="chapter"]/option').count
90
+ if chapters > 1
91
+ append_header_to_ch1
92
+
93
+ (2..chapters).each do |chapter|
94
+ tempfile = File.new("temp.html", "w")
95
+ tempfile.puts "<h2>Chapter #{chapter}</h2>"
96
+ pull = HTTParty.get("#{story_url}#{chapter}/")
97
+ doc = Nokogiri::HTML(pull.body)
98
+ doc.css(".storytext")[0].children.each do |paragraph|
99
+ if /^<(p|hr|i|b)/.match paragraph.to_s
100
+ tempfile.puts paragraph
101
+ end
102
+ end
103
+ tempfile.close
104
+ Converter.exec("pandoc temp.html -o #{"%04d" % chapter}.md")
105
+ end
106
+ end
107
+ Dir.chdir "../"
108
+ end
109
+
110
+ def get_doc_date(doc)
111
+ parsing = doc.xpath('//div[@style="padding-left:1em;padding-right:1em;padding-top:0.5em;"]')[0].text
112
+ match = /Updated: (.{8})/.match parsing
113
+ if match
114
+ return Date.strptime(match[1], "%m-%d-%y").strftime("%d %B %Y")
115
+ else
116
+ match = /Published: (.{8})/.match parsing
117
+ return Date.strptime(match[1], "%m-%d-%y").strftime("%d %B %Y")
118
+ end
119
+ end
120
+
121
+ def generate_template(title, author, date)
122
+ template = File.new("xetex.template", "w")
123
+ contents = <<-CONTENTS
124
+ % Shamelessly ripped off from https://github.com/karlseguin/the-little-mongodb-book
125
+ \\documentclass[$fontsize$,$columns$]{book}
126
+ \\usepackage{fullpage}
127
+ \\usepackage{changepage}
128
+ \\usepackage{fontspec,xltxtra,xunicode}
129
+ \\defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
130
+ \\setmainfont{$mainfont$}
131
+ \\setsansfont{$sansfont$}
132
+ \\setmonofont{$monofont$}
133
+
134
+ \\setlength{\\parindent}{0pt}
135
+ \\setlength{\\parskip}{12pt plus 2pt minus 1pt}
136
+ \\linespread{1.2}
137
+
138
+ \\usepackage{listings}
139
+ \\usepackage[dvipsnames,usenames]{color}
140
+
141
+ $if(fancy-enums)$
142
+ \\usepackage{enumerate}
143
+ $endif$
144
+ \\setcounter{secnumdepth}{-1}
145
+
146
+ \\usepackage{hyperref}
147
+ \\hypersetup{
148
+ colorlinks=true,%
149
+ citecolor=Black,%
150
+ filecolor=Black,%
151
+ linkcolor=Black,%
152
+ urlcolor=Black
153
+ }
154
+
155
+ \\title{#{title}}
156
+ \\author{#{author}}
157
+ \\date{#{date}}
158
+ \\begin{document}
159
+ $body$
160
+ \\end{document}
161
+ CONTENTS
162
+ template.puts(contents)
163
+ template.close
164
+ end
165
+
166
+ def generate_variables_file
167
+ variables = File.new("variables.txt", "w")
168
+ variables.puts("-V paper=a4paper -V hmargin=3cm -V vmargin=3cm -V mainfont=\"DejaVu Serif\" -V sansfont=\"DejaVu Sans\" -V monofont=\"DejaVu Sans Mono\" -V geometry=portrait -V columns=onecolumn -V fontsize=11pt ")
169
+ variables.close
170
+ end
171
+
172
+ def generate_title_page
173
+ title_page = File.new("0000.md", "w")
174
+ contents = <<-CONTENTS
175
+ \\thispagestyle{empty}
176
+ \\maketitle
177
+ \\tableofcontents
178
+
179
+ CONTENTS
180
+ title_page.puts(contents)
181
+ title_page.close
182
+ end
183
+
184
+ def append_header_to_ch1
185
+ chapter1 = File.new("0001.temp", "w")
186
+ chapter1.puts "\#\# Chapter 1"
187
+ chapter1.puts
188
+ IO.foreach("0001.md") do |line|
189
+ chapter1.puts line
190
+ end
191
+ chapter1.close
192
+ FileUtils.rm("0001.md")
193
+ File.rename("0001.temp", "0001.md")
194
+ end
195
+
196
+ def build_story
197
+ return unless check_story_dir
198
+ combine_mds
199
+ convert_to_pdf
200
+ end
201
+
202
+ def combine_mds
203
+ combined = File.new("#{@story_id}/combined.md", "w")
204
+ chapter_mds.each do |chapter|
205
+ IO.foreach("#{chapter}") do |line|
206
+ combined.puts(line)
207
+ end
208
+ combined.puts("\\clearpage")
209
+ combined.puts()
210
+ end
211
+ combined.close
212
+ end
213
+
214
+ def convert_to_pdf
215
+ Converter.convert_to_pdf(@story_id)
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,3 @@
1
+ module Ffnpdf
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ffnpdf::Converter do
4
+ context "exec" do
5
+ it "should be able to run commands" do
6
+ Ffnpdf::Converter.exec("pwd")
7
+ end
8
+ it "should be able to run syncrhonously" do
9
+ Ffnpdf::Converter.exec("rm temp.txt")
10
+ Ffnpdf::Converter.exec("pwd > temp.txt")
11
+ File.exists?("temp.txt").should == true
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ffnpdf::Exec do
4
+ end
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ffnpdf::Story do
4
+
5
+ it "should create a story" do
6
+ story = Ffnpdf::Story.new("1234567")
7
+ story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
8
+ story.check_story.should == true
9
+ end
10
+
11
+ it "should allow setting custom url" do
12
+ story = Ffnpdf::Story.new("1234567")
13
+ story.story_url.should == "http://www.fanfiction.net/s/1234567/"
14
+ story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
15
+ story.story_url.should == "http://bryanbibat.github.com/ffnpdf-test/s/1234567/"
16
+ end
17
+
18
+ it "should check if story id is valid" do
19
+ blah = Ffnpdf::Story.new("blah")
20
+ blah.check_story.should == false
21
+ blah.error.should == "Story ID is invalid"
22
+ end
23
+
24
+ it "should check story's existence" do
25
+ story = Ffnpdf::Story.new("0")
26
+ story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
27
+ story.check_story.should == false
28
+ story.error.should == "Story does not exist (#{story.story_url})"
29
+ end
30
+
31
+ context "pulling" do
32
+ before :each do
33
+ @story = Ffnpdf::Story.new("1234567")
34
+ @story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
35
+ end
36
+
37
+ after :each do
38
+ if File.directory?("1234567")
39
+ FileUtils.rm_rf("1234567")
40
+ end
41
+ end
42
+
43
+ it "should create a story directory" do
44
+ pwd = Dir.pwd
45
+ @story.pull_story
46
+ Dir.pwd.should == pwd
47
+ File.should be_directory("1234567")
48
+ File.should exist("1234567/0001.md")
49
+ File.should exist("1234567/0000.md")
50
+ File.should exist("1234567/variables.txt")
51
+ File.should exist("1234567/xetex.template")
52
+ end
53
+ end
54
+
55
+ context "building" do
56
+ after :each do
57
+ if File.directory?("1234567")
58
+ FileUtils.rm_rf("1234567")
59
+ end
60
+ end
61
+
62
+ it "should check non existence of directory" do
63
+ story = Ffnpdf::Story.new("1234567")
64
+ story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
65
+ story.check_story_dir.should == false
66
+ story.error.should == "Story folder does not exist (1234567/)"
67
+ end
68
+
69
+ it "should check non existence of files" do
70
+ story = Ffnpdf::Story.new("1234567")
71
+ story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
72
+ story.pull_story
73
+ story = Ffnpdf::Story.new("1234567")
74
+ story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
75
+ FileUtils.rm("1234567/0001.md")
76
+ FileUtils.rm("1234567/0000.md")
77
+ story.check_story_dir.should == false
78
+ story.error.should == "Story folder does not have markdown files (1234567/)"
79
+ end
80
+
81
+ it "should check existence of directory" do
82
+ story = Ffnpdf::Story.new("1234567")
83
+ story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
84
+ story.pull_story
85
+ story = Ffnpdf::Story.new("1234567")
86
+ story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
87
+ story.check_story_dir.should == true
88
+ end
89
+
90
+ end
91
+
92
+ context "pulling multi" do
93
+ before :each do
94
+ @story = Ffnpdf::Story.new("0000001")
95
+ @story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
96
+ end
97
+
98
+ after :each do
99
+ if File.directory?("0000001")
100
+ FileUtils.rm_rf("0000001")
101
+ end
102
+ end
103
+
104
+ it "should create a story directory" do
105
+ pwd = Dir.pwd
106
+ @story.pull_story
107
+ Dir.pwd.should == pwd
108
+ File.should be_directory("0000001")
109
+ File.should exist("0000001/0001.md")
110
+ File.should exist("0000001/0002.md")
111
+ File.should exist("0000001/0003.md")
112
+ end
113
+ end
114
+
115
+ context "building multi" do
116
+ before :each do
117
+ @story = Ffnpdf::Story.new("0000001")
118
+ @story.custom_url = "http://bryanbibat.github.com/ffnpdf-test/"
119
+ end
120
+
121
+ after :each do
122
+ if File.directory?("0000001")
123
+ #FileUtils.rm_rf("0000001")
124
+ end
125
+ end
126
+
127
+ it "should build a story" do
128
+ pwd = Dir.pwd
129
+ @story.pull_story
130
+ Dir.pwd.should == pwd
131
+ @story.build_story
132
+ Dir.pwd.should == pwd
133
+ File.should exist("0000001/combined.md")
134
+ File.should exist("0000001/combined.pdf")
135
+ end
136
+
137
+ end
138
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ffnpdf do
4
+ it "has the correct version" do
5
+ Ffnpdf::VERSION.should == "0.0.1"
6
+ end
7
+ end
8
+
9
+
@@ -0,0 +1,4 @@
1
+ require_relative '../lib/ffnpdf'
2
+ require "test_notifier/runner/rspec"
3
+
4
+ TestNotifier.default_notifier = :notify_send
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ffnpdf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Bryan Bibat
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &79274890 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *79274890
25
+ - !ruby/object:Gem::Dependency
26
+ name: test_notifier
27
+ requirement: &79272240 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *79272240
36
+ - !ruby/object:Gem::Dependency
37
+ name: autotest
38
+ requirement: &79270640 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *79270640
47
+ - !ruby/object:Gem::Dependency
48
+ name: nokogiri
49
+ requirement: &79269170 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *79269170
58
+ - !ruby/object:Gem::Dependency
59
+ name: httparty
60
+ requirement: &79268340 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *79268340
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: &79267380 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *79267380
80
+ - !ruby/object:Gem::Dependency
81
+ name: httparty
82
+ requirement: &79266680 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :runtime
89
+ prerelease: false
90
+ version_requirements: *79266680
91
+ description: Scrapes a story off FF.net, converts it to Markdown, and turns it to
92
+ PDF with LaTeX
93
+ email:
94
+ - bry@bryanbibat.net
95
+ executables:
96
+ - ffnpdf
97
+ extensions: []
98
+ extra_rdoc_files: []
99
+ files:
100
+ - .gitignore
101
+ - .rspec
102
+ - Gemfile
103
+ - README.md
104
+ - Rakefile
105
+ - autotest/discover.rb
106
+ - bin/ffnpdf
107
+ - ffnpdf.gemspec
108
+ - lib/ffnpdf.rb
109
+ - lib/ffnpdf/converter.rb
110
+ - lib/ffnpdf/exec.rb
111
+ - lib/ffnpdf/story.rb
112
+ - lib/ffnpdf/version.rb
113
+ - spec/ffnpdf/converter_spec.rb
114
+ - spec/ffnpdf/exec_spec.rb
115
+ - spec/ffnpdf/story_spec.rb
116
+ - spec/ffnpdf_spec.rb
117
+ - spec/spec_helper.rb
118
+ homepage: https://github.com/bryanbibat/ffnpdf
119
+ licenses: []
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project: ffnpdf
138
+ rubygems_version: 1.8.10
139
+ signing_key:
140
+ specification_version: 3
141
+ summary: PDF generator for FF.net stories
142
+ test_files: []