nandoc 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/README +5 -4
  2. data/Rakefile +1 -1
  3. data/bin/nandoc +2 -1
  4. data/doc/FAQ.md +3 -0
  5. data/doc/PROVISO.md +39 -0
  6. data/doc/commands/diff.md +49 -0
  7. data/doc/svg/less-fonts.svg +2 -2
  8. data/lib/nandoc/cli/README.md +6 -0
  9. data/lib/nandoc/cli/command-methods.rb +38 -0
  10. data/lib/nandoc/cli/option-methods/exclusive-options.rb +56 -0
  11. data/lib/nandoc/cli/option-methods/option-enum.rb +64 -0
  12. data/lib/nandoc/cli/option-methods.rb +35 -0
  13. data/lib/nandoc/cli.rb +3 -0
  14. data/lib/nandoc/commands/create-nandoc-site.rb +9 -12
  15. data/lib/nandoc/commands/diff.rb +14 -11
  16. data/lib/nandoc/commands.rb +9 -0
  17. data/lib/nandoc/{config.rb → core/config.rb} +18 -9
  18. data/lib/nandoc/core/project.rb +50 -0
  19. data/lib/nandoc/doc/hack-free-zone-defined.md +33 -0
  20. data/lib/nandoc/erb/agent.rb +5 -5
  21. data/lib/nandoc/{test/minitest-extlib.rb → extlib/minitest.rb} +1 -1
  22. data/lib/nandoc/filters/builtin-tags/fence/terminal.rb +24 -0
  23. data/lib/nandoc/filters/builtin-tags/fence-dispatcher.rb +43 -0
  24. data/lib/nandoc/filters/builtin-tags/fences.rb +4 -0
  25. data/lib/nandoc/filters/builtin-tags/see-test.rb +67 -0
  26. data/lib/nandoc/filters/builtin-tags.rb +11 -0
  27. data/lib/nandoc/filters/custom-tag.rb +43 -0
  28. data/lib/nandoc/filters/custom-tags.rb +19 -0
  29. data/lib/nandoc/filters/tag-parse-instance-methods.rb +11 -0
  30. data/lib/nandoc/filters/tag-parser.rb +206 -0
  31. data/lib/nandoc/filters.rb +11 -585
  32. data/lib/nandoc/{cri-hacks.rb → hacks/cri-hacks.rb} +4 -3
  33. data/lib/nandoc/{data-source.rb → hacks/data-source.rb} +5 -4
  34. data/lib/nandoc/{item-class-hacks.rb → hacks/item-class-hacks.rb} +3 -1
  35. data/lib/nandoc/hacks.rb +6 -0
  36. data/lib/nandoc/helpers/menu-bouncy.rb +1 -1
  37. data/lib/nandoc/helpers/site-map.rb +3 -0
  38. data/lib/nandoc/helpers.rb +1 -1
  39. data/lib/nandoc/html/tags.rb +65 -0
  40. data/lib/nandoc/html.rb +6 -0
  41. data/lib/nandoc/parse-readme.rb +4 -0
  42. data/lib/nandoc/spec-doc/agent-instance-methods.rb +24 -0
  43. data/lib/nandoc/spec-doc/code-snippet.rb +59 -0
  44. data/lib/nandoc/spec-doc/generic-agent.rb +40 -0
  45. data/lib/nandoc/spec-doc/mock-prompt.rb +3 -9
  46. data/lib/nandoc/spec-doc/parse-trace.rb +25 -0
  47. data/lib/nandoc/spec-doc/{mini-test/spec-instance-methods.rb → playback/html/foo-bar.rb} +0 -0
  48. data/lib/nandoc/spec-doc/playback/html.rb +2 -0
  49. data/lib/nandoc/spec-doc/playback/players/method.rb +64 -0
  50. data/lib/nandoc/spec-doc/playback/players/ruby.rb +158 -0
  51. data/lib/nandoc/spec-doc/playback/players/terminal.rb +93 -0
  52. data/lib/nandoc/spec-doc/playback/players.rb +4 -0
  53. data/lib/nandoc/spec-doc/playback/support/playback-methods.rb +44 -0
  54. data/lib/nandoc/spec-doc/playback/support/sexp-scanner.rb +61 -0
  55. data/lib/nandoc/spec-doc/playback/support.rb +3 -0
  56. data/lib/nandoc/spec-doc/playback/terminal/color-to-html.rb +100 -0
  57. data/lib/nandoc/spec-doc/playback.rb +3 -0
  58. data/lib/nandoc/spec-doc/recordings.rb +55 -0
  59. data/lib/nandoc/spec-doc/ruby2ruby-standin.rb +37 -0
  60. data/lib/nandoc/spec-doc/test-case-agent.rb +1 -1
  61. data/lib/nandoc/spec-doc/{mini-test.rb → test-framework/mini-test/proxy.rb} +9 -31
  62. data/lib/nandoc/spec-doc/{test-framework-proxy.rb → test-framework/proxy.rb} +27 -50
  63. data/lib/nandoc/spec-doc.rb +57 -13
  64. data/lib/nandoc/{test → support}/diff-to-string.rb +0 -0
  65. data/lib/nandoc/support/regexp-enhance.rb +6 -0
  66. data/lib/nandoc/support/regexp.rb +12 -0
  67. data/lib/nandoc/support/secret-parent.rb +21 -0
  68. data/lib/nandoc/support/shared-attr-reader.rb +32 -0
  69. data/lib/nandoc/support/site-merge.rb +1 -1
  70. data/lib/nandoc/support/site-methods.rb +4 -4
  71. data/lib/nandoc/support/stream-colorizer.rb +1 -1
  72. data/lib/nandoc/support/string-methods.rb +56 -0
  73. data/lib/nandoc.rb +12 -35
  74. data/proto/README.md +4 -2
  75. data/test/test.rb +1 -0
  76. metadata +58 -25
  77. data/doc/bar/baz.md +0 -4
  78. data/doc/bar/bliff.md +0 -8
  79. data/doc/foo.md +0 -5
  80. data/doc/getting-started.rb +0 -13
  81. data/lib/nandoc/spec-doc/support-modules.rb +0 -158
  82. data/lib/nandoc/spec-doc/test-framework-dispatcher.rb +0 -15
  83. data/lib/nandoc/support-modules.rb +0 -273
  84. data/lib/nandoc/treebis/NOGIT-DOCS/NEWS.md +0 -5
  85. data/lib/nandoc/treebis/NOGIT-README.md +0 -65
  86. data/lib/nandoc/treebis/nandoc.persistent.json +0 -3
@@ -1,7 +1,7 @@
1
1
  module NanDoc::Helpers
2
2
  module NanDocHelpers
3
3
  # @todo-now test this
4
- include NanDoc::StringFormatting # indent() unindent() no_blank_lines()
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
@@ -0,0 +1,6 @@
1
+ module NanDoc::Html
2
+ end
3
+
4
+ me = File.dirname(__FILE__)+'/html'
5
+ require me + '/tags.rb'
6
+
@@ -1,4 +1,8 @@
1
1
  module NanDoc
2
+ #
3
+ # @dependencies: none
4
+ #
5
+
2
6
  class ParseReadme
3
7
  #
4
8
  # If you are really really crazy then you don't like
@@ -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
- # @todo figure out how to get the symlink hack to work and avoid
2
- # this nonsense all the while letting this be a valid requireable file
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
@@ -0,0 +1,2 @@
1
+ me = File.dirname(__FILE__)+'/html'
2
+ require me + '/foo-bar.rb'
@@ -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,4 @@
1
+ me = File.dirname(__FILE__)+'/players'
2
+ require me + '/method.rb'
3
+ require me + '/ruby.rb'
4
+ require me + '/terminal.rb'
@@ -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