bitclust-core 1.2.1 → 1.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/data/bitclust/catalog/ja_JP.UTF-8 +4 -0
  3. data/data/bitclust/template.lillia/layout +1 -1
  4. data/data/bitclust/template.offline/class +127 -34
  5. data/data/bitclust/template.offline/class-index +33 -6
  6. data/data/bitclust/template.offline/doc +41 -8
  7. data/data/bitclust/template.offline/function +42 -9
  8. data/data/bitclust/template.offline/function-index +33 -7
  9. data/data/bitclust/template.offline/layout +21 -14
  10. data/data/bitclust/template.offline/library +48 -12
  11. data/data/bitclust/template.offline/library-index +33 -6
  12. data/data/bitclust/template.offline/method +56 -11
  13. data/lib/bitclust/classentry.rb +13 -2
  14. data/lib/bitclust/compat.rb +8 -0
  15. data/lib/bitclust/completion.rb +1 -0
  16. data/lib/bitclust/docentry.rb +4 -2
  17. data/lib/bitclust/entry.rb +3 -0
  18. data/lib/bitclust/functionentry.rb +8 -7
  19. data/lib/bitclust/functionreferenceparser.rb +2 -0
  20. data/lib/bitclust/libraryentry.rb +4 -1
  21. data/lib/bitclust/lineinput.rb +6 -2
  22. data/lib/bitclust/methoddatabase.rb +3 -0
  23. data/lib/bitclust/methodentry.rb +10 -8
  24. data/lib/bitclust/methodid.rb +1 -0
  25. data/lib/bitclust/nameutils.rb +15 -11
  26. data/lib/bitclust/preprocessor.rb +26 -21
  27. data/lib/bitclust/rdcompiler.rb +29 -19
  28. data/lib/bitclust/requesthandler.rb +3 -3
  29. data/lib/bitclust/ridatabase.rb +2 -1
  30. data/lib/bitclust/rrdparser.rb +19 -20
  31. data/lib/bitclust/screen.rb +39 -4
  32. data/lib/bitclust/silent_progress_bar.rb +8 -4
  33. data/lib/bitclust/simplesearcher.rb +1 -1
  34. data/lib/bitclust/subcommand.rb +9 -0
  35. data/lib/bitclust/subcommands/chm_command.rb +3 -3
  36. data/lib/bitclust/subcommands/methods_command.rb +1 -1
  37. data/lib/bitclust/subcommands/server_command.rb +6 -1
  38. data/lib/bitclust/subcommands/setup_command.rb +2 -2
  39. data/lib/bitclust/subcommands/statichtml_command.rb +44 -21
  40. data/lib/bitclust/syntax_highlighter.rb +5 -3
  41. data/lib/bitclust/version.rb +1 -1
  42. data/test/test_bitclust.rb +1 -1
  43. data/test/test_entry.rb +14 -1
  44. data/test/test_functionreferenceparser.rb +4 -4
  45. data/test/test_preprocessor.rb +21 -0
  46. data/test/test_rdcompiler.rb +240 -0
  47. data/test/test_rrdparser.rb +16 -0
  48. data/test/test_syntax_highlighter.rb +22 -4
  49. data/theme/default/rurema.png +0 -0
  50. data/theme/default/rurema.svg +31 -0
  51. data/theme/default/script.js +34 -0
  52. data/theme/default/style.css +112 -8
  53. metadata +32 -19
@@ -71,6 +71,7 @@ class Ent
71
71
  attr_reader :entry
72
72
 
73
73
  def ==(other)
74
+ return false if self.class != other.class
74
75
  @name == other.name
75
76
  end
76
77
 
@@ -121,7 +122,7 @@ class RiMethodEntry < Ent
121
122
  end
122
123
 
123
124
  def fullname
