juli 2.0.0
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 +7 -0
- data/.gitignore +26 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.rdoc +39 -0
- data/Rakefile +89 -0
- data/bin/console +14 -0
- data/bin/je +73 -0
- data/bin/juli +82 -0
- data/bin/juli_tb.rb +76 -0
- data/bin/setup +7 -0
- data/juli.gemspec +29 -0
- data/lib/juli.rb +21 -0
- data/lib/juli/absyn.rb +206 -0
- data/lib/juli/command.rb +180 -0
- data/lib/juli/command/file_entry.rb +12 -0
- data/lib/juli/command/recent_update.rb +52 -0
- data/lib/juli/command/sitemap.rb +55 -0
- data/lib/juli/command/tag.rb +81 -0
- data/lib/juli/line_parser.y +212 -0
- data/lib/juli/macro.rb +39 -0
- data/lib/juli/macro/amazon.rb +33 -0
- data/lib/juli/macro/jmap.rb +38 -0
- data/lib/juli/macro/photo.rb +161 -0
- data/lib/juli/macro/tag.rb +136 -0
- data/lib/juli/macro/template.rb +37 -0
- data/lib/juli/macro/template_base.rb +44 -0
- data/lib/juli/macro/wikipedia.rb +19 -0
- data/lib/juli/parser.y +360 -0
- data/lib/juli/template/default.html +64 -0
- data/lib/juli/template/facebook.html +82 -0
- data/lib/juli/template/je-bash-complete +42 -0
- data/lib/juli/template/juli.css +173 -0
- data/lib/juli/template/juli.js +87 -0
- data/lib/juli/template/locale/en.yml +10 -0
- data/lib/juli/template/locale/ja.yml +10 -0
- data/lib/juli/template/prototype.js +4320 -0
- data/lib/juli/template/simple.html +45 -0
- data/lib/juli/template/sitemap.html +78 -0
- data/lib/juli/template/sitemap_order_by_mtime_DESC.html +78 -0
- data/lib/juli/template/slidy.html +126 -0
- data/lib/juli/template/sourceforge.html +71 -0
- data/lib/juli/template/takahashi_method.html +116 -0
- data/lib/juli/util.rb +255 -0
- data/lib/juli/util/juli_i18n.rb +32 -0
- data/lib/juli/version.rb +3 -0
- data/lib/juli/visitor.rb +12 -0
- data/lib/juli/visitor/html.rb +462 -0
- data/lib/juli/visitor/html/helper.rb +97 -0
- data/lib/juli/visitor/html/helper/contents.rb +76 -0
- data/lib/juli/visitor/html/helper/fb_comments.rb +68 -0
- data/lib/juli/visitor/html/helper/fb_like.rb +37 -0
- data/lib/juli/visitor/html/tag_helper.rb +40 -0
- data/lib/juli/visitor/slidy.rb +39 -0
- data/lib/juli/visitor/takahashi_method.rb +41 -0
- data/lib/juli/visitor/tree.rb +135 -0
- data/lib/juli/wiki.rb +52 -0
- data/sample/protected_photo/2012-04-22/DCIM/101_PANA/P1010441.JPG +0 -0
- data/sample/update_public_juli.rb +71 -0
- data/setup.rb +1585 -0
- metadata +211 -0
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
|
3
|
+
class Juli::Visitor::Html
|
4
|
+
# This provides methods used in HTML Erb; called 'helper'.
|
5
|
+
#
|
6
|
+
# Any method here can be used at ERB template under LIB/juli/template/.
|
7
|
+
# Where, LIB is 'lib/' directory in package environment, or
|
8
|
+
# one of $LOAD_PATH in installed environment.
|
9
|
+
#
|
10
|
+
# === How to add new helper(1)
|
11
|
+
# If new method is added in this module, it can be used as helper at
|
12
|
+
# template ERB file. This is the simplest case.
|
13
|
+
#
|
14
|
+
# === How to add new helper(2)
|
15
|
+
# If some preparation is required before calling helper, above way is not
|
16
|
+
# enough. For example, recent_update() helper requires file list
|
17
|
+
# which is sorted by descendant order of mtime timestamp.
|
18
|
+
# It is time-consuming task to prepare such a file list on every
|
19
|
+
# recent_update() calling. It is enough to do that only once when juli(1)
|
20
|
+
# is executed.
|
21
|
+
#
|
22
|
+
# Another example: if the same helper is called more than once in one
|
23
|
+
# template, it could be effective to reduce the CPU resource to
|
24
|
+
# prepare some data and store it in the helper class instance then
|
25
|
+
# each helper uses it just to print the result.
|
26
|
+
#
|
27
|
+
# Juli supports such a case. Let me assume here to write
|
28
|
+
# 'weather_forecast' helper, which draws some local area's
|
29
|
+
# one week weather forecast (juli(1) is offline wiki so that
|
30
|
+
# this kind of realtime information is not a good example though...).
|
31
|
+
# Follow the steps below:
|
32
|
+
# 1. Write WeatherForecast helper class file as
|
33
|
+
# LIB/juli/visitor/html/helper/weather_forecast.rb.
|
34
|
+
# (recent_update.rb could be a reference for this.)
|
35
|
+
# 1. WeatherForecast should inherit
|
36
|
+
# Juli::Visitor::Html::Helper::AbstractHelper.
|
37
|
+
# 1. implement each method: initialize, on_root, run.
|
38
|
+
#
|
39
|
+
# Then, weather_forecast method can be used in ERB template.
|
40
|
+
# This method is dynamically defined at Html visitor and equivalent
|
41
|
+
# to WeatherForecast#run.
|
42
|
+
#
|
43
|
+
module Helper
|
44
|
+
class AbstractHelper
|
45
|
+
include Juli::Util
|
46
|
+
|
47
|
+
# called on 'juli init' to generate config sample template.
|
48
|
+
def self.conf_template
|
49
|
+
''
|
50
|
+
end
|
51
|
+
|
52
|
+
# called when juli(1) starts.
|
53
|
+
def initialize
|
54
|
+
end
|
55
|
+
|
56
|
+
# called on setting up conf to set default key=val
|
57
|
+
def set_conf_default(conf)
|
58
|
+
end
|
59
|
+
|
60
|
+
# called on each parsed document
|
61
|
+
def on_root(in_file, root, visitor)
|
62
|
+
end
|
63
|
+
|
64
|
+
# This will be a helper like 'abstract_helper(args)'
|
65
|
+
def run(*args)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# TRICKY PART: header_id is used for 'contents' helper link.
|
70
|
+
# Absyn::HeaderNode.dom_id cannot be used directory for
|
71
|
+
# this purpose since when clicking a header of 'contents',
|
72
|
+
# document jumps to its contents rather than header so that
|
73
|
+
# header is hidden on browser. To resolve this, header_id
|
74
|
+
# is required for 'contents' helper and it is set at Html visitor.
|
75
|
+
def header_id(n)
|
76
|
+
"#{n.dom_id}_header"
|
77
|
+
end
|
78
|
+
|
79
|
+
# dest's relative path from src
|
80
|
+
#
|
81
|
+
# === EXAMPLE
|
82
|
+
# relative_from('a.txt', 'juli.js'):: → './juli.js'
|
83
|
+
# relative_from('a/b.txt', 'juli.js'):: → '../juli.js'
|
84
|
+
def relative_from(src, dest)
|
85
|
+
result = []
|
86
|
+
Pathname.new(File.dirname(src)).descend{|dir|
|
87
|
+
result << (dir.to_s == '.' ? '.' : '..')
|
88
|
+
}
|
89
|
+
File.join(result, dest)
|
90
|
+
end
|
91
|
+
|
92
|
+
# import all of helper/*.rb files
|
93
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'helper/*.rb')){|v|
|
94
|
+
require File.join('juli/visitor/html/helper', File.basename(v))
|
95
|
+
}
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Juli::Visitor::Html::Helper
|
2
|
+
# Helper-class for 'contents' helper
|
3
|
+
class Contents < AbstractHelper
|
4
|
+
# Check if chapter exists or not
|
5
|
+
class ChapterChecker < Juli::Absyn::Visitor
|
6
|
+
attr_accessor :chapter_exists
|
7
|
+
|
8
|
+
def initialize(opts = {})
|
9
|
+
@chapter_exists = false
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def visit_chapter(n)
|
14
|
+
@chapter_exists = true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ContentsDrawer < Juli::Absyn::Visitor
|
19
|
+
include Juli::Visitor::Html::TagHelper
|
20
|
+
include Juli::Visitor::Html::Helper
|
21
|
+
|
22
|
+
def visit_node(n); ''; end
|
23
|
+
def visit_str(n); ''; end
|
24
|
+
def visit_verbatim(n); ''; end
|
25
|
+
def visit_ordered_list(n); ''; end
|
26
|
+
def visit_unordered_list(n); ''; end
|
27
|
+
def visit_compact_dictionary_list(n); ''; end
|
28
|
+
def visit_compact_dictionary_list_item(n); ''; end
|
29
|
+
def visit_dictionary_list(n); ''; end
|
30
|
+
def visit_dictionary_list_item(n); ''; end
|
31
|
+
|
32
|
+
def visit_array(n)
|
33
|
+
n.array.inject(''){|result, child|
|
34
|
+
result += child.accept(self)
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def visit_chapter(n)
|
39
|
+
content_tag(:li) do
|
40
|
+
content_tag(:a, :href=>'#' + header_id(n)) do
|
41
|
+
n.str
|
42
|
+
end +
|
43
|
+
content_tag(:ol) do
|
44
|
+
n.blocks.accept(self)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# called on each parsed document
|
51
|
+
def on_root(in_file, root, visitor = nil)
|
52
|
+
@root = root
|
53
|
+
end
|
54
|
+
|
55
|
+
# implementation of:
|
56
|
+
# contents
|
57
|
+
#
|
58
|
+
# which draws contents(a.k.a. outline) of this document.
|
59
|
+
#
|
60
|
+
# This visits document tree by ContentsDrawer visitor and
|
61
|
+
# generate HTML contents list.
|
62
|
+
def run(*args)
|
63
|
+
contents_drawer = ContentsDrawer.new
|
64
|
+
chapter_checker = ChapterChecker.new
|
65
|
+
@root.accept(chapter_checker)
|
66
|
+
if chapter_checker.chapter_exists
|
67
|
+
contents_drawer.content_tag(:b, I18n.t('contents')) +
|
68
|
+
contents_drawer.content_tag(:ol) do
|
69
|
+
@root.accept(contents_drawer)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
''
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Juli::Visitor::Html::Helper
|
2
|
+
# Helper-class for 'fb_like' helper
|
3
|
+
class FbComments < AbstractHelper
|
4
|
+
# default HTML template for facebook 'like' button.
|
5
|
+
# You can customize it in .juli/config facebook.like.template entry.
|
6
|
+
#
|
7
|
+
# %{href} in the template will be replaced to the actual URL of
|
8
|
+
# current wiki page.
|
9
|
+
DEFAULT_TEMPLATE =
|
10
|
+
'<fb:comments href="%{href}" num_posts="2" width="470">' +
|
11
|
+
'</fb:comments>'
|
12
|
+
|
13
|
+
# called on 'juli init' to generate config sample template.
|
14
|
+
def self.conf_template
|
15
|
+
<<EOM
|
16
|
+
# Facebook related setup is here.
|
17
|
+
#
|
18
|
+
#url_prefix: 'http://YOUR_HOST/juli'
|
19
|
+
#facebook:
|
20
|
+
# like:
|
21
|
+
# template: '#{Juli::Visitor::Html::Helper::FbLike::DEFAULT_TEMPLATE}'
|
22
|
+
# comments:
|
23
|
+
# template: '#{DEFAULT_TEMPLATE}'
|
24
|
+
EOM
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@fb_conf = conf['facebook']
|
29
|
+
end
|
30
|
+
|
31
|
+
# set default value in conf if no .juli/conf defined.
|
32
|
+
#
|
33
|
+
# Please overwrite this method when this implementation is not your
|
34
|
+
# case.
|
35
|
+
def set_conf_default(conf)
|
36
|
+
conf['url_prefix'] = 'http://YOUR_HOST/juli' if !conf['url_prefix']
|
37
|
+
conf['facebook'] = {} if !conf['facebook']
|
38
|
+
if !conf['facebook']['comments']
|
39
|
+
conf['facebook']['comments'] = {
|
40
|
+
'template' => self.class::DEFAULT_TEMPLATE
|
41
|
+
}
|
42
|
+
end
|
43
|
+
if !conf['facebook']['like']
|
44
|
+
conf['facebook']['like'] = {
|
45
|
+
'template' => Juli::Visitor::Html::Helper::FbLike::DEFAULT_TEMPLATE
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# called on each parsed document
|
51
|
+
def on_root(in_file, root, visitor = nil)
|
52
|
+
@in_file = in_file
|
53
|
+
end
|
54
|
+
|
55
|
+
def run(*args)
|
56
|
+
raise Juli::NoConfig if !conf['url_prefix']
|
57
|
+
raise Juli::NoConfig if !@in_file
|
58
|
+
|
59
|
+
template.gsub('%{href}',
|
60
|
+
conf['url_prefix'] + '/' + to_wikiname(@in_file) + conf['ext'])
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
def template
|
65
|
+
@fb_conf['comments']['template']
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Juli::Visitor::Html::Helper
|
2
|
+
# Helper-class for 'fb_like' helper
|
3
|
+
class FbLike < AbstractHelper
|
4
|
+
# default HTML template for facebook 'like' button.
|
5
|
+
# You can customize it in .juli/config facebook.like.template entry.
|
6
|
+
#
|
7
|
+
# %{href} in the template will be replaced to the actual URL of
|
8
|
+
# current wiki page.
|
9
|
+
DEFAULT_TEMPLATE =
|
10
|
+
'<fb:like href="%{href}" ' +
|
11
|
+
'send="false" layout="button_count" width="450" ' +
|
12
|
+
'show_faces="false">' +
|
13
|
+
'</fb:like>'
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@fb_conf = conf['facebook']
|
17
|
+
end
|
18
|
+
|
19
|
+
# called on each parsed document
|
20
|
+
def on_root(in_file, root, visitor = nil)
|
21
|
+
@in_file = in_file
|
22
|
+
end
|
23
|
+
|
24
|
+
def run(*args)
|
25
|
+
raise Juli::NoConfig if !conf['url_prefix']
|
26
|
+
raise Juli::NoConfig if !@in_file
|
27
|
+
|
28
|
+
template.gsub('%{href}',
|
29
|
+
conf['url_prefix'] + '/' + to_wikiname(@in_file) + conf['ext'])
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def template
|
34
|
+
@fb_conf['like']['template']
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Juli::Visitor::Html
|
2
|
+
# copied from Rails
|
3
|
+
module TagHelper
|
4
|
+
def tag(name, options = nil, open = false)
|
5
|
+
"<#{name}#{tag_options(options) if options}#{open ? ">" : " />"}"
|
6
|
+
end
|
7
|
+
|
8
|
+
def content_tag(name, content_or_options_with_block = nil, options = nil, &block)
|
9
|
+
if block_given?
|
10
|
+
options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
|
11
|
+
content_tag_string(name, block.call, options)
|
12
|
+
else
|
13
|
+
content_tag_string(name, content_or_options_with_block, options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked)
|
19
|
+
BOOLEAN_ATTRIBUTES << BOOLEAN_ATTRIBUTES.map{|s| s.to_sym}
|
20
|
+
|
21
|
+
def content_tag_string(name, content, options)
|
22
|
+
tag_options = tag_options(options) if options
|
23
|
+
"<#{name}#{tag_options}>#{content}</#{name}>"
|
24
|
+
end
|
25
|
+
|
26
|
+
def tag_options(options)
|
27
|
+
if options != {}
|
28
|
+
attrs = []
|
29
|
+
options.each_pair do |key, value|
|
30
|
+
if BOOLEAN_ATTRIBUTES.include?(key)
|
31
|
+
attrs << key if value
|
32
|
+
else
|
33
|
+
attrs << %(#{key}="#{value}") if !value.nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
" #{attrs.sort * ' '}" unless attrs.empty?
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Juli::Visitor
|
2
|
+
# This visits Absyn tree and generates HTML for Slideshow.
|
3
|
+
#
|
4
|
+
# Text files under juli-repository must have '.txt' extention.
|
5
|
+
#
|
6
|
+
# Almost all are the same as Html VISITOR.
|
7
|
+
#
|
8
|
+
# === OPTIONS
|
9
|
+
# -t template:: specify template
|
10
|
+
class Slidy < Html
|
11
|
+
# bulk-mode for slideshow generation doesn't make sense so that
|
12
|
+
# it just warns and return quickly.
|
13
|
+
def run_bulk
|
14
|
+
STDERR.printf("bulk-mode in Slidy is not supported.\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
# overwrite to:
|
18
|
+
# * add 'slide' stylesheet-class at level==1
|
19
|
+
# * include all contents in 'slide' stylesheet-class even title
|
20
|
+
def visit_chapter(n)
|
21
|
+
attr = {:id=>n.dom_id}
|
22
|
+
if n.level==1
|
23
|
+
attr.merge!(:class=>'slide')
|
24
|
+
end
|
25
|
+
content_tag(:div, attr) do
|
26
|
+
header_link(n) +
|
27
|
+
n.blocks.accept(self)
|
28
|
+
end + "\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
# overwrite to generate simple <h#>...</h#>
|
33
|
+
def header_link(n)
|
34
|
+
content_tag("h#{n.level + 1}") do
|
35
|
+
@header_sequence.gen(n.level) + '. ' + n.str
|
36
|
+
end + "\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Juli::Visitor
|
2
|
+
# This visits Absyn tree and generates HTML for
|
3
|
+
# 'Takahashi method' slideshow.
|
4
|
+
#
|
5
|
+
# Text files under juli-repository must have '.txt' extention.
|
6
|
+
#
|
7
|
+
# Almost all are the same as Html VISITOR.
|
8
|
+
#
|
9
|
+
# === OPTIONS
|
10
|
+
# -t template:: specify template
|
11
|
+
class TakahashiMethod < Html
|
12
|
+
# bulk-mode in TakahashiMethod doesn't make sense so that
|
13
|
+
# it just warns and return quickly.
|
14
|
+
def run_bulk
|
15
|
+
STDERR.printf("bulk-mode in TakahashiMethod is not supported.\n")
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
# overwrite to generate simple <h# class=slide>...</h#>
|
20
|
+
def header_link(n)
|
21
|
+
content_tag("h#{n.level + 1}", :class=>'slide') do
|
22
|
+
@header_sequence.gen(n.level) + '. ' + n.str
|
23
|
+
end + "\n"
|
24
|
+
end
|
25
|
+
|
26
|
+
# specify paragraph css
|
27
|
+
def paragraph_css
|
28
|
+
{:class=>'default slide'}
|
29
|
+
end
|
30
|
+
|
31
|
+
# specify blockquote css
|
32
|
+
def blockquote_css
|
33
|
+
{:class=>'slide'}
|
34
|
+
end
|
35
|
+
|
36
|
+
# specify list item css
|
37
|
+
def list_item_css
|
38
|
+
{:class=>'slide'}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'juli/absyn'
|
2
|
+
require 'juli/util'
|
3
|
+
require 'juli/line_parser.tab'
|
4
|
+
|
5
|
+
module Juli::Visitor
|
6
|
+
class LineTree < Juli::LineAbsyn::Visitor
|
7
|
+
include Juli::Util
|
8
|
+
|
9
|
+
def initialize(depth)
|
10
|
+
@depth = depth
|
11
|
+
end
|
12
|
+
|
13
|
+
def print_depth
|
14
|
+
print '| ' * @depth
|
15
|
+
end
|
16
|
+
|
17
|
+
def visit_string(n)
|
18
|
+
print_depth
|
19
|
+
printf "str: %s\n", str_trim(n.str)
|
20
|
+
end
|
21
|
+
|
22
|
+
def visit_wikiname(n)
|
23
|
+
print_depth
|
24
|
+
printf "wiki: %s\n", str_trim(n.str)
|
25
|
+
end
|
26
|
+
|
27
|
+
def visit_url(n)
|
28
|
+
print_depth
|
29
|
+
printf "url: %s\n", str_trim(n.str)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Another VISITOR-pattern for Absyn tree to print tree
|
34
|
+
# structure around each node.
|
35
|
+
class Tree < Juli::Absyn::Visitor
|
36
|
+
include Juli::Util
|
37
|
+
|
38
|
+
# visit root to generate absyn-tree structure.
|
39
|
+
def run_file(in_file, root)
|
40
|
+
@depth = 0
|
41
|
+
super
|
42
|
+
end
|
43
|
+
|
44
|
+
def visit_str(n)
|
45
|
+
print_depth
|
46
|
+
printf("StrNode(%d)\n", -1)
|
47
|
+
@depth += 1
|
48
|
+
process_str(n.str)
|
49
|
+
@depth -= 1
|
50
|
+
end
|
51
|
+
|
52
|
+
def visit_verbatim(n)
|
53
|
+
print_depth
|
54
|
+
printf("verbatim: %s\n", str_trim(n.str))
|
55
|
+
end
|
56
|
+
|
57
|
+
def visit_array(n)
|
58
|
+
print_depth
|
59
|
+
printf("Array\n")
|
60
|
+
@depth += 1
|
61
|
+
for child in n.array do
|
62
|
+
child.accept(self)
|
63
|
+
end
|
64
|
+
@depth -= 1
|
65
|
+
end
|
66
|
+
|
67
|
+
def visit_chapter(n)
|
68
|
+
print_depth
|
69
|
+
printf("Chapter(%d %s)\n", n.level, n.str)
|
70
|
+
@depth += 1
|
71
|
+
n.blocks.accept(self)
|
72
|
+
@depth -= 1
|
73
|
+
end
|
74
|
+
|
75
|
+
def visit_ordered_list(n)
|
76
|
+
visit_list("OrderedList\n", n)
|
77
|
+
end
|
78
|
+
|
79
|
+
def visit_unordered_list(n)
|
80
|
+
visit_list("UnorderedList\n", n)
|
81
|
+
end
|
82
|
+
|
83
|
+
def visit_compact_dictionary_list(n)
|
84
|
+
visit_list("CompactDictionaryList\n", n)
|
85
|
+
end
|
86
|
+
|
87
|
+
def visit_compact_dictionary_list_item(n)
|
88
|
+
visit_x_dictionary_list_item(n, "CompactDictionaryListItem\n")
|
89
|
+
end
|
90
|
+
|
91
|
+
def visit_dictionary_list(n)
|
92
|
+
visit_list("DictionaryList\n", n)
|
93
|
+
end
|
94
|
+
|
95
|
+
def visit_dictionary_list_item(n)
|
96
|
+
visit_x_dictionary_list_item(n, "DictionaryListItem\n")
|
97
|
+
end
|
98
|
+
|
99
|
+
def visit_quote(n)
|
100
|
+
print_depth
|
101
|
+
printf("QuoteNode(%s)\n", str_trim(n.str))
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
def print_depth
|
106
|
+
print '| ' * @depth
|
107
|
+
end
|
108
|
+
|
109
|
+
def visit_list(class_str, n)
|
110
|
+
print_depth
|
111
|
+
printf(class_str)
|
112
|
+
@depth += 1
|
113
|
+
for child in n.array do
|
114
|
+
child.accept(self)
|
115
|
+
end
|
116
|
+
@depth -= 1
|
117
|
+
end
|
118
|
+
|
119
|
+
# common for both dictionary list item and compact dictionary list item
|
120
|
+
def visit_x_dictionary_list_item(n, node_name)
|
121
|
+
print_depth
|
122
|
+
printf(node_name)
|
123
|
+
@depth += 1
|
124
|
+
process_str(n.term)
|
125
|
+
process_str(n.str)
|
126
|
+
@depth -= 1
|
127
|
+
end
|
128
|
+
|
129
|
+
# str -> Juli::LineAbsyn -> print with depth
|
130
|
+
def process_str(str)
|
131
|
+
Juli::LineParser.new.parse(str, Juli::Wiki.wikinames).
|
132
|
+
accept(LineTree.new(@depth))
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|