nandoc 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 +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
|