sqlpostgres 1.2.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/Gemfile +8 -0
- data/Gemfile.lock +22 -0
- data/LICENSE.md +23 -0
- data/README.rdoc +59 -0
- data/Rakefile +32 -0
- data/VERSION +1 -0
- data/doc/BUGS +2 -0
- data/doc/examples/README +6 -0
- data/doc/examples/connection.rb +16 -0
- data/doc/examples/connection_auto.rb +22 -0
- data/doc/examples/connection_ctor.rb +18 -0
- data/doc/examples/connection_default.rb +15 -0
- data/doc/examples/connection_exec.rb +18 -0
- data/doc/examples/connection_manual.rb +12 -0
- data/doc/examples/connection_wrapped_new.rb +13 -0
- data/doc/examples/connection_wrapped_open.rb +13 -0
- data/doc/examples/cursor.rb +38 -0
- data/doc/examples/include_module.rb +9 -0
- data/doc/examples/include_module2.rb +12 -0
- data/doc/examples/insert.rb +30 -0
- data/doc/examples/insert2.rb +36 -0
- data/doc/examples/insert_bytea.rb +16 -0
- data/doc/examples/insert_bytea_array.rb +17 -0
- data/doc/examples/insert_default_values.rb +16 -0
- data/doc/examples/insert_insert.rb +16 -0
- data/doc/examples/insert_insert_default.rb +16 -0
- data/doc/examples/insert_insert_select.rb +20 -0
- data/doc/examples/insert_select.rb +20 -0
- data/doc/examples/interval.rb +17 -0
- data/doc/examples/savepoint.rb +38 -0
- data/doc/examples/select.rb +33 -0
- data/doc/examples/select2.rb +36 -0
- data/doc/examples/select_cross_join.rb +18 -0
- data/doc/examples/select_distinct.rb +18 -0
- data/doc/examples/select_distinct_on +19 -0
- data/doc/examples/select_for_update.rb +18 -0
- data/doc/examples/select_from.rb +17 -0
- data/doc/examples/select_from_subselect.rb +20 -0
- data/doc/examples/select_group_by.rb +19 -0
- data/doc/examples/select_having.rb +20 -0
- data/doc/examples/select_join_on.rb +18 -0
- data/doc/examples/select_join_using.rb +18 -0
- data/doc/examples/select_limit.rb +19 -0
- data/doc/examples/select_natural_join.rb +18 -0
- data/doc/examples/select_offset.rb +19 -0
- data/doc/examples/select_order_by.rb +20 -0
- data/doc/examples/select_select.rb +30 -0
- data/doc/examples/select_select_alias.rb +30 -0
- data/doc/examples/select_select_expression.rb +31 -0
- data/doc/examples/select_select_literal.rb +24 -0
- data/doc/examples/select_union.rb +21 -0
- data/doc/examples/select_where_array.rb +18 -0
- data/doc/examples/select_where_in.rb +18 -0
- data/doc/examples/select_where_string.rb +18 -0
- data/doc/examples/simple.rb +34 -0
- data/doc/examples/transaction.rb +30 -0
- data/doc/examples/transaction_abort.rb +30 -0
- data/doc/examples/transaction_commit.rb +34 -0
- data/doc/examples/translate_substitute_values.rb +17 -0
- data/doc/examples/update.rb +32 -0
- data/doc/examples/update2.rb +44 -0
- data/doc/examples/update_only.rb +17 -0
- data/doc/examples/update_set.rb +17 -0
- data/doc/examples/update_set_array.rb +16 -0
- data/doc/examples/update_set_bytea.rb +16 -0
- data/doc/examples/update_set_expression.rb +16 -0
- data/doc/examples/update_set_subselect.rb +20 -0
- data/doc/examples/update_where.rb +17 -0
- data/doc/examples/use_prefix.rb +8 -0
- data/doc/examples/use_prefix2.rb +11 -0
- data/doc/index.html +31 -0
- data/doc/insertexamples.rb +9 -0
- data/doc/makemanual +4 -0
- data/doc/makerdoc +5 -0
- data/doc/manual.dbk +622 -0
- data/lib/sqlpostgres/Connection.rb +198 -0
- data/lib/sqlpostgres/Cursor.rb +157 -0
- data/lib/sqlpostgres/Delete.rb +67 -0
- data/lib/sqlpostgres/Exceptions.rb +15 -0
- data/lib/sqlpostgres/Insert.rb +279 -0
- data/lib/sqlpostgres/NullConnection.rb +22 -0
- data/lib/sqlpostgres/PgBit.rb +73 -0
- data/lib/sqlpostgres/PgBox.rb +37 -0
- data/lib/sqlpostgres/PgCidr.rb +21 -0
- data/lib/sqlpostgres/PgCircle.rb +75 -0
- data/lib/sqlpostgres/PgInet.rb +21 -0
- data/lib/sqlpostgres/PgInterval.rb +208 -0
- data/lib/sqlpostgres/PgLineSegment.rb +37 -0
- data/lib/sqlpostgres/PgMacAddr.rb +21 -0
- data/lib/sqlpostgres/PgPath.rb +64 -0
- data/lib/sqlpostgres/PgPoint.rb +65 -0
- data/lib/sqlpostgres/PgPolygon.rb +56 -0
- data/lib/sqlpostgres/PgTime.rb +77 -0
- data/lib/sqlpostgres/PgTimeWithTimeZone.rb +98 -0
- data/lib/sqlpostgres/PgTimestamp.rb +93 -0
- data/lib/sqlpostgres/PgTwoPoints.rb +54 -0
- data/lib/sqlpostgres/PgType.rb +34 -0
- data/lib/sqlpostgres/PgWrapper.rb +41 -0
- data/lib/sqlpostgres/Savepoint.rb +98 -0
- data/lib/sqlpostgres/Select.rb +855 -0
- data/lib/sqlpostgres/Transaction.rb +120 -0
- data/lib/sqlpostgres/Translate.rb +436 -0
- data/lib/sqlpostgres/Update.rb +188 -0
- data/lib/sqlpostgres.rb +67 -0
- data/test/Assert.rb +72 -0
- data/test/Connection.test.rb +246 -0
- data/test/Cursor.test.rb +190 -0
- data/test/Delete.test.rb +68 -0
- data/test/Insert.test.rb +123 -0
- data/test/MockPGconn.rb +62 -0
- data/test/NullConnection.test.rb +32 -0
- data/test/PgBit.test.rb +98 -0
- data/test/PgBox.test.rb +108 -0
- data/test/PgCidr.test.rb +61 -0
- data/test/PgCircle.test.rb +107 -0
- data/test/PgInet.test.rb +61 -0
- data/test/PgInterval.test.rb +180 -0
- data/test/PgLineSegment.test.rb +108 -0
- data/test/PgMacAddr.test.rb +61 -0
- data/test/PgPath.test.rb +106 -0
- data/test/PgPoint.test.rb +100 -0
- data/test/PgPolygon.test.rb +95 -0
- data/test/PgTime.test.rb +120 -0
- data/test/PgTimeWithTimeZone.test.rb +117 -0
- data/test/PgTimestamp.test.rb +134 -0
- data/test/RandomThings.rb +25 -0
- data/test/Savepoint.test.rb +286 -0
- data/test/Select.test.rb +930 -0
- data/test/Test.rb +62 -0
- data/test/TestConfig.rb +21 -0
- data/test/TestSetup.rb +13 -0
- data/test/TestUtil.rb +92 -0
- data/test/Transaction.test.rb +275 -0
- data/test/Translate.test.rb +354 -0
- data/test/Update.test.rb +227 -0
- data/test/roundtrip.test.rb +565 -0
- data/test/test +34 -0
- data/tools/exampleinserter/ExampleInserter.rb +177 -0
- data/tools/rdoc/ChangeLog +796 -0
- data/tools/rdoc/EXAMPLE.rb +48 -0
- data/tools/rdoc/MANIFEST +58 -0
- data/tools/rdoc/Makefile +27 -0
- data/tools/rdoc/NEW_FEATURES +226 -0
- data/tools/rdoc/README +390 -0
- data/tools/rdoc/ToDo +6 -0
- data/tools/rdoc/contrib/Index +6 -0
- data/tools/rdoc/contrib/xslfo/ChangeLog +181 -0
- data/tools/rdoc/contrib/xslfo/README +106 -0
- data/tools/rdoc/contrib/xslfo/TODO +10 -0
- data/tools/rdoc/contrib/xslfo/convert.xsl +151 -0
- data/tools/rdoc/contrib/xslfo/demo/README +21 -0
- data/tools/rdoc/contrib/xslfo/demo/rdocfo +99 -0
- data/tools/rdoc/contrib/xslfo/fcm.xsl +54 -0
- data/tools/rdoc/contrib/xslfo/files.xsl +62 -0
- data/tools/rdoc/contrib/xslfo/labeled-lists.xsl +66 -0
- data/tools/rdoc/contrib/xslfo/lists.xsl +44 -0
- data/tools/rdoc/contrib/xslfo/modules.xsl +152 -0
- data/tools/rdoc/contrib/xslfo/rdoc.xsl +75 -0
- data/tools/rdoc/contrib/xslfo/source.xsl +66 -0
- data/tools/rdoc/contrib/xslfo/styles.xsl +69 -0
- data/tools/rdoc/contrib/xslfo/tables.xsl +67 -0
- data/tools/rdoc/contrib/xslfo/utils.xsl +21 -0
- data/tools/rdoc/debian/changelog +33 -0
- data/tools/rdoc/debian/compat +1 -0
- data/tools/rdoc/debian/control +20 -0
- data/tools/rdoc/debian/copyright +10 -0
- data/tools/rdoc/debian/dirs +2 -0
- data/tools/rdoc/debian/docs +2 -0
- data/tools/rdoc/debian/rdoc.1 +252 -0
- data/tools/rdoc/debian/rdoc.manpages +1 -0
- data/tools/rdoc/debian/rdoc.pod +149 -0
- data/tools/rdoc/debian/rules +9 -0
- data/tools/rdoc/dot/dot.rb +255 -0
- data/tools/rdoc/etc/rdoc.dtd +203 -0
- data/tools/rdoc/install.rb +137 -0
- data/tools/rdoc/markup/install.rb +43 -0
- data/tools/rdoc/markup/sample/sample.rb +42 -0
- data/tools/rdoc/markup/simple_markup/fragments.rb +323 -0
- data/tools/rdoc/markup/simple_markup/inline.rb +348 -0
- data/tools/rdoc/markup/simple_markup/lines.rb +147 -0
- data/tools/rdoc/markup/simple_markup/preprocess.rb +68 -0
- data/tools/rdoc/markup/simple_markup/to_html.rb +281 -0
- data/tools/rdoc/markup/simple_markup.rb +474 -0
- data/tools/rdoc/markup/test/AllTests.rb +2 -0
- data/tools/rdoc/markup/test/TestInline.rb +151 -0
- data/tools/rdoc/markup/test/TestParse.rb +411 -0
- data/tools/rdoc/rdoc/code_objects.rb +536 -0
- data/tools/rdoc/rdoc/diagram.rb +331 -0
- data/tools/rdoc/rdoc/generators/chm_generator.rb +112 -0
- data/tools/rdoc/rdoc/generators/html_generator.rb +1268 -0
- data/tools/rdoc/rdoc/generators/template/chm/chm.rb +86 -0
- data/tools/rdoc/rdoc/generators/template/html/html.rb +705 -0
- data/tools/rdoc/rdoc/generators/template/html/kilmer.rb +377 -0
- data/tools/rdoc/rdoc/generators/template/xml/rdf.rb +110 -0
- data/tools/rdoc/rdoc/generators/template/xml/xml.rb +110 -0
- data/tools/rdoc/rdoc/generators/xml_generator.rb +130 -0
- data/tools/rdoc/rdoc/options.rb +451 -0
- data/tools/rdoc/rdoc/parsers/parse_c.rb +287 -0
- data/tools/rdoc/rdoc/parsers/parse_f95.rb +118 -0
- data/tools/rdoc/rdoc/parsers/parse_rb.rb +2311 -0
- data/tools/rdoc/rdoc/parsers/parse_simple.rb +37 -0
- data/tools/rdoc/rdoc/parsers/parserfactory.rb +75 -0
- data/tools/rdoc/rdoc/rdoc.rb +219 -0
- data/tools/rdoc/rdoc/template.rb +234 -0
- data/tools/rdoc/rdoc/tokenstream.rb +25 -0
- data/tools/rdoc/rdoc.rb +9 -0
- metadata +291 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
require 'rbconfig'
|
|
2
|
+
require 'find'
|
|
3
|
+
require 'ftools'
|
|
4
|
+
|
|
5
|
+
include Config
|
|
6
|
+
|
|
7
|
+
$ruby = CONFIG['ruby_install_name']
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Install a binary file. We patch in on the way through to
|
|
11
|
+
# insert a #! line. If this is a Unix install, we name
|
|
12
|
+
# the command (for example) 'rdoc' and let the shebang line
|
|
13
|
+
# handle running it. Under windows, we add a '.rb' extension
|
|
14
|
+
# and let file associations to their stuff
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
def installBIN(from, opfile)
|
|
18
|
+
|
|
19
|
+
tmp_dir = nil
|
|
20
|
+
for t in [".", "/tmp", "c:/temp", $bindir]
|
|
21
|
+
stat = File.stat(t) rescue next
|
|
22
|
+
if stat.directory? and stat.writable?
|
|
23
|
+
tmp_dir = t
|
|
24
|
+
break
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
fail "Cannot find a temporary directory" unless tmp_dir
|
|
29
|
+
tmp_file = File.join(tmp_dir, "_tmp")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
File.open(from) do |ip|
|
|
33
|
+
File.open(tmp_file, "w") do |op|
|
|
34
|
+
ruby = File.join($realbindir, $ruby)
|
|
35
|
+
op.puts "#!#{ruby}"
|
|
36
|
+
op.write ip.read
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
opfile += ".rb" if CONFIG["target_os"] =~ /mswin/i
|
|
41
|
+
File::install(tmp_file, File.join($bindir, opfile), 0755, true)
|
|
42
|
+
File::unlink(tmp_file)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
$sitedir = CONFIG["rubylibdir"]
|
|
50
|
+
unless $sitedir
|
|
51
|
+
version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
|
52
|
+
$libdir = File.join(CONFIG["libdir"], "ruby", version)
|
|
53
|
+
$sitedir = $:.find {|x| x =~ /site_ruby/}
|
|
54
|
+
if !$sitedir
|
|
55
|
+
$sitedir = File.join($libdir, "site_ruby")
|
|
56
|
+
elsif $sitedir !~ Regexp.quote(version)
|
|
57
|
+
$sitedir = File.join($sitedir, version)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
$bindir = CONFIG["bindir"]
|
|
62
|
+
|
|
63
|
+
$realbindir = $bindir
|
|
64
|
+
|
|
65
|
+
bindir = CONFIG["bindir"]
|
|
66
|
+
if (destdir = ENV['DESTDIR'])
|
|
67
|
+
$bindir = destdir + $bindir
|
|
68
|
+
$sitedir = destdir + $sitedir
|
|
69
|
+
|
|
70
|
+
File::makedirs($bindir)
|
|
71
|
+
File::makedirs($sitedir)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
rdoc_dest = File.join($sitedir, "rdoc")
|
|
75
|
+
dot_dest = File.join($sitedir, "dot")
|
|
76
|
+
rdoc_generators = File.join(rdoc_dest, "generators")
|
|
77
|
+
rdoc_templates = File.join(rdoc_generators, "template")
|
|
78
|
+
rdoc_parsers = File.join(rdoc_dest, "parsers")
|
|
79
|
+
|
|
80
|
+
File::makedirs(rdoc_dest,
|
|
81
|
+
dot_dest,
|
|
82
|
+
rdoc_generators,
|
|
83
|
+
rdoc_templates,
|
|
84
|
+
rdoc_parsers,
|
|
85
|
+
true)
|
|
86
|
+
|
|
87
|
+
File::chmod(0755, rdoc_dest)
|
|
88
|
+
|
|
89
|
+
# The library files
|
|
90
|
+
files = %w{
|
|
91
|
+
rdoc/code_objects.rb
|
|
92
|
+
rdoc/generators/*_generator.rb
|
|
93
|
+
rdoc/options.rb
|
|
94
|
+
rdoc/parsers/parserfactory.rb
|
|
95
|
+
rdoc/parsers/parse_*.rb
|
|
96
|
+
rdoc/template.rb
|
|
97
|
+
rdoc/tokenstream.rb
|
|
98
|
+
rdoc/diagram.rb
|
|
99
|
+
rdoc/rdoc.rb
|
|
100
|
+
dot/dot.rb
|
|
101
|
+
}.collect {|f| Dir.glob(f)}.flatten
|
|
102
|
+
|
|
103
|
+
for template in ["chm", "html", "xml"]
|
|
104
|
+
File::makedirs(File.join(rdoc_templates, template), true)
|
|
105
|
+
files.concat Dir.glob("rdoc/generators/template/#{template}/*.rb")
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
for aFile in files
|
|
109
|
+
File::install(aFile, File.join($sitedir, aFile), 0644, true)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# and the executable
|
|
113
|
+
|
|
114
|
+
installBIN("rdoc.rb", "rdoc")
|
|
115
|
+
|
|
116
|
+
# Temporary - we used to install html_generator in the rdoc
|
|
117
|
+
# directory, but now it's moved
|
|
118
|
+
|
|
119
|
+
File.unlink(File.join(rdoc_dest, "html_generator.rb")) rescue 1;
|
|
120
|
+
|
|
121
|
+
# and we used to have the templates under html_template
|
|
122
|
+
template = File.join(rdoc_dest, "generators", "html_template")
|
|
123
|
+
File.unlink(File.join(template, "standard.rb")) rescue 1;
|
|
124
|
+
File.unlink(File.join(template, "kilmer.rb")) rescue 1;
|
|
125
|
+
|
|
126
|
+
# and then they were in template/ ...
|
|
127
|
+
template = File.join(rdoc_dest, "generators", "template")
|
|
128
|
+
File.unlink(File.join(template, "standard.rb")) rescue 1;
|
|
129
|
+
File.unlink(File.join(template, "kilmer.rb")) rescue 1;
|
|
130
|
+
File.unlink(File.join(template, "xml.rb")) rescue 1;
|
|
131
|
+
File.unlink(File.join(template, "rdf.rb")) rescue 1;
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# 'Markup' will eventually be a separate package, but
|
|
135
|
+
# for now we'll install it automatically
|
|
136
|
+
|
|
137
|
+
Dir.chdir("markup") && system("#$ruby install.rb")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'rbconfig'
|
|
2
|
+
require 'find'
|
|
3
|
+
require 'ftools'
|
|
4
|
+
|
|
5
|
+
include Config
|
|
6
|
+
|
|
7
|
+
sitedir = CONFIG["rubylibdir"]
|
|
8
|
+
unless sitedir
|
|
9
|
+
version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
|
|
10
|
+
libdir = File.join(CONFIG["libdir"], "ruby", version)
|
|
11
|
+
sitedir = $:.find {|x| x =~ /site_ruby/}
|
|
12
|
+
if !sitedir
|
|
13
|
+
sitedir = File.join(libdir, "site_ruby")
|
|
14
|
+
elsif sitedir !~ Regexp.quote(version)
|
|
15
|
+
sitedir = File.join(sitedir, version)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
if (destdir = ENV['DESTDIR'])
|
|
20
|
+
sitedir = destdir + sitedir
|
|
21
|
+
File::makedirs(sitedir)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if !File.directory?(sitedir)
|
|
25
|
+
$stderr.puts "Cannot find sitedir #{sitedir}"
|
|
26
|
+
exit 1
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
dest = File.join(sitedir, "markup")
|
|
30
|
+
|
|
31
|
+
File.mkpath(dest, true)
|
|
32
|
+
|
|
33
|
+
Find.find("simple_markup.rb", "simple_markup") do |fname|
|
|
34
|
+
if File.directory?(fname)
|
|
35
|
+
next if fname =~ /CVS/
|
|
36
|
+
File.mkpath(File.join(dest, fname), true)
|
|
37
|
+
else
|
|
38
|
+
next unless fname =~ /\.rb$/
|
|
39
|
+
next if fname =~ /install.rb$/
|
|
40
|
+
File.install(fname, File.join(dest, fname), 0444, true)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# This program illustrates the basic use of the SimpleMarkup
|
|
2
|
+
# class. It extracts the first comment block from the
|
|
3
|
+
# simple_markup.rb file and converts it into HTML on
|
|
4
|
+
# standard output. Run it using
|
|
5
|
+
#
|
|
6
|
+
# % ruby sample.rb
|
|
7
|
+
#
|
|
8
|
+
# You should be in the sample/ directory when you do this,
|
|
9
|
+
# as it hardwires the path to the files it needs to require.
|
|
10
|
+
# This isn't necessary in the code you write once you've
|
|
11
|
+
# installed the package.
|
|
12
|
+
#
|
|
13
|
+
# For a better way of formatting code comment blocks (and more)
|
|
14
|
+
# see the rdoc package.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
$:.unshift "../.."
|
|
18
|
+
|
|
19
|
+
require 'markup/simple_markup'
|
|
20
|
+
require 'markup/simple_markup/to_html'
|
|
21
|
+
|
|
22
|
+
# Extract the comment block from the source file
|
|
23
|
+
|
|
24
|
+
input_string = ""
|
|
25
|
+
|
|
26
|
+
File.foreach("../simple_markup.rb") do |line|
|
|
27
|
+
break unless line.gsub!(/^\# ?/, '')
|
|
28
|
+
input_string << line
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Create a markup object
|
|
32
|
+
markup = SM::SimpleMarkup.new
|
|
33
|
+
|
|
34
|
+
# Attach it to an HTML formatter
|
|
35
|
+
h = SM::ToHtml.new
|
|
36
|
+
|
|
37
|
+
# And convert out comment block to html. Wrap it a body
|
|
38
|
+
# tag pair to let browsers view it
|
|
39
|
+
|
|
40
|
+
puts "<html><body>"
|
|
41
|
+
puts markup.convert(input_string, h)
|
|
42
|
+
puts "</body></html>"
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
require 'markup/simple_markup/lines.rb'
|
|
2
|
+
require 'markup/simple_markup/inline.rb'
|
|
3
|
+
|
|
4
|
+
module SM
|
|
5
|
+
|
|
6
|
+
##
|
|
7
|
+
# A Fragment is a chunk of text, subclassed as a paragraph, a list
|
|
8
|
+
# entry, or verbatim text
|
|
9
|
+
|
|
10
|
+
class Fragment
|
|
11
|
+
attr_reader :level, :param, :txt
|
|
12
|
+
attr_accessor :type
|
|
13
|
+
|
|
14
|
+
def initialize(level, param, type, txt)
|
|
15
|
+
@level = level
|
|
16
|
+
@param = param
|
|
17
|
+
@type = type
|
|
18
|
+
@txt = ""
|
|
19
|
+
add_text(txt) if txt
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add_text(txt)
|
|
23
|
+
@txt << " " if @txt.length > 0
|
|
24
|
+
@txt << txt.tr_s("\n ", " ").strip
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_s
|
|
28
|
+
"L#@level: #{self.class.name.split('::')[-1]}\n#@txt"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
######
|
|
32
|
+
# This is a simple factory system that lets us associate fragement
|
|
33
|
+
# types (a string) with a subclass of fragment
|
|
34
|
+
|
|
35
|
+
TYPE_MAP = {}
|
|
36
|
+
|
|
37
|
+
def Fragment.type_name(name)
|
|
38
|
+
TYPE_MAP[name] = self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def Fragment.for(line)
|
|
42
|
+
klass = TYPE_MAP[line.type] ||
|
|
43
|
+
raise("Unknown line type: '#{line.type.inspect}:' '#{line.text}'")
|
|
44
|
+
return klass.new(line.level, line.param, line.flag, line.text)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# A paragraph is a fragment which gets wrapped to fit. We remove all
|
|
50
|
+
# newlines when we're created, and have them put back on output
|
|
51
|
+
|
|
52
|
+
class Paragraph < Fragment
|
|
53
|
+
type_name Line::PARAGRAPH
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class BlankLine < Paragraph
|
|
57
|
+
type_name Line::BLANK
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class Heading < Paragraph
|
|
61
|
+
type_name Line::HEADING
|
|
62
|
+
|
|
63
|
+
def head_level
|
|
64
|
+
@param.to_i
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
##
|
|
69
|
+
# A List is a fragment with some kind of label
|
|
70
|
+
#
|
|
71
|
+
|
|
72
|
+
class ListBase < Paragraph
|
|
73
|
+
# List types
|
|
74
|
+
BULLET = :BULLET
|
|
75
|
+
NUMBER = :NUMBER
|
|
76
|
+
LABELED = :LABELED
|
|
77
|
+
NOTE = :NOTE
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class ListItem < ListBase
|
|
81
|
+
type_name Line::LIST
|
|
82
|
+
|
|
83
|
+
# def label
|
|
84
|
+
# am = AttributeManager.new(@param)
|
|
85
|
+
# am.flow
|
|
86
|
+
# end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class ListStart < ListBase
|
|
90
|
+
def initialize(level, param, type)
|
|
91
|
+
super(level, param, type, nil)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class ListEnd < ListBase
|
|
96
|
+
def initialize(level, type)
|
|
97
|
+
super(level, "", type, nil)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
# Verbatim code contains lines that don't get wrapped.
|
|
103
|
+
|
|
104
|
+
class Verbatim < Fragment
|
|
105
|
+
type_name Line::VERBATIM
|
|
106
|
+
|
|
107
|
+
def add_text(txt)
|
|
108
|
+
@txt << txt.chomp << "\n"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
##
|
|
114
|
+
# A horizontal rule
|
|
115
|
+
class Rule < Fragment
|
|
116
|
+
type_name Line::RULE
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# Collect groups of lines together. Each group
|
|
121
|
+
# will end up containing a flow of text
|
|
122
|
+
|
|
123
|
+
class LineCollection
|
|
124
|
+
|
|
125
|
+
def initialize
|
|
126
|
+
@fragments = []
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def add(fragment)
|
|
130
|
+
@fragments << fragment
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def each(&b)
|
|
134
|
+
@fragments.each(&b)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# For testing
|
|
138
|
+
def to_a
|
|
139
|
+
@fragments.map {|fragment| fragment.to_s}
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Factory for different fragment types
|
|
143
|
+
def fragment_for(*args)
|
|
144
|
+
Fragment.for(*args)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# tidy up at the end
|
|
148
|
+
def normalize
|
|
149
|
+
change_verbatim_blank_lines
|
|
150
|
+
add_list_start_and_ends
|
|
151
|
+
add_list_breaks
|
|
152
|
+
tidy_blank_lines
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def to_s
|
|
156
|
+
@fragments.join("\n----\n")
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def accept(am, visitor)
|
|
160
|
+
|
|
161
|
+
visitor.start_accepting
|
|
162
|
+
|
|
163
|
+
@fragments.each do |fragment|
|
|
164
|
+
case fragment
|
|
165
|
+
when Verbatim
|
|
166
|
+
visitor.accept_verbatim(am, fragment)
|
|
167
|
+
when Rule
|
|
168
|
+
visitor.accept_rule(am, fragment)
|
|
169
|
+
when ListStart
|
|
170
|
+
visitor.accept_list_start(am, fragment)
|
|
171
|
+
when ListEnd
|
|
172
|
+
visitor.accept_list_end(am, fragment)
|
|
173
|
+
when ListItem
|
|
174
|
+
visitor.accept_list_item(am, fragment)
|
|
175
|
+
when BlankLine
|
|
176
|
+
visitor.accept_blank_line(am, fragment)
|
|
177
|
+
when Heading
|
|
178
|
+
visitor.accept_heading(am, fragment)
|
|
179
|
+
when Paragraph
|
|
180
|
+
visitor.accept_paragraph(am, fragment)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
visitor.end_accepting
|
|
185
|
+
end
|
|
186
|
+
#######
|
|
187
|
+
private
|
|
188
|
+
#######
|
|
189
|
+
|
|
190
|
+
# If you have:
|
|
191
|
+
#
|
|
192
|
+
# normal paragraph text.
|
|
193
|
+
#
|
|
194
|
+
# this is code
|
|
195
|
+
#
|
|
196
|
+
# and more code
|
|
197
|
+
#
|
|
198
|
+
# You'll end up with the fragments Paragraph, BlankLine,
|
|
199
|
+
# Verbatim, BlankLine, Verbatim, BlankLine, etc
|
|
200
|
+
#
|
|
201
|
+
# The BlankLine in the middle of the verbatim chunk needs to
|
|
202
|
+
# be changed to a real verbatim newline, and the two
|
|
203
|
+
# verbatim blocks merged
|
|
204
|
+
#
|
|
205
|
+
#
|
|
206
|
+
def change_verbatim_blank_lines
|
|
207
|
+
last_was_verbatim = false
|
|
208
|
+
@fragments.size.times do |i|
|
|
209
|
+
if BlankLine === @fragments[i]
|
|
210
|
+
if last_was_verbatim and
|
|
211
|
+
i < @fragments.size - 1 and
|
|
212
|
+
Verbatim === @fragments[i+1]
|
|
213
|
+
merge_fragments(i-1)
|
|
214
|
+
@fragments[i] = @fragments[i+1] = nil
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
last_was_verbatim = Verbatim === @fragments[i]
|
|
218
|
+
end
|
|
219
|
+
@fragments.compact!
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Merge the sequence Verbatim/Blank/Verbatim into
|
|
223
|
+
# a single Verbatim fragment
|
|
224
|
+
def merge_fragments(start)
|
|
225
|
+
target = @fragments[start]
|
|
226
|
+
target.add_text("\n")
|
|
227
|
+
target.add_text(@fragments[start+2].txt)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# List nesting is implicit given the level of
|
|
231
|
+
# Make it explicit, just to make life a tad
|
|
232
|
+
# easier for the output processors
|
|
233
|
+
|
|
234
|
+
def add_list_start_and_ends
|
|
235
|
+
level = 0
|
|
236
|
+
res = []
|
|
237
|
+
type_stack = []
|
|
238
|
+
|
|
239
|
+
@fragments.each do |fragment|
|
|
240
|
+
# $stderr.puts "#{level} : #{fragment.class.name} : #{fragment.level}"
|
|
241
|
+
new_level = fragment.level
|
|
242
|
+
while (level < new_level)
|
|
243
|
+
level += 1
|
|
244
|
+
type = fragment.type
|
|
245
|
+
res << ListStart.new(level, fragment.param, type) if type
|
|
246
|
+
type_stack.push type
|
|
247
|
+
# $stderr.puts "Start: #{level}"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
while level > new_level
|
|
251
|
+
type = type_stack.pop
|
|
252
|
+
res << ListEnd.new(level, type) if type
|
|
253
|
+
level -= 1
|
|
254
|
+
# $stderr.puts "End: #{level}, #{type}"
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
res << fragment
|
|
258
|
+
level = fragment.level
|
|
259
|
+
end
|
|
260
|
+
level.downto(1) do |i|
|
|
261
|
+
type = type_stack.pop
|
|
262
|
+
res << ListEnd.new(i, type) if type
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
@fragments = res
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# now insert start/ends between list entries at the
|
|
269
|
+
# same level that have different element types
|
|
270
|
+
|
|
271
|
+
def add_list_breaks
|
|
272
|
+
res = @fragments
|
|
273
|
+
|
|
274
|
+
@fragments = []
|
|
275
|
+
list_stack = []
|
|
276
|
+
|
|
277
|
+
res.each do |fragment|
|
|
278
|
+
case fragment
|
|
279
|
+
when ListStart
|
|
280
|
+
list_stack.push fragment
|
|
281
|
+
when ListEnd
|
|
282
|
+
start = list_stack.pop
|
|
283
|
+
fragment.type = start.type
|
|
284
|
+
when ListItem
|
|
285
|
+
l = list_stack.last
|
|
286
|
+
if fragment.type != l.type
|
|
287
|
+
@fragments << ListEnd.new(l.level, l.type)
|
|
288
|
+
start = ListStart.new(l.level, fragment.param, fragment.type)
|
|
289
|
+
@fragments << start
|
|
290
|
+
list_stack.pop
|
|
291
|
+
list_stack.push start
|
|
292
|
+
end
|
|
293
|
+
else
|
|
294
|
+
;
|
|
295
|
+
end
|
|
296
|
+
@fragments << fragment
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# Finally tidy up the blank lines:
|
|
301
|
+
# * change Blank/ListEnd into ListEnd/Blank
|
|
302
|
+
# * remove blank lines at the front
|
|
303
|
+
|
|
304
|
+
def tidy_blank_lines
|
|
305
|
+
(@fragments.size - 1).times do |i|
|
|
306
|
+
if @fragments[i].kind_of?(BlankLine) and
|
|
307
|
+
@fragments[i+1].kind_of?(ListEnd)
|
|
308
|
+
@fragments[i], @fragments[i+1] = @fragments[i+1], @fragments[i]
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# remove leading blanks
|
|
313
|
+
@fragments.each_with_index do |f, i|
|
|
314
|
+
break unless f.kind_of? BlankLine
|
|
315
|
+
@fragments[i] = nil
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
@fragments.compact!
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
end
|