nandoc 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README +5 -4
- data/Rakefile +1 -1
- data/bin/nandoc +2 -1
- data/doc/FAQ.md +3 -0
- data/doc/PROVISO.md +39 -0
- data/doc/commands/diff.md +49 -0
- data/doc/svg/less-fonts.svg +2 -2
- data/lib/nandoc/cli/README.md +6 -0
- data/lib/nandoc/cli/command-methods.rb +38 -0
- data/lib/nandoc/cli/option-methods/exclusive-options.rb +56 -0
- data/lib/nandoc/cli/option-methods/option-enum.rb +64 -0
- data/lib/nandoc/cli/option-methods.rb +35 -0
- data/lib/nandoc/cli.rb +3 -0
- data/lib/nandoc/commands/create-nandoc-site.rb +9 -12
- data/lib/nandoc/commands/diff.rb +14 -11
- data/lib/nandoc/commands.rb +9 -0
- data/lib/nandoc/{config.rb → core/config.rb} +18 -9
- data/lib/nandoc/core/project.rb +50 -0
- data/lib/nandoc/doc/hack-free-zone-defined.md +33 -0
- data/lib/nandoc/erb/agent.rb +5 -5
- data/lib/nandoc/{test/minitest-extlib.rb → extlib/minitest.rb} +1 -1
- data/lib/nandoc/filters/builtin-tags/fence/terminal.rb +24 -0
- data/lib/nandoc/filters/builtin-tags/fence-dispatcher.rb +43 -0
- data/lib/nandoc/filters/builtin-tags/fences.rb +4 -0
- data/lib/nandoc/filters/builtin-tags/see-test.rb +67 -0
- data/lib/nandoc/filters/builtin-tags.rb +11 -0
- data/lib/nandoc/filters/custom-tag.rb +43 -0
- data/lib/nandoc/filters/custom-tags.rb +19 -0
- data/lib/nandoc/filters/tag-parse-instance-methods.rb +11 -0
- data/lib/nandoc/filters/tag-parser.rb +206 -0
- data/lib/nandoc/filters.rb +11 -585
- data/lib/nandoc/{cri-hacks.rb → hacks/cri-hacks.rb} +4 -3
- data/lib/nandoc/{data-source.rb → hacks/data-source.rb} +5 -4
- data/lib/nandoc/{item-class-hacks.rb → hacks/item-class-hacks.rb} +3 -1
- data/lib/nandoc/hacks.rb +6 -0
- data/lib/nandoc/helpers/menu-bouncy.rb +1 -1
- data/lib/nandoc/helpers/site-map.rb +3 -0
- data/lib/nandoc/helpers.rb +1 -1
- data/lib/nandoc/html/tags.rb +65 -0
- data/lib/nandoc/html.rb +6 -0
- data/lib/nandoc/parse-readme.rb +4 -0
- data/lib/nandoc/spec-doc/agent-instance-methods.rb +24 -0
- data/lib/nandoc/spec-doc/code-snippet.rb +59 -0
- data/lib/nandoc/spec-doc/generic-agent.rb +40 -0
- data/lib/nandoc/spec-doc/mock-prompt.rb +3 -9
- data/lib/nandoc/spec-doc/parse-trace.rb +25 -0
- data/lib/nandoc/spec-doc/{mini-test/spec-instance-methods.rb → playback/html/foo-bar.rb} +0 -0
- data/lib/nandoc/spec-doc/playback/html.rb +2 -0
- data/lib/nandoc/spec-doc/playback/players/method.rb +64 -0
- data/lib/nandoc/spec-doc/playback/players/ruby.rb +158 -0
- data/lib/nandoc/spec-doc/playback/players/terminal.rb +93 -0
- data/lib/nandoc/spec-doc/playback/players.rb +4 -0
- data/lib/nandoc/spec-doc/playback/support/playback-methods.rb +44 -0
- data/lib/nandoc/spec-doc/playback/support/sexp-scanner.rb +61 -0
- data/lib/nandoc/spec-doc/playback/support.rb +3 -0
- data/lib/nandoc/spec-doc/playback/terminal/color-to-html.rb +100 -0
- data/lib/nandoc/spec-doc/playback.rb +3 -0
- data/lib/nandoc/spec-doc/recordings.rb +55 -0
- data/lib/nandoc/spec-doc/ruby2ruby-standin.rb +37 -0
- data/lib/nandoc/spec-doc/test-case-agent.rb +1 -1
- data/lib/nandoc/spec-doc/{mini-test.rb → test-framework/mini-test/proxy.rb} +9 -31
- data/lib/nandoc/spec-doc/{test-framework-proxy.rb → test-framework/proxy.rb} +27 -50
- data/lib/nandoc/spec-doc.rb +57 -13
- data/lib/nandoc/{test → support}/diff-to-string.rb +0 -0
- data/lib/nandoc/support/regexp-enhance.rb +6 -0
- data/lib/nandoc/support/regexp.rb +12 -0
- data/lib/nandoc/support/secret-parent.rb +21 -0
- data/lib/nandoc/support/shared-attr-reader.rb +32 -0
- data/lib/nandoc/support/site-merge.rb +1 -1
- data/lib/nandoc/support/site-methods.rb +4 -4
- data/lib/nandoc/support/stream-colorizer.rb +1 -1
- data/lib/nandoc/support/string-methods.rb +56 -0
- data/lib/nandoc.rb +12 -35
- data/proto/README.md +4 -2
- data/test/test.rb +1 -0
- metadata +58 -25
- data/doc/bar/baz.md +0 -4
- data/doc/bar/bliff.md +0 -8
- data/doc/foo.md +0 -5
- data/doc/getting-started.rb +0 -13
- data/lib/nandoc/spec-doc/support-modules.rb +0 -158
- data/lib/nandoc/spec-doc/test-framework-dispatcher.rb +0 -15
- data/lib/nandoc/support-modules.rb +0 -273
- data/lib/nandoc/treebis/NOGIT-DOCS/NEWS.md +0 -5
- data/lib/nandoc/treebis/NOGIT-README.md +0 -65
- data/lib/nandoc/treebis/nandoc.persistent.json +0 -3
data/lib/nandoc/helpers.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module NanDoc::Helpers
|
2
2
|
module NanDocHelpers
|
3
3
|
# @todo-now test this
|
4
|
-
include NanDoc::
|
4
|
+
include NanDoc::StringMethods # indent() unindent() no_blank_lines()
|
5
5
|
module BlockAttrAccessor
|
6
6
|
attr_accessor :block_attr_accessors
|
7
7
|
class << self
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module NanDoc::Html
|
2
|
+
class Tags
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@current = nil
|
6
|
+
@content = []
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :content
|
10
|
+
attr_reader :current
|
11
|
+
|
12
|
+
def push_raw str
|
13
|
+
flush if @current
|
14
|
+
@content.push str
|
15
|
+
end
|
16
|
+
|
17
|
+
def push_smart name, classes, content
|
18
|
+
tag = normalize_tag(name, classes)
|
19
|
+
if @current != tag
|
20
|
+
flush if @current
|
21
|
+
@current = tag
|
22
|
+
@content.push render_open_tag(tag)
|
23
|
+
end
|
24
|
+
@content.push content
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def push_tag_now name, classes, content
|
29
|
+
tag = normalize_tag(name, classes)
|
30
|
+
@content.push render_open_tag(tag)
|
31
|
+
@content.push content
|
32
|
+
@content.push render_close_tag(tag)
|
33
|
+
nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_html
|
37
|
+
flush if @current
|
38
|
+
@content.join('')
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def flush
|
44
|
+
if @current
|
45
|
+
@content.push render_close_tag(@current)
|
46
|
+
@current = nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def render_close_tag tag
|
51
|
+
name = tag.first
|
52
|
+
"</#{name}>"
|
53
|
+
end
|
54
|
+
|
55
|
+
def render_open_tag tag
|
56
|
+
name, classes = tag
|
57
|
+
"<#{name} class='#{classes.join(' ')}'>"
|
58
|
+
end
|
59
|
+
|
60
|
+
def normalize_tag name, classes
|
61
|
+
classes = classes.kind_of?(Array) ? classes : [classes]
|
62
|
+
[name, classes]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/nandoc/html.rb
ADDED
data/lib/nandoc/parse-readme.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
module NanDoc::SpecDoc
|
2
|
+
module AgentInstanceMethods
|
3
|
+
# share things between MockPrompt and TestCaseAgent
|
4
|
+
|
5
|
+
# we used to use first method, now we use first test_ method
|
6
|
+
def method_name_to_record caller
|
7
|
+
line = caller.detect{ |x| x =~ /in `test_/ } or fail('hack fail')
|
8
|
+
method = line =~ /in `(.+)'\Z/ && $1 or fail("hack fail")
|
9
|
+
method
|
10
|
+
end
|
11
|
+
|
12
|
+
def recordings
|
13
|
+
@recordings ||= NanDoc::SpecDoc::Recordings.get(test_case)
|
14
|
+
end
|
15
|
+
|
16
|
+
def story story_name
|
17
|
+
method = method_name_to_record(caller)
|
18
|
+
rec = recordings
|
19
|
+
rec.add(:method, method)
|
20
|
+
rec.add(:story, story_name)
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module NanDoc::SpecDoc
|
2
|
+
class CodeSnippet
|
3
|
+
#
|
4
|
+
# internally this does deferred parsing of the thing
|
5
|
+
# a code snippet holds meta information (or maybe content)
|
6
|
+
# for record_ruby nandoc commands in tests.
|
7
|
+
#
|
8
|
+
|
9
|
+
def initialize matches_hash
|
10
|
+
@start_at = matches_hash
|
11
|
+
@stop_at = nil
|
12
|
+
@lines_proc = nil
|
13
|
+
end
|
14
|
+
attr_reader :start_at
|
15
|
+
%w(method line file).each do |meth|
|
16
|
+
sym = meth.to_sym
|
17
|
+
define_method(meth){ || @start_at[sym] }
|
18
|
+
end
|
19
|
+
def describe
|
20
|
+
last = method ? ":in `#{method}'" : ''
|
21
|
+
"#{file}:#{line}#{tail}"
|
22
|
+
end
|
23
|
+
# just hide all the lines from dumps to make irb debugging prettier
|
24
|
+
def file_lines
|
25
|
+
@lines_proc ||= begin
|
26
|
+
stop_at_assert # not really appropriate here
|
27
|
+
same_file_assert # not really appropriate here
|
28
|
+
all_lines = File.open(@start_at[:file],'r').lines.map # sure why not
|
29
|
+
proc{ all_lines }
|
30
|
+
end
|
31
|
+
@lines_proc.call
|
32
|
+
end
|
33
|
+
def line_start
|
34
|
+
@start_at[:line]
|
35
|
+
end
|
36
|
+
def line_stop
|
37
|
+
@stop_at[:line]
|
38
|
+
end
|
39
|
+
def lines_raw
|
40
|
+
@lines_raw ||= file_lines[line_start..(line_stop-2)]
|
41
|
+
end
|
42
|
+
def string_raw
|
43
|
+
@string_raw ||= lines_raw.join('')
|
44
|
+
end
|
45
|
+
def stop_at data=nil
|
46
|
+
data ? (@stop_at = data) : @stop_at
|
47
|
+
end
|
48
|
+
private
|
49
|
+
def same_file_assert
|
50
|
+
@stop_at[:file] == @start_at[:file] or fail("I want life to be"<<
|
51
|
+
" simple. start and stop files must be the same: "<<
|
52
|
+
([@stop_at, @start_at].map{ |x| File.basename(x)}*' and '))
|
53
|
+
end
|
54
|
+
def stop_at_assert
|
55
|
+
stop_at or fail("no record_ruby_stop() found in method "<<
|
56
|
+
"after #{describe}")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module NanDoc::SpecDoc
|
2
|
+
class GenericAgent
|
3
|
+
#
|
4
|
+
# Experimental doohickey that lets random ass objects record
|
5
|
+
# things.
|
6
|
+
#
|
7
|
+
|
8
|
+
include ParseTrace
|
9
|
+
|
10
|
+
def initialize whatever
|
11
|
+
@whatever = whatever
|
12
|
+
end
|
13
|
+
|
14
|
+
def record_ruby
|
15
|
+
caller_info = parse_trace_assert(caller.first)
|
16
|
+
snip = CodeSnippet.new(caller_info)
|
17
|
+
recordings.add(:record_ruby, snip)
|
18
|
+
@last_snip = snip
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def record_ruby_stop
|
23
|
+
line = caller.first
|
24
|
+
caller_info = parse_trace_assert(line)
|
25
|
+
@last_snip or fail("no record_start in method before "<<
|
26
|
+
"record_stop at #{line}")
|
27
|
+
@last_snip.stop_at caller_info
|
28
|
+
end
|
29
|
+
|
30
|
+
# override the one that requires we are in a method
|
31
|
+
def story name
|
32
|
+
recordings.add :story, name
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def recordings
|
37
|
+
Recordings.get_for_key(:generic)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,11 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require(File.expand_path('../../../nandoc.rb',__FILE__)) unless
|
4
|
-
Object.const_defined?('NanDoc')
|
5
|
-
require(File.expand_path('../../spec-doc.rb',__FILE__)) unless
|
6
|
-
NanDoc.const_defined?('SpecDoc')
|
7
|
-
require(File.dirname(__FILE__)+'/mini-test.rb') unless
|
8
|
-
NanDoc::SpecDoc.const_defined?('MiniTest')
|
1
|
+
require 'nandoc'
|
2
|
+
require 'nandoc/spec-doc'
|
9
3
|
|
10
4
|
module NanDoc
|
11
5
|
class MockPrompt
|
@@ -115,7 +109,7 @@ module NanDoc
|
|
115
109
|
re = /^#{Regexp.escape(string)}/
|
116
110
|
str.gsub(re, '')
|
117
111
|
end
|
118
|
-
|
112
|
+
public
|
119
113
|
attr_reader :test_case
|
120
114
|
end
|
121
115
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'nandoc/support/regexp'
|
2
|
+
|
3
|
+
module NanDoc::SpecDoc
|
4
|
+
module ParseTrace
|
5
|
+
#
|
6
|
+
# @return [Regexp] enhanced regex that parses a stack trace line
|
7
|
+
#
|
8
|
+
def parse_trace
|
9
|
+
@parse_trace_re ||= begin
|
10
|
+
NanDoc::Regexp.new(
|
11
|
+
/\A(.*):(\d+)(?::in `([^']+)')?\Z/,
|
12
|
+
:file, :line, :method
|
13
|
+
)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def parse_trace_assert line
|
17
|
+
md = parse_trace.match(line) or
|
18
|
+
fail("couldn't parse trace line: #{line}")
|
19
|
+
h = md.to_hash
|
20
|
+
/\A\d+\Z/ =~ h[:line] or fail("not line: #{h[:line]}.inspect")
|
21
|
+
h[:line] = h[:line].to_i
|
22
|
+
h
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
File without changes
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'nandoc/spec-doc/playback'
|
2
|
+
|
3
|
+
module NanDoc::SpecDoc::Playback
|
4
|
+
class Method
|
5
|
+
# "playback" a recorded ruby (test?) method, generating html
|
6
|
+
|
7
|
+
@handlers = {
|
8
|
+
:cd => [:class, 'Terminal', :run_cd],
|
9
|
+
:cd_end => [:class, 'Terminal', :run_cd_end],
|
10
|
+
:command => [:class, 'Terminal', :run_command],
|
11
|
+
:note => [:class, self, :run_note],
|
12
|
+
:out => [:class, 'Terminal', :run_out],
|
13
|
+
:out_begin => [:class, 'Terminal', :run_out_begin],
|
14
|
+
:record_ruby => [:class, 'Ruby', :run_record_ruby],
|
15
|
+
:story => [:stop]
|
16
|
+
}
|
17
|
+
class << self
|
18
|
+
attr_reader :handlers
|
19
|
+
end
|
20
|
+
|
21
|
+
include PlaybackMethods
|
22
|
+
|
23
|
+
private
|
24
|
+
def initialize test_file_path=nil, things=nil
|
25
|
+
@test_file_path = test_file_path
|
26
|
+
@things = things
|
27
|
+
end
|
28
|
+
def handlers
|
29
|
+
Method.handlers
|
30
|
+
end
|
31
|
+
public
|
32
|
+
def make_html doc
|
33
|
+
fail("need one or two things") unless (1..2).include?(@things.size)
|
34
|
+
fail("can't run method tag filter without at @test_file_path") unless
|
35
|
+
@test_file_path
|
36
|
+
proj = NanDoc::Project.instance
|
37
|
+
proxy = proj.test_framework_proxy_for_file(@test_file_path)
|
38
|
+
sexp = proxy.sexp_get @test_file_path, @things.first
|
39
|
+
run_sexp(doc, sexp, *@things[1..-1])
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
def run_note out, scn
|
43
|
+
node = scn.scan_assert(:note)
|
44
|
+
note_content = node[1].call
|
45
|
+
out.push_raw note_content
|
46
|
+
nil
|
47
|
+
end
|
48
|
+
private
|
49
|
+
def run_sexp doc, sexp, story=nil
|
50
|
+
scn = SexpScanner.new(sexp)
|
51
|
+
scn.scan_assert(:method)
|
52
|
+
scn.skip_to_after_assert(:story, story) if story
|
53
|
+
node = scn.current or fail("unexpected end of sexp")
|
54
|
+
run_sexp_with_handlers(doc, scn)
|
55
|
+
if ! scn.eos?
|
56
|
+
node = scn.current
|
57
|
+
if :method != node.first
|
58
|
+
fail("#{self.class} has no handler for #{node.first.inspect}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'syntax/convertors/html'
|
2
|
+
require 'nandoc/spec-doc/ruby2ruby-standin'
|
3
|
+
|
4
|
+
# require 'nandoc/spec-doc/playback'
|
5
|
+
|
6
|
+
|
7
|
+
module NanDoc::SpecDoc::Playback
|
8
|
+
class Ruby
|
9
|
+
# playback things like as if my name was sega
|
10
|
+
#
|
11
|
+
|
12
|
+
include NanDoc::SpecDoc::Ruby2RubyStandin # re_for_*
|
13
|
+
include PlaybackMethods
|
14
|
+
include Singleton
|
15
|
+
|
16
|
+
class << self
|
17
|
+
alias_method :get_tag_filter, :instance
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@here = NanDoc::Regexp.new( /\A(.*)(?:, ?<<-'?([A-Z]+))/,
|
22
|
+
:keep, :here)
|
23
|
+
|
24
|
+
@inspect = NanDoc::Regexp.new(
|
25
|
+
/\A([ \t]*)(?:nandoc\.inspect[ \t]*)(.+)\Z/,
|
26
|
+
:indent, :tail)
|
27
|
+
|
28
|
+
@prefix = '# '
|
29
|
+
|
30
|
+
@re_out = NanDoc::Regexp.new(/\A[ \t]*nandoc\.out\([ \t]*<<-'?([A-Z]+)/)
|
31
|
+
|
32
|
+
@re_until_do = /\A[ \t]*\)[ \t]*do[ \t]*\Z/
|
33
|
+
end
|
34
|
+
|
35
|
+
def run_record_ruby out, scn
|
36
|
+
node = scn.scan_assert(:record_ruby)
|
37
|
+
code = node[1]
|
38
|
+
@file_lines = code.file_lines.dup # we change the originals
|
39
|
+
while ! scn.eos? && [:inspect, :out].include?(curr = scn.current.first)
|
40
|
+
case curr
|
41
|
+
when :inspect; process_inspect(scn)
|
42
|
+
when :out; process_out(scn)
|
43
|
+
else fail("do me: #{curr.inspect}")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
these = @file_lines[code.start_at[:line]..code.stop_at[:line]-2]
|
47
|
+
block = these.join('')
|
48
|
+
unind = unindent(block)
|
49
|
+
unind.chomp! # sure why not
|
50
|
+
conv = ::Syntax::Convertors::HTML.for_syntax('ruby')
|
51
|
+
html = conv.convert(unind, false)
|
52
|
+
out.push_smart 'pre', 'ruby', html
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# @todo stuff could be cleaned up to use StringScanner but why?
|
59
|
+
|
60
|
+
# @return void. change @file_lines
|
61
|
+
def inspect_oneline node
|
62
|
+
offset = node[2][:line] - 1
|
63
|
+
line = @file_lines[offset]
|
64
|
+
/\A([ \t]*)nandoc.inspect *([^,]+), *([^,]+)\n\Z/ =~ line or fail(
|
65
|
+
"DocSpec hack fail: Why can't we parse this inspect "<<
|
66
|
+
" line?\n#{line.inspect}")
|
67
|
+
ind, keep, val = $1, $2, $3 # actually we don't want $3
|
68
|
+
replace_with = "#{ind}#{keep}\n#{ind}#{@prefix}#{node[1]}\n"
|
69
|
+
# assume no newlines in value when the whole thing was oneline
|
70
|
+
@file_lines[offset] = replace_with
|
71
|
+
nil
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return void. change @file_lines
|
75
|
+
def process_inspect scn
|
76
|
+
node = scn.scan_assert(:inspect)
|
77
|
+
offset = node[2][:line] - 1
|
78
|
+
act = @file_lines[offset]
|
79
|
+
md = @inspect.match_assert(act)
|
80
|
+
md = md.to_hash
|
81
|
+
tail = md[:tail]
|
82
|
+
my_lines = []
|
83
|
+
md2 = @here.match(tail) or return inspect_oneline(node)
|
84
|
+
md2 = md2.to_hash
|
85
|
+
ind = leading_indent(@file_lines[offset])
|
86
|
+
my_lines.push "#{ind}#{md2[:keep]}\n"
|
87
|
+
re = re_for_here(md2[:here])
|
88
|
+
j = offset + 1
|
89
|
+
last = @file_lines.length - 1
|
90
|
+
until re =~ @file_lines[j] || j > last
|
91
|
+
back_one = @file_lines[j].sub(/\A(?: |\t)/,'')
|
92
|
+
my_lines.push back_one.sub(/\A([\t ]*)/){ "#{$1}#{@prefix}" }
|
93
|
+
j += 1
|
94
|
+
end
|
95
|
+
j > last && fail("DocSpec hack fail: #{md2[:here]} not found "<<
|
96
|
+
"anywhere before EOF")
|
97
|
+
(offset..j).each do |k|
|
98
|
+
@file_lines[k] = nil
|
99
|
+
end
|
100
|
+
(0..my_lines.length-1).each do |k|
|
101
|
+
l = offset+k
|
102
|
+
@file_lines[l] = my_lines[k]
|
103
|
+
end
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
# the block content gets output as if it's bare ruby,
|
109
|
+
# the output (whether it was expected or actual we don't care)
|
110
|
+
# gets output with leading comment markers. All of this nonsense is
|
111
|
+
# bs proof of concept that needs to get blown away by ruby2ruby or
|
112
|
+
# something
|
113
|
+
#
|
114
|
+
def process_out scn
|
115
|
+
node = scn.scan_assert(:out)
|
116
|
+
call_offset = node[2][:line] - 1
|
117
|
+
first = @file_lines[call_offset]
|
118
|
+
@re_out.match_assert(first, 'nandoc.out line')
|
119
|
+
j = call_offset + 1
|
120
|
+
last = @file_lines.length - 1
|
121
|
+
j += 1 until j > last || @re_until_do =~ @file_lines[j]
|
122
|
+
j <= last or fail("DocSpec hack fail: Couldn't find do block "<<
|
123
|
+
"anywhere before EOF with #{ReUntilDo}")
|
124
|
+
do_line = @file_lines[j]
|
125
|
+
re = re_for_line_with_same_indent_as(do_line)
|
126
|
+
repl_lines = []
|
127
|
+
j += 1
|
128
|
+
repl_from_here = j
|
129
|
+
j += 1 until j > last || re =~ @file_lines[j]
|
130
|
+
j <= last or fail("DocSpec hack fail: Couldn't find end of do "<<
|
131
|
+
"block anywhere before EOF with #{re}")
|
132
|
+
offset_of_line_with_end = j
|
133
|
+
repl_lines = @file_lines[repl_from_here..offset_of_line_with_end-1]
|
134
|
+
repl_lines.any? or fail("DocSpec hack fail -- no lines")
|
135
|
+
ind_short = leading_indent(do_line)
|
136
|
+
ind_long = leading_indent(repl_lines.first)
|
137
|
+
ind_diff = string_diff_assert(ind_long, ind_short)
|
138
|
+
unindent = re_for_unindent_gsub(ind_diff)
|
139
|
+
repl_lines.map{ |x| x.sub!(unindent, '') }
|
140
|
+
# this changes @file_lines val
|
141
|
+
(0..repl_lines.length-1).each do |l|
|
142
|
+
actual_offset = call_offset + l
|
143
|
+
@file_lines[actual_offset] = repl_lines[l]
|
144
|
+
end
|
145
|
+
erase_from_here = call_offset + repl_lines.length
|
146
|
+
(erase_from_here..offset_of_line_with_end).each do |l|
|
147
|
+
@file_lines[l] = nil
|
148
|
+
end
|
149
|
+
# this is so fragile, it requires multiline blah blah
|
150
|
+
commented_content = node[1].gsub(/^/m, "#{ind_short}#{@prefix}")
|
151
|
+
@file_lines[erase_from_here] = commented_content
|
152
|
+
nil
|
153
|
+
end
|
154
|
+
def re_for_here here
|
155
|
+
/\A[ \t]*#{Regexp.escape(here)}[ \t]*\n?\Z/
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'nandoc/spec-doc/playback'
|
2
|
+
require 'nandoc/spec-doc/playback/terminal/color-to-html'
|
3
|
+
|
4
|
+
module NanDoc::SpecDoc::Playback
|
5
|
+
class Terminal
|
6
|
+
# playback things like as if my name was sega
|
7
|
+
#
|
8
|
+
|
9
|
+
include PlaybackMethods
|
10
|
+
include Singleton
|
11
|
+
include ColorToHtml
|
12
|
+
include Nanoc3::Helpers::HTMLEscape
|
13
|
+
|
14
|
+
class << self
|
15
|
+
alias_method :get_tag_filter, :instance
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@ellipsis_default = '...'
|
20
|
+
@prompt_str_default = '~ > '
|
21
|
+
@prompt_str = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def fake_pwd_push new_dir
|
25
|
+
/\A(.+) > \Z/ =~ prompt_str or
|
26
|
+
fail("can't determine cwd from #{prmpt_str.inspect}")
|
27
|
+
new_pwd = "#{$1}/#{new_dir}"
|
28
|
+
@old_prompts ||= []
|
29
|
+
@old_prompts.push prompt_str
|
30
|
+
@prompt_str = "#{new_pwd} > "
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def fake_pwd_pop
|
35
|
+
@prompt_str = @old_prompts.pop
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor :ellipsis_default
|
39
|
+
|
40
|
+
attr_accessor :prompt_str_default
|
41
|
+
|
42
|
+
def prompt_str
|
43
|
+
@prompt_str ||= @prompt_str_default
|
44
|
+
end
|
45
|
+
|
46
|
+
def run_cd out, scn
|
47
|
+
node = scn.scan_assert(:cd)
|
48
|
+
the_new_directory = node[1]
|
49
|
+
html = prompt_highlight2(prompt_str, "cd #{the_new_directory}")
|
50
|
+
fake_pwd_push the_new_directory
|
51
|
+
out.push_smart 'pre', 'terminal', html
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def run_cd_end out, scn
|
56
|
+
_ = scn.scan_assert(:cd_end)
|
57
|
+
fake_pwd_pop
|
58
|
+
nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def run_command out, scn
|
62
|
+
node = scn.scan_assert(:command)
|
63
|
+
command_content = node[1]
|
64
|
+
html = prompt_highlight2(prompt_str, command_content)
|
65
|
+
out.push_smart 'pre', 'terminal', html
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def run_out out, scn
|
70
|
+
node = scn.scan_assert(:out)
|
71
|
+
raw = node[1]
|
72
|
+
html = terminal_color_to_html(raw) || html_escape(raw)
|
73
|
+
out.push_smart 'pre', 'terminal', html
|
74
|
+
nil
|
75
|
+
end
|
76
|
+
|
77
|
+
def run_out_begin out, scn
|
78
|
+
node = scn.scan_assert(:out_begin)
|
79
|
+
lines = [node[1].strip]
|
80
|
+
if node = scn.scan(:cosmetic_ellipsis)
|
81
|
+
lines.push node[1]
|
82
|
+
else
|
83
|
+
lines.push ellipsis_default
|
84
|
+
end
|
85
|
+
node = scn.scan_assert(:out_end)
|
86
|
+
lines.push node[1]
|
87
|
+
raw = lines.join("\n")
|
88
|
+
html = terminal_color_to_html(raw) || html_escape(raw)
|
89
|
+
out.push_smart 'pre', 'terminal', html
|
90
|
+
nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module NanDoc::SpecDoc::Playback
|
2
|
+
module PlaybackMethods
|
3
|
+
def get_tag_filter record
|
4
|
+
record.first == :class or fail("not a class record #{record.inspect}")
|
5
|
+
ret = nil
|
6
|
+
mixed = record[1]
|
7
|
+
if mixed.kind_of?(Class)
|
8
|
+
if self.kind_of?(mixed)
|
9
|
+
ret = self
|
10
|
+
else
|
11
|
+
ret = mixed.get_tag_filter
|
12
|
+
end
|
13
|
+
else
|
14
|
+
pb = NanDoc::SpecDoc::Playback
|
15
|
+
cls = pb.const_defined?(mixed) && pb.const_get(mixed)
|
16
|
+
# we need the extra check below for Terminal,
|
17
|
+
# which in some cases can have sub-files/modules loaded w/o it
|
18
|
+
# there is room to make more advanced loaders, e.g. with ::Foo::Bar
|
19
|
+
if ! ( cls && cls.respond_to?(:get_tag_filter) )
|
20
|
+
thing = mixed.gsub(/([a-z])([A-Z])/){ "#{$1}-#{$2}" }.downcase
|
21
|
+
require "nandoc/spec-doc/playback/#{thing}.rb"
|
22
|
+
end
|
23
|
+
cls = pb.const_get(mixed)
|
24
|
+
ret = cls.get_tag_filter
|
25
|
+
end
|
26
|
+
ret
|
27
|
+
end
|
28
|
+
|
29
|
+
def run_sexp_with_handlers doc, scn
|
30
|
+
these = handlers
|
31
|
+
while node = scn.current
|
32
|
+
if these.key?(node.first)
|
33
|
+
record = these[node.first]
|
34
|
+
break if record.first == :stop
|
35
|
+
handler = get_tag_filter(record)
|
36
|
+
handler.send(record[2], doc, scn)
|
37
|
+
else
|
38
|
+
break
|
39
|
+
end
|
40
|
+
end
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|