124
- c, t, m = @entry.fullname.split(/([\.\#])/, 2)
125
+ c, t = @entry.fullname.split(/([\.\#])/, 2)
125
126
  "#{c}#{t}#{@name}"
126
127
  end
127
128
  end
@@ -10,11 +10,11 @@
10
10
  require 'bitclust/compat'
11
11
  require 'bitclust/preprocessor'
12
12
  require 'bitclust/methodid'
13
+ require 'bitclust/methoddatabase'
13
14
  require 'bitclust/lineinput'
14
15
  require 'bitclust/parseutils'
15
16
  require 'bitclust/nameutils'
16
17
  require 'bitclust/exception'
17
- require 'bitclust/methoddatabase'
18
18
 
19
19
  module BitClust
20
20
 
@@ -70,7 +70,7 @@ module BitClust
70
70
 
71
71
  def parse_file(path, libname, params = {})
72
72
  fopen(path, 'r:UTF-8') {|f|
73
- return parse(f, libname, params)
73
+ return parse(f, libname, params).tap { |lib| lib.source_location = Location.new(path, 1) }
74
74
  }
75
75
  end
76
76
 
@@ -114,18 +114,14 @@ module BitClust
114
114
  type, name, superclass = *parse_level1_header(line)
115
115
  case type
116
116
  when 'class'
117
- @context.define_class name, (superclass || 'Object')
117
+ @context.define_class name, (superclass || 'Object'), location: line.location
118
118
  read_class_body f
119
119
  when 'module'
120
120
  parse_error "superclass given for module", line if superclass
121
- @context.define_module name
121
+ @context.define_module name, location: line.location
122
122
  read_class_body f
123
123
  when 'object'
124
- if superclass
125
- # FIXME
126
- tty_warn "#{line.location}: singleton object class not implemented yet"
127
- end
128
- @context.define_object name
124
+ @context.define_object name, superclass, location: line.location
129
125
  read_object_body f
130
126
  when 'reopen'
131
127
  @context.reopen_class name
@@ -353,29 +349,31 @@ module BitClust
353
349
  @library.sublibrary @db.get_library(libname)
354
350
  end
355
351
 
356
- def define_class(name, supername)
352
+ def define_class(name, supername, location: nil)
357
353
  if @db.properties['version'] >= "1.9.0"
358
354
  top = 'BasicObject'
359
355
  else
360
356
  top = 'Object'
361
357
  end
362
358
  superclass = (name == top ? nil : @db.get_class(supername))
363
- register_class :class, name, superclass
359
+ register_class :class, name, superclass, location: location
364
360
  end
365
361
 
366
- def define_module(name)
367
- register_class :module, name, nil
362
+ def define_module(name, location: nil)
363
+ register_class :module, name, nil, location: location
368
364
  end
369
365
 
370
- def define_object(name)
371
- register_class :object, name, nil
366
+ def define_object(name, singleton_object_class, location: nil)
367
+ singleton_object_class = @db.get_class(singleton_object_class) if singleton_object_class
368
+ register_class :object, name, singleton_object_class, location: location
372
369
  end
373
370
 
374
- def register_class(type, name, superclass)
371
+ def register_class(type, name, superclass, location: nil)
375
372
  @klass = @db.open_class(name) {|c|
376
373
  c.type = type
377
374
  c.superclass = superclass
378
375
  c.library = @library
376
+ c.source_location = location
379
377
  @library.add_class c
380
378
  }
381
379
  @kind = :defined
@@ -452,10 +450,11 @@ module BitClust
452
450
  def define_method(chunk)
453
451
  id = method_id(chunk)
454
452
  @db.open_method(id) {|m|
455
- m.names = chunk.names.sort
456
- m.kind = @kind
457
- m.visibility = @visibility || :public
458
- m.source = chunk.source
453
+ m.names = chunk.names.sort
454
+ m.kind = chunk.source.match?(/^@undef$/) ? :undefined : @kind
455
+ m.visibility = @visibility || :public
456
+ m.source = chunk.source
457
+ m.source_location = chunk.source.location
459
458
  case @kind
460
459
  when :added, :redefined
461
460
  @library.add_method m
@@ -13,7 +13,9 @@ require 'bitclust/htmlutils'
13
13
  require 'bitclust/nameutils'
14
14
  require 'bitclust/messagecatalog'
15
15
  require 'erb'
16
+ require 'json'
16
17
  require 'stringio'
18
+ require 'uri'
17
19
 
18
20
  module BitClust
19
21
 
@@ -185,7 +187,7 @@ module BitClust
185
187
  private
186
188
 
187
189
  def preproc(template)
188
- template.gsub(/^\.include ([\w\-]+)/) { load($1.untaint) }.untaint
190
+ template.gsub(/^\.include ([\w\-]+)/) { load($1) }
189
191
  end
190
192
  end
191
193
 
@@ -366,6 +368,10 @@ module BitClust
366
368
  @urlmapper.canonical_url(current_url)
367
369
  end
368
370
 
371
+ def edit_url(location)
372
+ @urlmapper.edit_url(location)
373
+ end
374
+
369
375
  def opensearchdescription_url
370
376
  @urlmapper.opensearchdescription_url
371
377
  end
@@ -394,8 +400,11 @@ module BitClust
394
400
  @hlevel -= 1
395
401
  end
396
402
 
397
- def headline(str)
398
- "<h#{@hlevel}>#{escape_html(str)}</h#{@hlevel}>"
403
+ def headline(str, edit_url: nil)
404
+ edit_link = edit_url ? <<~HTML : ''
405
+ <span class="permalink">[<a href="#{edit_url}">edit</a>]</span>
406
+ HTML
407
+ "<h#{@hlevel}>#{escape_html(str)}</h#{@hlevel}>" + edit_link
399
408
  end
400
409
 
401
410
  def headline_noescape(str)
@@ -415,8 +424,12 @@ module BitClust
415
424
  end
416
425
  end
417
426
 
427
+ def manual_home_name
428
+ _('Ruby %s Reference Manual', ruby_version())
429
+ end
430
+
418
431
  def manual_home_link
419
- document_link('index', _('Ruby %s Reference Manual', ruby_version()))
432
+ document_link('index', manual_home_name)
420
433
  end
421
434
 
422
435
  def friendly_library_link(id)
@@ -452,6 +465,28 @@ module BitClust
452
465
  yield sigs, body
453
466
  end
454
467
  end
468
+
469
+ def breadcrumb_json_ld(items)
470
+ {
471
+ '@context': 'http://schema.org',
472
+ '@type': 'BreadcrumbList',
473
+ 'itemListElement' => items.map.with_index(1) do |item, index|
474
+ {
475
+ '@type' => 'ListItem',
476
+ 'item' => item[:url],
477
+ 'name' => item[:name],
478
+ 'position' => index
479
+ }
480
+ end
481
+ }.to_json
482
+ end
483
+
484
+ def absolute_url_to(path)
485
+ ::URI.join(
486
+ canonical_url,
487
+ path
488
+ )
489
+ end
455
490
  end
456
491
 
457
492
  class IndexScreen < TemplateScreen
@@ -3,13 +3,17 @@ module BitClust
3
3
  # Null-object version of ProgressBar.
4
4
  class SilentProgressBar
5
5
 
6
- attr_reader :title
6
+ attr_accessor :title
7
7
 
8
- def initialize(title, total, out = $stderr)
9
- @title, @total, @out = title, total, out
8
+ def self.create(output: $stderr, title:, total:)
9
+ self.new(output: output, title: title, total: total)
10
10
  end
11
11
 
12
- def inc(step = 1)
12
+ def initialize(output:, title:, total:)
13
+ @title, @total, @output = title, total, output
14
+ end
15
+
16
+ def increment
13
17
  end
14
18
 
15
19
  def finish
@@ -13,7 +13,7 @@ module BitClust
13
13
  pat = to_pattern(pat)
14
14
  return [] if pat.empty? or /\A\s+\z/ =~ pat
15
15
  cname, type, mname = parse_method_spec_pattern(pat)
16
- ret = cs = ms = []
16
+ cs = ms = []
17
17
  if cname and not cname.empty?
18
18
  if mname
19
19
  ms = find_class_method(db, cname, type, mname)
@@ -52,6 +52,15 @@ module BitClust
52
52
  def srcdir_root
53
53
  Pathname.new(__FILE__).realpath.dirname.parent.parent
54
54
  end
55
+
56
+ def align_progress_bar_title(title)
57
+ size = title.size
58
+ if size > 14
59
+ title[0..13]
60
+ else
61
+ title + ' ' * (14 - size)
62
+ end
63
+ end
55
64
  end
56
65
  end
57
66
 
@@ -176,7 +176,7 @@ EOS
176
176
  end
177
177
 
178
178
  entries = db.docs + db.libraries.sort + db.classes.sort + methods.values.sort
179
- pb = ProgressBar.new('entry', entries.size)
179
+ pb = ProgressBar.create(title: 'entry', total: entries.size)
180
180
  entries.each do |c|
181
181
  filename = create_html_file(c, manager, @outputdir, db)
182
182
  @html_files << filename
@@ -206,8 +206,8 @@ EOS
206
206
  Sitemap::Content.new("#{e.klass.name}#{e.typemark}#{name} (#{e.library.name})", filename)
207
207
  end
208
208
  end
209
- pb.title.replace(e.name)
210
- pb.inc
209
+ pb.title = align_progress_bar_title(e.name)
210
+ pb.increment
211
211
  end
212
212
  pb.finish
213
213
  end
@@ -102,7 +102,7 @@ module BitClust
102
102
  ORDER = { '.' => 1, '#' => 2, '::' => 3 }
103
103
 
104
104
  def m_order(m)
105
- m, t, c = *m.reverse.split(/(\#|\.|::)/, 2)
105
+ m, t = *m.reverse.split(/(\#|\.|::)/, 2)
106
106
  [ORDER[t] || 0, m.reverse]
107
107
  end
108
108
 
@@ -27,7 +27,12 @@ module BitClust
27
27
  @srcdir = @datadir = @themedir = @theme = @templatedir = nil
28
28
  @encoding = 'utf-8' # encoding of view
29
29
  if Object.const_defined?(:Encoding)
30
- Encoding.default_external = @encoding
30
+ begin
31
+ verbose, $VERBOSE = $VERBOSE, false
32
+ Encoding.default_external = @encoding
33
+ ensure
34
+ $VERBOSE = verbose
35
+ end
31
36
  end
32
37
 
33
38
  @debugp = false
@@ -19,13 +19,13 @@ module BitClust
19
19
  @prepare = nil
20
20
  @cleanup = nil
21
21
  @purge = nil
22
- @versions = ["2.1.0", "2.2.0", "2.3.0", "2.4.0"]
22
+ @versions = ["2.4.0", "2.5.0", "2.6.0"]
23
23
  @update = true
24
24
  @parser.banner = "Usage: #{File.basename($0, '.*')} setup [options]"
25
25
  @parser.on('--prepare', 'Prepare config file and checkout repository. Do not create database.') {
26
26
  @prepare = true
27
27
  }
28
- @parser.on('--cleanup', 'Cleanup datebase before create database.') {
28
+ @parser.on('--cleanup', 'Cleanup database before create database.') {
29
29
  @cleanup = true
30
30
  }
31
31
  @parser.on('--purge', 'Purge all downloaded and generated files and exit.') {
@@ -28,6 +28,7 @@ module BitClust
28
28
  @suffix = h[:suffix]
29
29
  @fs_casesensitive = h[:fs_casesensitive]
30
30
  @canonical_base_url = h[:canonical_base_url]
31
+ @edit_base_url = h[:edit_base_url]
31
32
  end
32
33
 
33
34
  def library_url(name)
@@ -67,6 +68,10 @@ module BitClust
67
68
  @bitclust_html_base + "/" + filename
68
69
  end
69
70
 
71
+ def custom_js_url(filename)
72
+ @bitclust_html_base + "/" + filename
73
+ end
74
+
70
75
  def favicon_url
71
76
  @bitclust_html_base + "/" + @favicon_url
72
77
  end
@@ -83,6 +88,10 @@ module BitClust
83
88
  (@canonical_base_url + "/#{current_url}").sub(@bitclust_html_base, "").sub(/([^:])\/\/+/, "\\1/")
84
89
  end
85
90
 
91
+ def edit_url(location)
92
+ "#{@edit_base_url}/#{location.file}#L#{location.line}".sub(/([^:])\/\/+/, "\\1/")
93
+ end
94
+
86
95
  def encodename_package(str)
87
96
  if @fs_casesensitive
88
97
  encodename_url(str)
@@ -94,7 +103,12 @@ module BitClust
94
103
 
95
104
  def initialize
96
105
  if Object.const_defined?(:Encoding)
97
- Encoding.default_external = 'utf-8'
106
+ begin
107
+ verbose, $VERBOSE = $VERBOSE, false
108
+ Encoding.default_external = 'utf-8'
109
+ ensure
110
+ $VERBOSE = verbose
111
+ end
98
112
  end
99
113
  super
100
114
  @verbose = true
@@ -104,6 +118,7 @@ module BitClust
104
118
  @suffix = ".html"
105
119
  @gtm_tracking_id = nil
106
120
  @meta_robots_content = ["noindex"]
121
+ @stop_on_syntax_error = true
107
122
  @parser.banner = "Usage: #{File.basename($0, '.*')} statichtml [options]"
108
123
  @parser.on('-o', '--outputdir=PATH', 'Output directory') do |path|
109
124
  begin
@@ -131,12 +146,18 @@ module BitClust
131
146
  @parser.on('--canonical-base-url=URL', 'Canonical base URL') do |url|
132
147
  @canonical_base_url = url
133
148
  end
149
+ @parser.on('--edit-base-url=URL', 'Edit base URL') do |url|
150
+ @edit_base_url = url
151
+ end
134
152
  @parser.on('--tracking-id=ID', 'Google Tag Manager Tracking ID') do |id|
135
153
  @gtm_tracking_id = id
136
154
  end
137
155
  @parser.on('--meta-robots-content=VALUE1,VALUE2,...', Array, 'HTML <meta> element: <meta name="robots" content="VALUE1,VALUE2..."') do |values|
138
156
  @meta_robots_content = values
139
157
  end
158
+ @parser.on('--no-stop-on-syntax-error', 'Do not stop on syntax error') do |boolean|
159
+ @stop_on_syntax_error = boolean
160
+ end
140
161
  @parser.on('--[no-]quiet', 'Be quiet') do |quiet|
141
162
  @verbose = !quiet
142
163
  end
@@ -165,7 +186,6 @@ module BitClust
165
186
  end
166
187
 
167
188
  fdb.transaction do
168
- functions = {}
169
189
  create_html_entries("capi", fdb.functions, manager, fdb)
170
190
  end
171
191
 
@@ -181,19 +201,21 @@ module BitClust
181
201
  :verbose => @verbose)
182
202
  create_index_html(@outputdir)
183
203
  FileUtils.cp(@manager_config[:themedir] + @manager_config[:css_url],
184
- @outputdir.to_s, {:verbose => @verbose, :preserve => true})
204
+ @outputdir.to_s, :verbose => @verbose, :preserve => true)
185
205
  FileUtils.cp(@manager_config[:themedir] + "syntax-highlight.css",
186
- @outputdir.to_s, {:verbose => @verbose, :preserve => true})
206
+ @outputdir.to_s, :verbose => @verbose, :preserve => true)
207
+ FileUtils.cp(@manager_config[:themedir] + "script.js",
208
+ @outputdir.to_s, :verbose => @verbose, :preserve => true)
187
209
  FileUtils.cp(@manager_config[:themedir] + @manager_config[:favicon_url],
188
- @outputdir.to_s, {:verbose => @verbose, :preserve => true})
210
+ @outputdir.to_s, :verbose => @verbose, :preserve => true)
189
211
  Dir.mktmpdir do |tmpdir|
190
212
  FileUtils.cp_r(@manager_config[:themedir] + 'images', tmpdir,
191
- {:verbose => @verbose, :preserve => true})
213
+ :verbose => @verbose, :preserve => true)
192
214
  Dir.glob(File.join(tmpdir, 'images', '/**/.svn')).each do |d|
193
- FileUtils.rm_r(d, {:verbose => @verbose})
215
+ FileUtils.rm_r(d, :verbose => @verbose)
194
216
  end
195
217
  FileUtils.cp_r(File.join(tmpdir, 'images'), @outputdir.to_s,
196
- {:verbose => @verbose, :preserve => true})
218
+ :verbose => @verbose, :preserve => true)
197
219
  end
198
220
  end
199
221
 
@@ -211,42 +233,46 @@ module BitClust
211
233
  :tochm_mode => true,
212
234
  :fs_casesensitive => @fs_casesensitive,
213
235
  :canonical_base_url => @canonical_base_url,
236
+ :edit_base_url => @edit_base_url,
214
237
  :gtm_tracking_id => @gtm_tracking_id,
215
238
  :meta_robots_content => @meta_robots_content,
239
+ :stop_on_syntax_error => @stop_on_syntax_error,
216
240
  }
217
241
  @manager_config[:urlmapper] = URLMapperEx.new(@manager_config)
218
242
  @urlmapper = @manager_config[:urlmapper]
219
243
  end
220
244
 
221
245
  def create_html_entries(title, entries, manager, db)
246
+ title = align_progress_bar_title(title)
222
247
  original_title = title.dup
223
248
  if @verbose
224
- progressbar = ProgressBar.new(title, entries.size)
249
+ progressbar = ProgressBar.create(title: title, total: entries.size)
225
250
  else
226
- progressbar = SilentProgressBar.new(title, entries.size)
251
+ progressbar = SilentProgressBar.create(title: title, total: entries.size)
227
252
  end
228
253
  entries.each do |entry|
229
254
  create_html_file(entry, manager, @outputdir, db)
230
- progressbar.title.replace([entry].flatten.first.name)
231
- progressbar.inc
255
+ progressbar.title = align_progress_bar_title([entry].flatten.first.name)
256
+ progressbar.increment
232
257
  end
233
- progressbar.title.replace(original_title)
258
+ progressbar.title = original_title
234
259
  progressbar.finish
235
260
  end
236
261
 
237
262
  def create_html_methods(title, methods, manager, db)
263
+ title = align_progress_bar_title(title)
238
264
  original_title = title.dup
239
265
  if @verbose
240
- progressbar = ProgressBar.new(title, methods.size)
266
+ progressbar = ProgressBar.create(title: title, total: methods.size)
241
267
  else
242
- progressbar = SilentProgressBar.new(title, methods.size)
268
+ progressbar = SilentProgressBar.create(title: title, total: methods.size)
243
269
  end
244
270
  methods.each do |method_name, method_entries|
245
271
  create_html_method_file(method_name, method_entries, manager, @outputdir, db)
246
- progressbar.title.replace(method_name)
247
- progressbar.inc
272
+ progressbar.title = align_progress_bar_title(method_name)
273
+ progressbar.increment
248
274
  end
249
- progressbar.title.replace(original_title)
275
+ progressbar.title = original_title
250
276
  progressbar.finish
251
277
  end
252
278
 
@@ -268,7 +294,6 @@ HERE
268
294
  @urlmapper.bitclust_html_base = '..'
269
295
  path = outputdir + e.type_id.to_s + html_filename(encodename_package(e.name), @suffix)
270
296
  create_html_file_p(entry, manager, path, db)
271
- path.relative_path_from(outputdir).to_s
272
297
  when :function
273
298
  create_html_function_file(entry, manager, outputdir, db)
274
299
  else
@@ -285,7 +310,6 @@ HERE
285
310
  path = outputdir + e.type_id.to_s + encodename_package(e.klass.name) +
286
311
  e.typechar + html_filename(encodename_package(name), @suffix)
287
312
  create_html_file_p(entries, manager, path, db)
288
- path.relative_path_from(outputdir).to_s
289
313
  end
290
314
 
291
315
  def create_html_function_file(entry, manager, outputdir, db)
@@ -293,7 +317,6 @@ HERE
293
317
  @urlmapper.bitclust_html_base = '..'
294
318
  path = outputdir + entry.type_id.to_s + html_filename(entry.name, @suffix)
295
319
  create_html_file_p(entry, manager, path, db)
296
- path.relative_path_from(outputdir).to_s
297
320
  end
298
321
 
299
322
  def create_html_file_p(entry, manager, path, db)