markdown_prawn 0.0.3.pre → 0.0.4.pre
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/bin/md2pdf +1 -1
- data/bin/showoff2pdf +144 -0
- data/lib/markdown_fragments/list_fragment.rb +1 -0
- data/lib/markdown_parser/parser.rb +21 -2
- data/markdown_prawn.gemspec +2 -2
- data/markdown_prawn.rb +12 -0
- metadata +6 -4
data/bin/md2pdf
CHANGED
@@ -6,6 +6,6 @@
|
|
6
6
|
# Takes input from standard in, expected to be a markdown document
|
7
7
|
# and renders a PDF to standard out.
|
8
8
|
#
|
9
|
-
require 'markdown_prawn'
|
9
|
+
require File.dirname(__FILE__) + '/../markdown_prawn.rb'
|
10
10
|
content = $stdin.read
|
11
11
|
puts MarkdownPrawn::StringParser.new(content).to_pdf.render
|
data/bin/showoff2pdf
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'markdown_prawn'
|
4
|
+
require 'json/pure'
|
5
|
+
|
6
|
+
paths = []
|
7
|
+
images = []
|
8
|
+
|
9
|
+
# First, grab all of the markdown documents, assume they will always end with either .md
|
10
|
+
# or .mdown extensions.
|
11
|
+
#
|
12
|
+
JSON.parse(IO.read(File.dirname(__FILE__) + '/showoff.json')).each do |content|
|
13
|
+
paths << Dir.glob(File.expand_path(File.dirname(__FILE__) + "/#{content['section']}/*.{md,mdown}"))
|
14
|
+
end
|
15
|
+
paths.flatten!
|
16
|
+
|
17
|
+
# Also want to track where all the images are. Only looking for JPEGs and PNGs
|
18
|
+
#
|
19
|
+
JSON.parse(IO.read(File.dirname(__FILE__) + '/showoff.json')).each do |content|
|
20
|
+
images << Dir.glob(File.expand_path(File.dirname(__FILE__) + "/#{content['section']}/**/*.{png,jpg,jpeg}"))
|
21
|
+
end
|
22
|
+
images.flatten!
|
23
|
+
|
24
|
+
class ShowoffSlideStream
|
25
|
+
def initialize(content, parser)
|
26
|
+
@content = content
|
27
|
+
@parser = parser
|
28
|
+
end
|
29
|
+
def each_with_index(&block)
|
30
|
+
@content.split(/!SLIDE/).each do |slide|
|
31
|
+
slide.each_with_index do |line, index|
|
32
|
+
yield line, index
|
33
|
+
end
|
34
|
+
@parser.document_structure << PageBreakFragment.new([''])
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class PageBreakFragment < MarkdownFragment
|
40
|
+
def render_on(pdf_object)
|
41
|
+
pdf_object.start_new_page(:size => "A4", :layout => :landscape)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class JPEG
|
46
|
+
attr_reader :width, :height, :bits
|
47
|
+
|
48
|
+
def initialize(file)
|
49
|
+
if file.kind_of? IO
|
50
|
+
examine(file)
|
51
|
+
else
|
52
|
+
File.open(file, 'rb') { |io| examine(io) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def examine(io)
|
58
|
+
raise 'malformed JPEG' unless io.getc == 0xFF && io.getc == 0xD8 # SOI
|
59
|
+
|
60
|
+
class << io
|
61
|
+
def readint; (readchar << 8) + readchar; end
|
62
|
+
def readframe; read(readint - 2); end
|
63
|
+
def readsof; [readint, readchar, readint, readint, readchar]; end
|
64
|
+
def next
|
65
|
+
c = readchar while c != 0xFF
|
66
|
+
c = readchar while c == 0xFF
|
67
|
+
c
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
while marker = io.next
|
72
|
+
case marker
|
73
|
+
when 0xC0..0xC3, 0xC5..0xC7, 0xC9..0xCB, 0xCD..0xCF # SOF markers
|
74
|
+
length, @bits, @height, @width, components = io.readsof
|
75
|
+
raise 'malformed JPEG' unless length == 8 + components * 3
|
76
|
+
when 0xD9, 0xDA: break # EOI, SOS
|
77
|
+
when 0xFE: @comment = io.readframe # COM
|
78
|
+
when 0xE1: io.readframe # APP1, contains EXIF tag
|
79
|
+
else io.readframe # ignore frame
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
class ImageFragment < MarkdownFragment
|
87
|
+
def self._image_assets=(value)
|
88
|
+
@@_image_assets = value
|
89
|
+
end
|
90
|
+
|
91
|
+
def self._image_assets
|
92
|
+
@@_image_assets
|
93
|
+
end
|
94
|
+
|
95
|
+
def render_on(pdf_object)
|
96
|
+
if is_remote_uri?
|
97
|
+
filename = @content.first.split('/').last
|
98
|
+
file_path = "#{Dir.tmpdir}/#{filename}"
|
99
|
+
content = Net::HTTP.get(URI.parse(@content.first))
|
100
|
+
File.open(file_path, 'w') do |f|
|
101
|
+
f.puts content
|
102
|
+
end
|
103
|
+
else
|
104
|
+
if !ImageFragment._image_assets.nil?
|
105
|
+
ImageFragment._image_assets.each do |image|
|
106
|
+
if image =~ /#{@content.first}$/
|
107
|
+
file_path = image
|
108
|
+
end
|
109
|
+
end
|
110
|
+
else
|
111
|
+
file_path = @content.first
|
112
|
+
end
|
113
|
+
end
|
114
|
+
if file_path =~ /.png$/
|
115
|
+
width, height = IO.read(file_path)[0x10..0x18].unpack('NN')
|
116
|
+
else
|
117
|
+
width = JPEG.new(file_path).width
|
118
|
+
height = JPEG.new(file_path).height
|
119
|
+
end
|
120
|
+
pdf_object.image file_path, :width => width, :height => height, :scale => 0.8
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
class MarkdownPrawn::ShowoffParser < MarkdownPrawn::Parser
|
126
|
+
attr_accessor :document_structure
|
127
|
+
|
128
|
+
def initialize(showoff_section_content)
|
129
|
+
@links_list = { :urls_seen => [], :object => LinksReferenceFragment.new }
|
130
|
+
@document_structure = []
|
131
|
+
@slides_list = []
|
132
|
+
@images_list = []
|
133
|
+
@content = ''
|
134
|
+
showoff_section_content.each { |p| @content << IO.read(p) }
|
135
|
+
@content = ShowoffSlideStream.new(@content, self)
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
# Convert the whole shebang into a PDF
|
142
|
+
#
|
143
|
+
ImageFragment._image_assets = images
|
144
|
+
puts MarkdownPrawn::ShowoffParser.new(paths).to_pdf({:page_layout => :landscape}).render
|
@@ -23,7 +23,7 @@ class Parser
|
|
23
23
|
#
|
24
24
|
def to_pdf(options = {})
|
25
25
|
parse!
|
26
|
-
options =
|
26
|
+
options = { :page_layout => :portrait, :page_size => 'A4' }.merge(options)
|
27
27
|
pdf = Prawn::Document.new(options)
|
28
28
|
@document_structure.each { |markdown_fragment| markdown_fragment.render_on(pdf) }
|
29
29
|
pdf
|
@@ -170,13 +170,32 @@ class Parser
|
|
170
170
|
@links_list[:urls_seen] << url
|
171
171
|
@links_list[:object].content << [ reference, url, "#{title}" ]
|
172
172
|
end
|
173
|
+
|
174
|
+
to_replace = []
|
173
175
|
|
174
176
|
# Deal with inline images
|
175
177
|
#
|
176
178
|
line.scan(/(?:^|\s)?(\!\[(?:.+?)\]\((.+?)\))/) do |val|
|
177
|
-
|
179
|
+
paragraph.content[-1] = paragraph.content[-1].gsub(val[0],'')
|
180
|
+
to_replace << val[0]
|
178
181
|
@document_structure << ImageFragment.new([val[1]])
|
179
182
|
end
|
183
|
+
|
184
|
+
to_replace.each { |v| line.gsub!(v) }
|
185
|
+
to_replace = []
|
186
|
+
|
187
|
+
# Deal with inline hyperlinks, which are similar to
|
188
|
+
# images.
|
189
|
+
#
|
190
|
+
line.scan(/(?:^|\s)?(\[(?:.+?)\]\((.+?)\))/) do |val|
|
191
|
+
if @links_list[:urls_seen].include?(val[1])
|
192
|
+
else
|
193
|
+
@links_list[:urls_seen] << val[1]
|
194
|
+
@links_list[:object].content << [ '12', val[1], "#{title}" ]
|
195
|
+
end
|
196
|
+
paragraph.content[-1] = paragraph.content[-1].gsub(val[0],'[Link][12]')
|
197
|
+
end
|
198
|
+
|
180
199
|
end
|
181
200
|
if !list.content.empty? && ! @document_structure.include?(list)
|
182
201
|
@document_structure << list
|
data/markdown_prawn.gemspec
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
description = "Markdown Parawn is a library and an executable script which allow you to generate a PDF from any valid Markdown."
|
2
2
|
Gem::Specification.new do |spec|
|
3
3
|
spec.name = "markdown_prawn"
|
4
|
-
spec.version = '0.0.
|
4
|
+
spec.version = '0.0.4.pre'
|
5
5
|
spec.platform = Gem::Platform::RUBY
|
6
6
|
spec.files = Dir.glob("{bin,lib,test}/**/**/*") +
|
7
|
-
["Rakefile", "markdown_prawn.gemspec"]
|
7
|
+
["Rakefile", "markdown_prawn.gemspec",'markdown_prawn.rb']
|
8
8
|
spec.require_path = "lib"
|
9
9
|
spec.required_ruby_version = '>= 1.8.7'
|
10
10
|
spec.required_rubygems_version = ">= 1.3.6"
|
data/markdown_prawn.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
require 'prawn'
|
4
|
+
module MarkdownPrawn
|
5
|
+
# Namespace for PDF Fun
|
6
|
+
end
|
7
|
+
require File.dirname(__FILE__) + '/lib/markdown_parser.rb'
|
8
|
+
require File.dirname(__FILE__) + '/lib/markdown_fragments.rb'
|
9
|
+
require File.dirname(__FILE__) + '/lib/markdown_prawn_exceptions.rb'
|
10
|
+
|
11
|
+
|
12
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markdown_prawn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 961915988
|
5
5
|
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
9
|
+
- 4
|
10
10
|
- pre
|
11
|
-
version: 0.0.
|
11
|
+
version: 0.0.4.pre
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Ryan Stenhouse
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-11-
|
19
|
+
date: 2010-11-22 00:00:00 +00:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -43,6 +43,7 @@ extensions: []
|
|
43
43
|
extra_rdoc_files: []
|
44
44
|
|
45
45
|
files:
|
46
|
+
- bin/showoff2pdf
|
46
47
|
- bin/md2pdf
|
47
48
|
- lib/markdown_fragments.rb
|
48
49
|
- lib/markdown_parser/parser.rb
|
@@ -65,6 +66,7 @@ files:
|
|
65
66
|
- test/helper.rb
|
66
67
|
- Rakefile
|
67
68
|
- markdown_prawn.gemspec
|
69
|
+
- markdown_prawn.rb
|
68
70
|
has_rdoc: true
|
69
71
|
homepage: http://ryanstenhouse.eu
|
70
72
|
licenses: []
|