polytexnic 1.0.beta3 → 1.0.beta4
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77cd3da83721b462b620c6264b757009d7764242
|
4
|
+
data.tar.gz: 66afdad9074a52e82885ab4c59de356b41aefc27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6fc1fd9be6e8abca50d1974632eb8240a4cc1d2e0d9eb97f0c82fd38796a969f44477c426d54926f654b84325936e6ddd4825ea7ffd5b9d2ab924fb341a59a2d
|
7
|
+
data.tar.gz: 333b985f56228ca304ace76eb0ee5b578fc01068c0c955e8d8cfb9f84f81b9983115ae9a0ca36022491561827ab28d6481ac9f88166df102b39f291472627c94
|
@@ -1,35 +1,95 @@
|
|
1
1
|
module CodeInclusion
|
2
2
|
class CodeInclusionException < Exception; end;
|
3
|
+
class RetrievalException < CodeInclusionException; end;
|
4
|
+
class SubsetException < CodeInclusionException; end;
|
3
5
|
|
4
|
-
class Code
|
5
|
-
CODE_REGEX = /^\s*%=\s+<<\s*\( # opening
|
6
|
-
\s*([^\s]+?) # path to file
|
7
|
-
(?:\[(.+?)\])? # optional section name
|
8
|
-
(?:,\s*tag:\s*([\w\.\/\-]+?))? # optional git tag
|
9
|
-
(?:,\s*lang:\s*(\w+))? # optional lang
|
10
|
-
(,\s*options:\s*.*)? # optional options
|
11
|
-
\s*\) # closing paren
|
12
|
-
/x
|
13
6
|
|
7
|
+
# Converts the input line into:
|
8
|
+
# Retrieval Args:
|
9
|
+
# filename: filename # required
|
10
|
+
# git: { tag: tagname } # optional
|
11
|
+
# section: sectionname, # 'section:' and 'line_numbers:'
|
12
|
+
# line_numbers: 1,4-6,8,14 # are optional and mutually exclusive
|
13
|
+
#
|
14
|
+
# Render Args:
|
15
|
+
# custom_language: 'ruby'
|
16
|
+
# hightlight: '"hl_lines": [1, 2], "linenos": true'
|
17
|
+
class Args
|
18
|
+
CODE_REGEX =
|
19
|
+
/^\s*%=\s+<<\s*\( # opening
|
20
|
+
\s*([^\s]+?) # path to file
|
21
|
+
(?:\[(.+?)\])? # optional section or line numbers
|
22
|
+
(?:,\s*git:\s*([ \w\.\/\-\{\}:]+?))? # optional git tag
|
23
|
+
(?:,\s*lang:\s*(\w+))? # optional lang
|
24
|
+
(,\s*options:\s*.*)? # optional options
|
25
|
+
\s*\) # closing paren
|
26
|
+
/x
|
27
|
+
|
28
|
+
attr_reader :input, :retrieval, :render, :match
|
29
|
+
|
30
|
+
def initialize(input)
|
31
|
+
@input = input
|
32
|
+
@retrieval = {}
|
33
|
+
@render = {}
|
34
|
+
@match = parse
|
35
|
+
|
36
|
+
extract
|
37
|
+
end
|
38
|
+
|
39
|
+
def extract
|
40
|
+
return unless code_inclusion_line?
|
41
|
+
|
42
|
+
retrieval[:filename] = match[1]
|
43
|
+
|
44
|
+
if specifies_line_numbers?
|
45
|
+
retrieval[:line_numbers] = match[2]
|
46
|
+
else
|
47
|
+
retrieval[:section] = match[2]
|
48
|
+
end
|
49
|
+
|
50
|
+
retrieval[:git] = extract_git(match[3]) if match[3]
|
51
|
+
|
52
|
+
render[:custom_language] = match[4]
|
53
|
+
render[:highlight] = match[5]
|
54
|
+
end
|
55
|
+
|
56
|
+
def specifies_line_numbers?
|
57
|
+
whitespace_digits_dashes_and_commas.match(match[2])
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse
|
61
|
+
CODE_REGEX.match(input)
|
62
|
+
end
|
63
|
+
|
64
|
+
def code_inclusion_line?
|
65
|
+
!match.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
def whitespace_digits_dashes_and_commas
|
69
|
+
/\s*\d[-,\d\s]*$/
|
70
|
+
end
|
71
|
+
|
72
|
+
def extract_git(git_args)
|
73
|
+
# only expect tag:, but could easily extract branch: or repo:
|
74
|
+
tag = /\s?{\s?tag:\s(.*)\s?}/.match(git_args)[1]
|
75
|
+
{tag: tag}
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
class Code
|
14
81
|
DEFAULT_LANGUAGE = 'text'
|
15
82
|
|
16
83
|
# Returns an instance of CodeInclusion::Code or nil
|
17
84
|
def self.for(line)
|
18
|
-
|
19
|
-
|
20
|
-
opts[:tag] = $3
|
21
|
-
opts[:custom_language] = $4
|
22
|
-
opts[:highlight] = $5
|
23
|
-
new($1, $2, opts)
|
24
|
-
end
|
85
|
+
args = Args.new(line)
|
86
|
+
new(args.retrieval, args.render) if args.code_inclusion_line?
|
25
87
|
end
|
26
88
|
|
27
|
-
attr_reader :
|
89
|
+
attr_reader :retrieval_args, :render_args
|
28
90
|
|
29
|
-
def initialize(
|
30
|
-
@
|
31
|
-
@sectionname = sectionname
|
32
|
-
@opts = opts
|
91
|
+
def initialize(retrieval_args, render_args)
|
92
|
+
@retrieval_args, @render_args = retrieval_args, render_args
|
33
93
|
end
|
34
94
|
|
35
95
|
# Returns the formatted code or an error message
|
@@ -37,7 +97,7 @@ module CodeInclusion
|
|
37
97
|
return unless filename
|
38
98
|
|
39
99
|
result = []
|
40
|
-
result << "%= lang:#{language}#{
|
100
|
+
result << "%= lang:#{language}#{highlight}"
|
41
101
|
result << '\begin{code}'
|
42
102
|
result.concat(raw_code)
|
43
103
|
result << '\end{code}'
|
@@ -46,31 +106,31 @@ module CodeInclusion
|
|
46
106
|
code_error(e.message)
|
47
107
|
end
|
48
108
|
|
109
|
+
private
|
110
|
+
|
49
111
|
def raw_code
|
50
|
-
|
112
|
+
Listing.for(retrieval_args)
|
51
113
|
end
|
52
114
|
|
53
|
-
|
115
|
+
def filename
|
116
|
+
retrieval_args[:filename]
|
117
|
+
end
|
54
118
|
|
55
|
-
|
56
|
-
|
57
|
-
@reader ||=
|
58
|
-
if opts[:tag]
|
59
|
-
GitTaggedFileReader.new(filename,
|
60
|
-
sectionname,
|
61
|
-
opts.delete(:tag),
|
62
|
-
opts)
|
63
|
-
elsif sectionname
|
64
|
-
SectionReader.new(filename, sectionname)
|
65
|
-
else
|
66
|
-
FileReader.new(filename)
|
67
|
-
end
|
119
|
+
def highlight
|
120
|
+
render_args[:highlight]
|
68
121
|
end
|
69
122
|
|
70
|
-
def
|
123
|
+
def custom_language
|
124
|
+
render_args[:custom_language]
|
125
|
+
end
|
126
|
+
|
127
|
+
def language_from_extension
|
71
128
|
extension_array = File.extname(filename).scan(/\.(.*)/).first
|
72
129
|
lang_from_extension = extension_array.nil? ? nil : extension_array[0]
|
73
|
-
|
130
|
+
end
|
131
|
+
|
132
|
+
def language
|
133
|
+
(custom_language || language_from_extension || DEFAULT_LANGUAGE)
|
74
134
|
end
|
75
135
|
|
76
136
|
def code_error(details)
|
@@ -78,169 +138,253 @@ module CodeInclusion
|
|
78
138
|
end
|
79
139
|
end
|
80
140
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
141
|
+
# Listing.for takes a set of retrieval args and returns an array of
|
142
|
+
# source code lines to be included in the book.
|
143
|
+
#
|
144
|
+
# Listing is responsible for retrieving the file you're including
|
145
|
+
# (the 'FullListing') and for extracting individual lines from that file
|
146
|
+
# (the 'Subset').
|
147
|
+
|
148
|
+
# It contains factory methods to choose the correct FullListing and Subset
|
149
|
+
# classes and the code to wire them together. If you add new FullListing or
|
150
|
+
# Subset objects, you'll need to wire them together here.
|
151
|
+
class Listing
|
152
|
+
|
153
|
+
# Returns the lines of code to be included or
|
154
|
+
# an exception containing the error message.
|
155
|
+
def self.for(args)
|
156
|
+
new(args).final_listing
|
90
157
|
end
|
91
158
|
|
92
|
-
attr_reader :
|
159
|
+
attr_reader :args
|
93
160
|
|
94
|
-
def initialize(
|
95
|
-
@
|
96
|
-
@sectionname = sectionname
|
97
|
-
@tagname = tagname
|
98
|
-
@opts = opts
|
99
|
-
@git = git
|
161
|
+
def initialize(args)
|
162
|
+
@args = args
|
100
163
|
end
|
101
164
|
|
102
|
-
def
|
103
|
-
|
165
|
+
def final_listing
|
166
|
+
subset_class.new(full_listing, args).lines
|
104
167
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
}
|
168
|
+
rescue SubsetException => e
|
169
|
+
raise RetrievalException.new(e.message +
|
170
|
+
" in file '#{args[:filename]}'")
|
109
171
|
end
|
110
172
|
|
111
173
|
private
|
112
174
|
|
113
|
-
def
|
114
|
-
|
115
|
-
raise(CodeInclusionException, "Tag '#{tagname}' does not exist.")
|
116
|
-
end
|
175
|
+
def full_listing
|
176
|
+
retrieval_class.new(args).lines
|
117
177
|
end
|
118
178
|
|
119
|
-
def
|
120
|
-
|
121
|
-
|
122
|
-
|
179
|
+
def retrieval_class
|
180
|
+
case
|
181
|
+
when args[:git]
|
182
|
+
FullListing::GitTag
|
183
|
+
else
|
184
|
+
FullListing::File
|
123
185
|
end
|
124
186
|
end
|
125
187
|
|
126
|
-
def
|
127
|
-
|
128
|
-
|
188
|
+
def subset_class
|
189
|
+
case
|
190
|
+
when args[:line_numbers]
|
191
|
+
Subset::LineNumber
|
192
|
+
when args[:section]
|
193
|
+
Subset::Section
|
194
|
+
else
|
195
|
+
Subset::Everything
|
196
|
+
end
|
129
197
|
end
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
# FullListing objects retrieve an entire file from some location.
|
202
|
+
module FullListing
|
203
|
+
|
204
|
+
# Return lines contained in a file read from disk.
|
205
|
+
class File
|
206
|
+
attr_reader :filename
|
207
|
+
|
208
|
+
def initialize(args)
|
209
|
+
@filename = args[:filename]
|
210
|
+
end
|
130
211
|
|
131
|
-
|
132
|
-
|
212
|
+
def lines
|
213
|
+
ensure_exists!
|
214
|
+
::File.read(filename).split("\n")
|
215
|
+
end
|
216
|
+
|
217
|
+
private
|
218
|
+
|
219
|
+
def ensure_exists!
|
220
|
+
unless ::File.exist?(filename)
|
221
|
+
raise(RetrievalException, "File '#{filename}' does not exist")
|
222
|
+
end
|
223
|
+
end
|
133
224
|
end
|
134
225
|
|
226
|
+
# Return lines contained in a file that's tagged in git.
|
227
|
+
class GitTag
|
228
|
+
|
229
|
+
def self.git_cmd
|
230
|
+
GitCmd.new
|
231
|
+
end
|
232
|
+
|
233
|
+
attr_reader :filename, :tag, :git_cmd
|
135
234
|
|
136
|
-
|
137
|
-
|
138
|
-
|
235
|
+
def initialize(args, git_cmd=self.class.git_cmd)
|
236
|
+
@filename = args[:filename]
|
237
|
+
@tag = args[:git][:tag]
|
238
|
+
@git_cmd = git_cmd
|
139
239
|
end
|
140
240
|
|
141
|
-
def
|
142
|
-
|
241
|
+
def lines
|
242
|
+
ensure_exists!
|
243
|
+
result = git_cmd.show(filename, tag)
|
244
|
+
|
245
|
+
if git_cmd.succeeded?
|
246
|
+
result.split("\n")
|
247
|
+
else
|
248
|
+
raise(RetrievalException, result)
|
249
|
+
end
|
143
250
|
end
|
144
251
|
|
145
|
-
|
146
|
-
|
252
|
+
private
|
253
|
+
|
254
|
+
def ensure_exists!
|
255
|
+
unless git_cmd.tag_exists?(tag)
|
256
|
+
raise(RetrievalException, "Tag '#{tag}' does not exist.")
|
257
|
+
end
|
147
258
|
end
|
148
259
|
|
149
|
-
|
150
|
-
|
260
|
+
class GitCmd
|
261
|
+
def show(filename, tagname)
|
262
|
+
`git show #{tagname}:#{filename}`
|
263
|
+
end
|
264
|
+
|
265
|
+
def succeeded?
|
266
|
+
$? == 0
|
267
|
+
end
|
268
|
+
|
269
|
+
def tags
|
270
|
+
`git tag`
|
271
|
+
end
|
272
|
+
|
273
|
+
def tag_exists?(tagname)
|
274
|
+
tags.split("\n").include?(tagname)
|
275
|
+
end
|
151
276
|
end
|
152
277
|
end
|
153
278
|
end
|
154
279
|
|
155
280
|
|
156
|
-
#
|
157
|
-
|
158
|
-
# Example: <<(lib/polytexnic/literal.rb)
|
159
|
-
class FileReader
|
160
|
-
attr_reader :filename
|
281
|
+
# Subsets reduce an input array of strings to a subset of that array.
|
282
|
+
module Subset
|
161
283
|
|
162
|
-
|
163
|
-
|
164
|
-
|
284
|
+
# Return the lines in the named section.
|
285
|
+
class Section
|
286
|
+
attr_reader :input, :name
|
165
287
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
288
|
+
def initialize(input, args)
|
289
|
+
@input = input
|
290
|
+
@name = args[:section]
|
291
|
+
end
|
170
292
|
|
171
|
-
|
172
|
-
|
173
|
-
|
293
|
+
def lines
|
294
|
+
ensure_exists!
|
295
|
+
input.slice(index_of_first_line, length)
|
174
296
|
end
|
175
|
-
end
|
176
|
-
end
|
177
297
|
|
298
|
+
private
|
178
299
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
#
|
183
|
-
# Sections are delineated by '#// begin section_name' and '#// end',
|
184
|
-
# for example:
|
185
|
-
#
|
186
|
-
# #// begin my_section
|
187
|
-
# some code
|
188
|
-
# #// end
|
189
|
-
class SectionReader < FileReader
|
190
|
-
attr_reader :lines, :sectionname
|
300
|
+
def exist?
|
301
|
+
!!index_of_begin
|
302
|
+
end
|
191
303
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
304
|
+
def index_of_begin
|
305
|
+
@section_begin_i ||=
|
306
|
+
input.index {|line| clean(line) == begin_text }
|
307
|
+
end
|
196
308
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
lines.slice(index_of_first_line, length)
|
201
|
-
end
|
309
|
+
def index_of_first_line
|
310
|
+
@first_line_i ||= index_of_begin + 1
|
311
|
+
end
|
202
312
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
313
|
+
def length
|
314
|
+
input.slice(index_of_first_line, input.size).index { |line|
|
315
|
+
clean(line) == (end_text)
|
316
|
+
}
|
317
|
+
end
|
207
318
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
end
|
319
|
+
def marker
|
320
|
+
'#//'
|
321
|
+
end
|
212
322
|
|
213
|
-
|
214
|
-
|
215
|
-
|
323
|
+
def begin_text
|
324
|
+
"#{marker} begin #{name}"
|
325
|
+
end
|
216
326
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
}
|
221
|
-
end
|
327
|
+
def end_text
|
328
|
+
"#{marker} end"
|
329
|
+
end
|
222
330
|
|
223
|
-
|
224
|
-
|
225
|
-
|
331
|
+
def clean(str)
|
332
|
+
str.strip.squeeze(" ")
|
333
|
+
end
|
226
334
|
|
227
|
-
|
228
|
-
|
335
|
+
def ensure_exists!
|
336
|
+
unless exist?
|
337
|
+
section_err = "Could not find section header '#{begin_text}'"
|
338
|
+
raise(SubsetException, section_err)
|
339
|
+
end
|
340
|
+
end
|
229
341
|
end
|
230
342
|
|
231
|
-
|
232
|
-
|
233
|
-
|
343
|
+
# Return the lines specified by :line_numbers.
|
344
|
+
# Line numbers are comma separated and may contain ranges, i.e.,
|
345
|
+
# 2, 4-6, 8, 14
|
346
|
+
#
|
347
|
+
# Rules:
|
348
|
+
# whitespace is ignored
|
349
|
+
# ranges are included in ascending order (4-6 is the same as 6-4)
|
350
|
+
# lines numbers higher than the max available are ignored
|
351
|
+
class LineNumber
|
352
|
+
attr_reader :input, :numbers
|
353
|
+
def initialize(input, args)
|
354
|
+
@input = input
|
355
|
+
@numbers = args[:line_numbers]
|
356
|
+
end
|
357
|
+
|
358
|
+
def lines
|
359
|
+
individual_numbers.collect {|i| input[i - 1]}.compact
|
360
|
+
end
|
361
|
+
|
362
|
+
private
|
363
|
+
|
364
|
+
def individual_numbers
|
365
|
+
clumps.collect {|clump| expand_clump(clump)}.flatten
|
366
|
+
end
|
234
367
|
|
235
|
-
|
236
|
-
|
368
|
+
def clumps
|
369
|
+
numbers.gsub(/ /,'').split(",")
|
370
|
+
end
|
371
|
+
|
372
|
+
def expand_clump(clump)
|
373
|
+
edges = clump.split('-').collect(&:to_i)
|
374
|
+
(edges.min.to_i..edges.max.to_i).to_a
|
375
|
+
end
|
237
376
|
end
|
238
377
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
378
|
+
# Return everything (think of this as the null object subset)
|
379
|
+
class Everything
|
380
|
+
attr_reader :input
|
381
|
+
|
382
|
+
def initialize(input, _=nil)
|
383
|
+
@input = input
|
384
|
+
end
|
385
|
+
|
386
|
+
def lines
|
387
|
+
input
|
244
388
|
end
|
245
389
|
end
|
246
390
|
end
|
data/lib/polytexnic/version.rb
CHANGED
@@ -0,0 +1,136 @@
|
|
1
|
+
# encoding=utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe "full listing" do
|
5
|
+
|
6
|
+
describe "file" do
|
7
|
+
|
8
|
+
context "exists" do
|
9
|
+
let(:args) { {filename: __FILE__} }
|
10
|
+
subject { CodeInclusion::FullListing::File.new(args).lines }
|
11
|
+
|
12
|
+
it { should eq(File.read(__FILE__).split("\n")) }
|
13
|
+
end
|
14
|
+
|
15
|
+
context "does not exist" do
|
16
|
+
let(:args) { {filename: "badfile"} }
|
17
|
+
subject { lambda { CodeInclusion::FullListing::File.new(args).lines } }
|
18
|
+
|
19
|
+
it { should raise_exception(CodeInclusion::RetrievalException) }
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "git tag" do
|
25
|
+
|
26
|
+
context "file exists" do
|
27
|
+
before(:all) do
|
28
|
+
class FakeGitCmd < CodeInclusion::FullListing::GitTag::GitCmd
|
29
|
+
def show(_, _)
|
30
|
+
"Real data\nsecond line"
|
31
|
+
end
|
32
|
+
def tag_exists?(tagname)
|
33
|
+
true
|
34
|
+
end
|
35
|
+
def succeeded?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:args) { { filename: "goodfile", git: {tag: "goodtag"} } }
|
42
|
+
subject {
|
43
|
+
CodeInclusion::FullListing::GitTag.new(args, FakeGitCmd.new).lines }
|
44
|
+
|
45
|
+
it { should eq(["Real data", "second line"]) }
|
46
|
+
end
|
47
|
+
|
48
|
+
context "tag does not exist" do
|
49
|
+
before(:all) do
|
50
|
+
class FakeGitCmd < CodeInclusion::FullListing::GitTag::GitCmd
|
51
|
+
def tag_exists?(tagname)
|
52
|
+
false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
let(:args) { { filename: "irreleventfile", git: {tag: "badtag"} } }
|
58
|
+
subject { lambda {
|
59
|
+
CodeInclusion::FullListing::GitTag.new(args, FakeGitCmd.new).lines } }
|
60
|
+
|
61
|
+
it { should raise_exception(
|
62
|
+
CodeInclusion::RetrievalException,
|
63
|
+
"Tag 'badtag' does not exist."
|
64
|
+
) }
|
65
|
+
end
|
66
|
+
|
67
|
+
context "file does not exist" do
|
68
|
+
before(:all) do
|
69
|
+
class FakeGitCmd < CodeInclusion::FullListing::GitTag::GitCmd
|
70
|
+
def show(filename, tag)
|
71
|
+
"fatal: Path 'badfile' does not exist in 'goodtag'"
|
72
|
+
end
|
73
|
+
def tag_exists?(tagname)
|
74
|
+
true
|
75
|
+
end
|
76
|
+
def succeeded?
|
77
|
+
false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
let(:args) { { filename: "badfile", git: {tag: "goodtag"} } }
|
83
|
+
subject { lambda {
|
84
|
+
CodeInclusion::FullListing::GitTag.new(args, FakeGitCmd.new).lines } }
|
85
|
+
|
86
|
+
it { should raise_exception(
|
87
|
+
CodeInclusion::RetrievalException,
|
88
|
+
"fatal: Path 'badfile' does not exist in 'goodtag'") }
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
describe "subset" do
|
96
|
+
let(:input) {["line1",
|
97
|
+
"line2",
|
98
|
+
"#// begin sec_AAA",
|
99
|
+
"line4",
|
100
|
+
"line5",
|
101
|
+
"#// end",
|
102
|
+
"line7",
|
103
|
+
"line8",
|
104
|
+
"line9",
|
105
|
+
"line10"]}
|
106
|
+
|
107
|
+
describe "section" do
|
108
|
+
|
109
|
+
context "exists" do
|
110
|
+
let(:args) { {section: "sec_AAA"} }
|
111
|
+
subject { CodeInclusion::Subset::Section.new(input, args).lines }
|
112
|
+
|
113
|
+
it { should eq(["line4", "line5"]) }
|
114
|
+
end
|
115
|
+
|
116
|
+
context "does not exist" do
|
117
|
+
let(:args) { {section: "missing section name"} }
|
118
|
+
subject { lambda {CodeInclusion::Subset::Section.new(input, args).lines} }
|
119
|
+
|
120
|
+
it { should raise_exception(CodeInclusion::SubsetException) }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "line numbers" do
|
125
|
+
let(:args) { {line_numbers: "1 , 2-1, 4- 5,10, 42"} }
|
126
|
+
subject { CodeInclusion::Subset::LineNumber.new(input, args).lines }
|
127
|
+
|
128
|
+
it { should eq(["line1", "line1", "line2", "line4", "line5", "line10"]) }
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "everything" do
|
132
|
+
subject { CodeInclusion::Subset::Everything.new(input).lines }
|
133
|
+
|
134
|
+
it { should eq(input)}
|
135
|
+
end
|
136
|
+
end
|
@@ -244,24 +244,22 @@ describe Polytexnic::Pipeline do
|
|
244
244
|
context "from a git tag" do
|
245
245
|
shared_examples "an inclusion" do
|
246
246
|
it "resembles the given output" do
|
247
|
-
allow(CodeInclusion::
|
248
|
-
and_return(
|
247
|
+
allow(CodeInclusion::FullListing::GitTag).to receive(:git_cmd).
|
248
|
+
and_return(FakeGitCmd.new)
|
249
249
|
expect(processed_text).to resemble(output)
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
253
253
|
context "the tag and file exist" do
|
254
254
|
before(:all) do
|
255
|
-
class
|
256
|
-
|
257
|
-
|
258
|
-
f = File.join(tmpdir, filename)
|
259
|
-
File.open(f, 'w') { |file| file.write("Fake data") }
|
255
|
+
class FakeGitCmd < CodeInclusion::FullListing::GitTag::GitCmd
|
256
|
+
def show(_, _)
|
257
|
+
"Fake data\nsecond line"
|
260
258
|
end
|
261
259
|
def tag_exists?(tagname)
|
262
260
|
true
|
263
261
|
end
|
264
|
-
def
|
262
|
+
def succeeded?
|
265
263
|
true
|
266
264
|
end
|
267
265
|
end
|
@@ -269,7 +267,7 @@ describe Polytexnic::Pipeline do
|
|
269
267
|
|
270
268
|
context "with tag only" do
|
271
269
|
let(:polytex) do <<-'EOS'
|
272
|
-
%= <<(tagged_file.rb, tag: fake_tag.1.0)
|
270
|
+
%= <<(tagged_file.rb, git: {tag: fake_tag.1.0})
|
273
271
|
EOS
|
274
272
|
end
|
275
273
|
let(:output) do <<-'EOS'
|
@@ -277,6 +275,7 @@ describe Polytexnic::Pipeline do
|
|
277
275
|
<div class="highlight">
|
278
276
|
<pre>
|
279
277
|
<span class="no">Fake</span> <span class="n">data</span>
|
278
|
+
<span class="n">second</span> <span class="n">line</span>
|
280
279
|
</pre>
|
281
280
|
</div>
|
282
281
|
EOS
|
@@ -288,7 +287,10 @@ describe Polytexnic::Pipeline do
|
|
288
287
|
let(:output) do <<-'EOS'
|
289
288
|
<div class="code">
|
290
289
|
<div class="highlight">
|
291
|
-
<pre>
|
290
|
+
<pre>
|
291
|
+
Fake data
|
292
|
+
second line
|
293
|
+
</pre>
|
292
294
|
</div>
|
293
295
|
</div>
|
294
296
|
EOS
|
@@ -296,7 +298,7 @@ describe Polytexnic::Pipeline do
|
|
296
298
|
|
297
299
|
context "with tag and lang" do
|
298
300
|
let(:polytex) do <<-'EOS'
|
299
|
-
%= <<(tagged_file.rb, tag: slashes/and-dashes-are/ok/too, lang: tex)
|
301
|
+
%= <<(tagged_file.rb, git: {tag: slashes/and-dashes-are/ok/too}, lang: tex)
|
300
302
|
EOS
|
301
303
|
end
|
302
304
|
it_behaves_like "an inclusion"
|
@@ -304,7 +306,7 @@ describe Polytexnic::Pipeline do
|
|
304
306
|
|
305
307
|
context "with tag, lang and options" do
|
306
308
|
let(:polytex) do <<-'EOS'
|
307
|
-
%= <<(tagged_file.rb, tag: v0.9.4, lang: tex, options: "hl_lines": [5])
|
309
|
+
%= <<(tagged_file.rb, git: {tag: v0.9.4}, lang: tex, options: "hl_lines": [5])
|
308
310
|
EOS
|
309
311
|
end
|
310
312
|
it_behaves_like "an inclusion"
|
@@ -314,20 +316,21 @@ describe Polytexnic::Pipeline do
|
|
314
316
|
|
315
317
|
context "the tag does not exist" do
|
316
318
|
before(:all) do
|
317
|
-
class
|
318
|
-
def
|
319
|
+
class FakeGitCmd < CodeInclusion::FullListing::GitTag::GitCmd
|
320
|
+
def show(_, _)
|
321
|
+
''
|
319
322
|
end
|
320
323
|
def tag_exists?(tagname)
|
321
324
|
false
|
322
325
|
end
|
323
|
-
def
|
326
|
+
def succeeded?
|
324
327
|
false
|
325
328
|
end
|
326
329
|
end
|
327
330
|
end
|
328
331
|
|
329
332
|
let(:polytex) do <<-'EOS'
|
330
|
-
%= <<(tagged_file.rb, tag: non_existent_tag)
|
333
|
+
%= <<(tagged_file.rb, git: {tag: non_existent_tag})
|
331
334
|
EOS
|
332
335
|
end
|
333
336
|
let(:output) do <<-'EOS'
|
@@ -343,27 +346,27 @@ describe Polytexnic::Pipeline do
|
|
343
346
|
|
344
347
|
context "the file does not exist" do
|
345
348
|
before(:all) do
|
346
|
-
class
|
347
|
-
def
|
348
|
-
"
|
349
|
+
class FakeGitCmd < CodeInclusion::FullListing::GitTag::GitCmd
|
350
|
+
def show(filename, _)
|
351
|
+
"fatal: Path 'path/to/non_existent_file.rb' does not exist in 'v0.9.9'"
|
349
352
|
end
|
350
353
|
def tag_exists?(tagname)
|
351
354
|
true
|
352
355
|
end
|
353
|
-
def
|
356
|
+
def succeeded?
|
354
357
|
false
|
355
358
|
end
|
356
359
|
end
|
357
360
|
end
|
358
361
|
|
359
362
|
let(:polytex) do <<-'EOS'
|
360
|
-
%= <<(non_existent_file, tag: v0.9.4)
|
363
|
+
%= <<(path/to/non_existent_file.rb, git: {tag: v0.9.4})
|
361
364
|
EOS
|
362
365
|
end
|
363
366
|
let(:output) do <<-'EOS'
|
364
367
|
<p>
|
365
368
|
<span class="inline_verbatim">
|
366
|
-
ERROR:
|
369
|
+
ERROR: fatal: Path 'path/to/non_existent_file.rb' does not exist in 'v0.9.9'
|
367
370
|
</span>
|
368
371
|
</p>
|
369
372
|
EOS
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polytexnic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.beta4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Hartl
|
@@ -258,6 +258,7 @@ files:
|
|
258
258
|
- spec/to_html/graphics_and_figures_spec.rb
|
259
259
|
- spec/to_html/input_spec.rb
|
260
260
|
- spec/to_html/lists_spec.rb
|
261
|
+
- spec/to_html/literal_environments/code_inclusion_spec.rb
|
261
262
|
- spec/to_html/literal_environments/code_spec.rb
|
262
263
|
- spec/to_html/literal_environments/math_spec.rb
|
263
264
|
- spec/to_html/literal_environments/unicode_spec.rb
|
@@ -321,6 +322,7 @@ test_files:
|
|
321
322
|
- spec/to_html/graphics_and_figures_spec.rb
|
322
323
|
- spec/to_html/input_spec.rb
|
323
324
|
- spec/to_html/lists_spec.rb
|
325
|
+
- spec/to_html/literal_environments/code_inclusion_spec.rb
|
324
326
|
- spec/to_html/literal_environments/code_spec.rb
|
325
327
|
- spec/to_html/literal_environments/math_spec.rb
|
326
328
|
- spec/to_html/literal_environments/unicode_spec.rb
|