docurium 0.4.1 → 0.7.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 +5 -5
- data/.github/workflows/main.yml +42 -0
- data/Gemfile +4 -4
- data/README.md +0 -15
- data/bin/cm +19 -2
- data/docurium.gemspec +7 -6
- data/lib/docurium/cli.rb +6 -1
- data/lib/docurium/debug.rb +41 -0
- data/lib/docurium/docparser.rb +96 -27
- data/lib/docurium/layout.rb +0 -3
- data/lib/docurium/version.rb +1 -1
- data/lib/docurium.rb +276 -92
- data/lib/libdetect.rb +1 -1
- data/site/css/style.css +17 -11
- data/site/index.html +133 -122
- data/site/js/backbone.js +1 -1
- data/site/js/docurium.js +178 -162
- data/site/js/underscore.js +5 -5
- data/test/docurium_test.rb +235 -0
- data/test/fixtures/git2/cherrypick.h +19 -0
- data/test/fixtures/git2/common.h +1 -0
- data/test/fixtures/git2/repository.h +39 -0
- data/test/fixtures/git2/types.h +2 -0
- data/test/gen_test.rb +2 -2
- data/test/parser_test.rb +18 -14
- metadata +38 -23
- data/.travis.yml +0 -13
- data/test/repo_test.rb +0 -136
data/lib/docurium.rb
CHANGED
@@ -4,12 +4,14 @@ require 'version_sorter'
|
|
4
4
|
require 'rocco'
|
5
5
|
require 'docurium/version'
|
6
6
|
require 'docurium/layout'
|
7
|
+
require 'docurium/debug'
|
7
8
|
require 'libdetect'
|
8
9
|
require 'docurium/docparser'
|
9
10
|
require 'pp'
|
10
11
|
require 'rugged'
|
11
12
|
require 'redcarpet'
|
12
13
|
require 'redcarpet/compat'
|
14
|
+
require 'parallel'
|
13
15
|
require 'thread'
|
14
16
|
|
15
17
|
# Markdown expects the old redcarpet compat API, so let's tell it what
|
@@ -17,13 +19,15 @@ require 'thread'
|
|
17
19
|
Rocco::Markdown = RedcarpetCompat
|
18
20
|
|
19
21
|
class Docurium
|
20
|
-
attr_accessor :branch, :output_dir, :data
|
22
|
+
attr_accessor :branch, :output_dir, :data, :head_data
|
21
23
|
|
22
|
-
def initialize(config_file, repo = nil)
|
24
|
+
def initialize(config_file, cli_options = {}, repo = nil)
|
23
25
|
raise "You need to specify a config file" if !config_file
|
24
26
|
raise "You need to specify a valid config file" if !valid_config(config_file)
|
25
27
|
@sigs = {}
|
26
|
-
@
|
28
|
+
@head_data = nil
|
29
|
+
@repo = repo || Rugged::Repository.discover(config_file)
|
30
|
+
@cli_options = cli_options
|
27
31
|
end
|
28
32
|
|
29
33
|
def init_data(version = 'HEAD')
|
@@ -115,8 +119,31 @@ class Docurium
|
|
115
119
|
def generate_doc_for(version)
|
116
120
|
index = Rugged::Index.new
|
117
121
|
read_subtree(index, version, option_version(version, 'input', ''))
|
122
|
+
|
118
123
|
data = parse_headers(index, version)
|
119
|
-
data
|
124
|
+
examples = format_examples!(data, version)
|
125
|
+
[data, examples]
|
126
|
+
end
|
127
|
+
|
128
|
+
def process_project(versions)
|
129
|
+
nversions = versions.count
|
130
|
+
Parallel.each_with_index(versions, finish: -> (version, index, result) do
|
131
|
+
data, examples = result
|
132
|
+
# There's still some work we need to do serially
|
133
|
+
tally_sigs!(version, data)
|
134
|
+
force_utf8(data)
|
135
|
+
|
136
|
+
puts "Adding documentation for #{version} [#{index}/#{nversions}]"
|
137
|
+
|
138
|
+
# Store it so we can show it at the end
|
139
|
+
@head_data = data if version == 'HEAD'
|
140
|
+
|
141
|
+
yield index, version, result if block_given?
|
142
|
+
|
143
|
+
end) do |version, index|
|
144
|
+
puts "Generating documentation for #{version} [#{index}/#{nversions}]"
|
145
|
+
generate_doc_for(version)
|
146
|
+
end
|
120
147
|
end
|
121
148
|
|
122
149
|
def generate_docs
|
@@ -125,68 +152,46 @@ class Docurium
|
|
125
152
|
@tf = File.expand_path(File.join(File.dirname(__FILE__), 'docurium', 'layout.mustache'))
|
126
153
|
versions = get_versions
|
127
154
|
versions << 'HEAD'
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
read, write = IO.pipe
|
135
|
-
pid = Process.fork do
|
136
|
-
read.close
|
137
|
-
|
138
|
-
data = generate_doc_for(version)
|
139
|
-
examples = format_examples!(data, version)
|
140
|
-
|
141
|
-
Marshal.dump([version, data, examples], write)
|
142
|
-
write.close
|
155
|
+
# If the user specified versions, validate them and overwrite
|
156
|
+
if !(vers = (@cli_options[:for] || [])).empty?
|
157
|
+
vers.each do |v|
|
158
|
+
next if versions.include?(v)
|
159
|
+
puts "Unknown version #{v}"
|
160
|
+
exit(false)
|
143
161
|
end
|
144
|
-
|
145
|
-
pipes[pid] = read
|
146
|
-
write.close
|
162
|
+
versions = vers
|
147
163
|
end
|
148
164
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
# This may seem odd, but we need to keep reading from the pipe or
|
153
|
-
# the buffer will fill and they'll block and never exit. Therefore
|
154
|
-
# we can't rely on Process.wait to tell us when the work is
|
155
|
-
# done. Instead read from all the pipes concurrently and send the
|
156
|
-
# ruby objects through the queue.
|
157
|
-
Thread.abort_on_exception = true
|
158
|
-
pipes.each do |pid, read|
|
159
|
-
Thread.new do
|
160
|
-
result = read.read
|
161
|
-
output << Marshal.load(result)
|
162
|
-
end
|
165
|
+
if (@repo.config['user.name'].nil? || @repo.config['user.email'].nil?)
|
166
|
+
puts "ERROR: 'user.name' or 'user.email' is not configured. Docurium will not be able to commit the documentation"
|
167
|
+
exit(false)
|
163
168
|
end
|
164
169
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
# There's still some work we need to do serially
|
169
|
-
tally_sigs!(version, data)
|
170
|
+
process_project(versions) do |i, version, result|
|
171
|
+
data, examples = result
|
170
172
|
sha = @repo.write(data.to_json, :blob)
|
171
173
|
|
172
|
-
print "Generating documentation [#{i}/#{
|
174
|
+
print "Generating documentation [#{i}/#{versions.count}]\r"
|
173
175
|
|
174
|
-
|
175
|
-
|
176
|
-
|
176
|
+
unless dry_run?
|
177
|
+
output_index.add(:path => "#{version}.json", :oid => sha, :mode => 0100644)
|
178
|
+
examples.each do |path, id|
|
179
|
+
output_index.add(:path => path, :oid => id, :mode => 0100644)
|
180
|
+
end
|
177
181
|
end
|
182
|
+
end
|
178
183
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
184
|
+
if head_data
|
185
|
+
puts ''
|
186
|
+
show_warnings(head_data)
|
187
|
+
end
|
183
188
|
|
184
|
-
|
185
|
-
puts ''
|
186
|
-
show_warnings(data)
|
187
|
-
end
|
189
|
+
return if dry_run?
|
188
190
|
|
189
|
-
|
191
|
+
# We tally the signatures in the order they finished, which is
|
192
|
+
# arbitrary due to the concurrency, so we need to sort them once
|
193
|
+
# they've finished.
|
194
|
+
sort_sigs!
|
190
195
|
|
191
196
|
project = {
|
192
197
|
:versions => versions.reverse,
|
@@ -220,34 +225,145 @@ class Docurium
|
|
220
225
|
puts "\tupdated #{br}"
|
221
226
|
end
|
222
227
|
|
223
|
-
def
|
224
|
-
|
228
|
+
def force_utf8(data)
|
229
|
+
# Walk the data to force strings encoding to UTF-8.
|
230
|
+
if data.instance_of? Hash
|
231
|
+
data.each do |key, value|
|
232
|
+
if [:comment, :comments, :description].include?(key)
|
233
|
+
data[key] = value.force_encoding('UTF-8') unless value.nil?
|
234
|
+
else
|
235
|
+
force_utf8(value)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
elsif data.respond_to?(:each)
|
239
|
+
data.each { |x| force_utf8(x) }
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
class Warning
|
244
|
+
class UnmatchedParameter < Warning
|
245
|
+
def initialize(function, opts = {})
|
246
|
+
super :unmatched_param, :function, function, opts
|
247
|
+
end
|
248
|
+
|
249
|
+
def _message; "unmatched param"; end
|
250
|
+
end
|
251
|
+
|
252
|
+
class SignatureChanged < Warning
|
253
|
+
def initialize(function, opts = {})
|
254
|
+
super :signature_changed, :function, function, opts
|
255
|
+
end
|
256
|
+
|
257
|
+
def _message; "signature changed"; end
|
258
|
+
end
|
259
|
+
|
260
|
+
class MissingDocumentation < Warning
|
261
|
+
def initialize(type, identifier, opts = {})
|
262
|
+
super :missing_documentation, type, identifier, opts
|
263
|
+
end
|
264
|
+
|
265
|
+
def _message
|
266
|
+
["%s %s is missing documentation", :type, :identifier]
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
WARNINGS = [
|
271
|
+
:unmatched_param,
|
272
|
+
:signature_changed,
|
273
|
+
:missing_documentation,
|
274
|
+
]
|
275
|
+
|
276
|
+
attr_reader :warning, :type, :identifier, :file, :line, :column
|
277
|
+
|
278
|
+
def initialize(warning, type, identifier, opts = {})
|
279
|
+
raise ArgumentError.new("invalid warning class") unless WARNINGS.include?(warning)
|
280
|
+
@warning = warning
|
281
|
+
@type = type
|
282
|
+
@identifier = identifier
|
283
|
+
if type = opts.delete(:type)
|
284
|
+
@file = type[:file]
|
285
|
+
if input_dir = opts.delete(:input_dir)
|
286
|
+
File.expand_path(File.join(input_dir, @file))
|
287
|
+
end
|
288
|
+
@file ||= "<missing>"
|
289
|
+
@line = type[:line] || 1
|
290
|
+
@column = type[:column] || 1
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def message
|
295
|
+
msg = self._message
|
296
|
+
msg.kind_of?(Array) ? msg.shift % msg.map {|a| self.send(a).to_s } : msg
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
def collect_warnings(data)
|
301
|
+
warnings = []
|
302
|
+
input_dir = File.join(@project_dir, option_version("HEAD", 'input'))
|
225
303
|
|
226
304
|
# check for unmatched paramaters
|
227
|
-
unmatched = []
|
228
305
|
data[:functions].each do |f, fdata|
|
229
|
-
|
230
|
-
end
|
231
|
-
if unmatched.size > 0
|
232
|
-
out ' - unmatched params in'
|
233
|
-
unmatched.sort.each { |p| out ("\t" + p) }
|
306
|
+
warnings << Warning::UnmatchedParameter.new(f, type: fdata, input_dir: input_dir) if fdata[:comments] =~ /@param/
|
234
307
|
end
|
235
308
|
|
236
309
|
# check for changed signatures
|
237
310
|
sigchanges = []
|
238
|
-
@sigs.each do |fun,
|
239
|
-
if
|
240
|
-
|
311
|
+
@sigs.each do |fun, sig_data|
|
312
|
+
warnings << Warning::SignatureChanged.new(fun) if sig_data[:changes]['HEAD']
|
313
|
+
end
|
314
|
+
|
315
|
+
# check for undocumented things
|
316
|
+
types = [:functions, :callbacks, :globals, :types]
|
317
|
+
types.each do |type_id|
|
318
|
+
under_type = type_id.tap {|t| break t.to_s[0..-2].to_sym }
|
319
|
+
data[type_id].each do |ident, type|
|
320
|
+
under_type = type[:type] if type_id == :types
|
321
|
+
|
322
|
+
warnings << Warning::MissingDocumentation.new(under_type, ident, type: type, input_dir: input_dir) if type[:description].empty?
|
323
|
+
|
324
|
+
case type[:type]
|
325
|
+
when :struct
|
326
|
+
if type[:fields]
|
327
|
+
type[:fields].each do |field|
|
328
|
+
warnings << Warning::MissingDocumentation.new(:field, "#{ident}.#{field[:name]}", type: type, input_dir: input_dir) if field[:comments].empty?
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
241
332
|
end
|
242
333
|
end
|
243
|
-
|
244
|
-
|
245
|
-
|
334
|
+
warnings
|
335
|
+
end
|
336
|
+
|
337
|
+
def check_warnings(options)
|
338
|
+
versions = []
|
339
|
+
versions << get_versions.pop
|
340
|
+
versions << 'HEAD'
|
341
|
+
|
342
|
+
process_project(versions)
|
343
|
+
|
344
|
+
collect_warnings(head_data).each do |warning|
|
345
|
+
puts "#{warning.file}:#{warning.line}:#{warning.column}: #{warning.message}"
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def show_warnings(data)
|
350
|
+
out '* checking your api'
|
351
|
+
|
352
|
+
collect_warnings(data).group_by {|w| w.warning }.each do |klass, klass_warnings|
|
353
|
+
klass_warnings.group_by {|w| w.type }.each do |type, type_warnings|
|
354
|
+
out " - " + type_warnings[0].message
|
355
|
+
type_warnings.sort_by {|w| w.identifier }.each do |warning|
|
356
|
+
out "\t" + warning.identifier
|
357
|
+
end
|
358
|
+
end
|
246
359
|
end
|
247
360
|
end
|
248
361
|
|
249
362
|
def get_versions
|
250
|
-
|
363
|
+
releases = @repo.tags
|
364
|
+
.map { |tag| tag.name.gsub(%r(^refs/tags/), '') }
|
365
|
+
.delete_if { |tagname| tagname.match(%r(-rc\d*$)) }
|
366
|
+
VersionSorter.sort(releases)
|
251
367
|
end
|
252
368
|
|
253
369
|
def parse_headers(index, version)
|
@@ -258,10 +374,11 @@ class Docurium
|
|
258
374
|
end
|
259
375
|
|
260
376
|
data = init_data(version)
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
377
|
+
DocParser.with_files(files, :prefix => version) do |parser|
|
378
|
+
headers.each do |header|
|
379
|
+
records = parser.parse_file(header, debug: interesting?(:file, header))
|
380
|
+
update_globals!(data, records)
|
381
|
+
end
|
265
382
|
end
|
266
383
|
|
267
384
|
data[:groups] = group_functions!(data)
|
@@ -288,6 +405,14 @@ class Docurium
|
|
288
405
|
end
|
289
406
|
end
|
290
407
|
|
408
|
+
def sort_sigs!
|
409
|
+
@sigs.keys.each do |fn|
|
410
|
+
VersionSorter.sort!(@sigs[fn][:exists])
|
411
|
+
# Put HEAD at the back
|
412
|
+
@sigs[fn][:exists] << @sigs[fn][:exists].shift
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
291
416
|
def find_subtree(version, path)
|
292
417
|
tree = nil
|
293
418
|
if version == 'HEAD'
|
@@ -326,40 +451,57 @@ class Docurium
|
|
326
451
|
def group_functions!(data)
|
327
452
|
func = {}
|
328
453
|
data[:functions].each_pair do |key, value|
|
454
|
+
debug_set interesting?(:function, key)
|
455
|
+
debug "grouping #{key}: #{value}"
|
329
456
|
if @options['prefix']
|
330
457
|
k = key.gsub(@options['prefix'], '')
|
331
458
|
else
|
332
459
|
k = key
|
333
460
|
end
|
334
461
|
group, rest = k.split('_', 2)
|
335
|
-
|
336
|
-
if
|
337
|
-
group
|
462
|
+
debug "grouped: k: #{k}, group: #{group}, rest: #{rest}"
|
463
|
+
if group.empty?
|
464
|
+
puts "empty group for function #{key}"
|
465
|
+
next
|
338
466
|
end
|
467
|
+
debug "grouped: k: #{k}, group: #{group}, rest: #{rest}"
|
339
468
|
data[:functions][key][:group] = group
|
340
469
|
func[group] ||= []
|
341
470
|
func[group] << key
|
342
471
|
func[group].sort!
|
343
472
|
end
|
344
|
-
misc = []
|
345
473
|
func.to_a.sort
|
346
474
|
end
|
347
475
|
|
348
476
|
def find_type_usage!(data)
|
349
|
-
# go through all
|
477
|
+
# go through all functions, callbacks, and structs
|
478
|
+
# see which other types are used and returned
|
350
479
|
# store them in the types data
|
351
|
-
|
480
|
+
h = {}
|
481
|
+
h.merge!(data[:functions])
|
482
|
+
h.merge!(data[:callbacks])
|
483
|
+
|
484
|
+
structs = data[:types].find_all {|t, tdata| (tdata[:type] == :struct and tdata[:fields] and not tdata[:fields].empty?) }
|
485
|
+
structs = Hash[structs.map {|t, tdata| [t, tdata] }]
|
486
|
+
h.merge!(structs)
|
487
|
+
|
488
|
+
h.each do |use, use_data|
|
352
489
|
data[:types].each_with_index do |tdata, i|
|
353
490
|
type, typeData = tdata
|
354
|
-
|
355
|
-
|
356
|
-
|
491
|
+
|
492
|
+
data[:types][i][1][:used] ||= {:returns => [], :needs => [], :fields => []}
|
493
|
+
if use_data[:return] && use_data[:return][:type].index(/#{type}[ ;\)\*]?/)
|
494
|
+
data[:types][i][1][:used][:returns] << use
|
357
495
|
data[:types][i][1][:used][:returns].sort!
|
358
496
|
end
|
359
|
-
if
|
360
|
-
data[:types][i][1][:used][:needs] <<
|
497
|
+
if use_data[:argline] && use_data[:argline].index(/#{type}[ ;\)\*]?/)
|
498
|
+
data[:types][i][1][:used][:needs] << use
|
361
499
|
data[:types][i][1][:used][:needs].sort!
|
362
500
|
end
|
501
|
+
if use_data[:fields] and use_data[:fields].find {|f| f[:type] == type }
|
502
|
+
data[:types][i][1][:used][:fields] << use
|
503
|
+
data[:types][i][1][:used][:fields].sort!
|
504
|
+
end
|
363
505
|
end
|
364
506
|
end
|
365
507
|
end
|
@@ -376,9 +518,28 @@ class Docurium
|
|
376
518
|
|
377
519
|
file_map = {}
|
378
520
|
|
379
|
-
md = Redcarpet::Markdown.new
|
521
|
+
md = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new({}), :no_intra_emphasis => true)
|
380
522
|
recs.each do |r|
|
381
523
|
|
524
|
+
types = %w(function file type).map(&:to_sym)
|
525
|
+
dbg = false
|
526
|
+
types.each do |t|
|
527
|
+
dbg ||= if r[:type] == t and interesting?(t, r[:name])
|
528
|
+
true
|
529
|
+
elsif t == :file and interesting?(:file, r[:file])
|
530
|
+
true
|
531
|
+
elsif [:struct, :enum].include?(r[:type]) and interesting?(:type, r[:name])
|
532
|
+
true
|
533
|
+
else
|
534
|
+
false
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
debug_set dbg
|
539
|
+
|
540
|
+
debug "processing record: #{r}"
|
541
|
+
debug
|
542
|
+
|
382
543
|
# initialize filemap for this file
|
383
544
|
file_map[r[:file]] ||= {
|
384
545
|
:file => r[:file], :functions => [], :meta => {}, :lines => 0
|
@@ -390,7 +551,7 @@ class Docurium
|
|
390
551
|
# process this type of record
|
391
552
|
case r[:type]
|
392
553
|
when :function, :callback
|
393
|
-
|
554
|
+
t = r[:type] == :function ? :functions : :callbacks
|
394
555
|
data[t][r[:name]] ||= {}
|
395
556
|
wanted[:functions].each do |k|
|
396
557
|
next unless r.has_key? k
|
@@ -458,13 +619,24 @@ class Docurium
|
|
458
619
|
|
459
620
|
when :struct, :fnptr
|
460
621
|
data[:types][r[:name]] ||= {}
|
622
|
+
known = data[:types][r[:name]]
|
461
623
|
r[:value] ||= r[:name]
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
624
|
+
# we don't want to override "opaque" structs with typedefs or
|
625
|
+
# "public" documentation
|
626
|
+
unless r[:tdef].nil? and known[:fields] and known[:comments] and known[:description]
|
627
|
+
wanted[:types].each do |k|
|
628
|
+
next unless r.has_key? k
|
629
|
+
if k == :comments
|
630
|
+
data[:types][r[:name]][k] = md.render r[k]
|
631
|
+
else
|
632
|
+
data[:types][r[:name]][k] = r[k]
|
633
|
+
end
|
634
|
+
end
|
635
|
+
else
|
636
|
+
# We're about to skip that type. Just make sure we preserve the
|
637
|
+
# :fields comment
|
638
|
+
if r[:fields] and known[:fields].empty?
|
639
|
+
data[:types][r[:name]][:fields] = r[:fields]
|
468
640
|
end
|
469
641
|
end
|
470
642
|
if r[:type] == :fnptr
|
@@ -475,6 +647,10 @@ class Docurium
|
|
475
647
|
# Anything else we want to record?
|
476
648
|
end
|
477
649
|
|
650
|
+
debug "processed record: #{r}"
|
651
|
+
debug
|
652
|
+
|
653
|
+
debug_restore
|
478
654
|
end
|
479
655
|
|
480
656
|
data[:files] << file_map.values[0]
|
@@ -505,4 +681,12 @@ class Docurium
|
|
505
681
|
def out(text)
|
506
682
|
puts text
|
507
683
|
end
|
684
|
+
|
685
|
+
def dry_run?
|
686
|
+
@cli_options[:dry_run]
|
687
|
+
end
|
688
|
+
|
689
|
+
def interesting?(type, what)
|
690
|
+
@cli_options['debug'] || (@cli_options["debug-#{type}"] || []).include?(what)
|
691
|
+
end
|
508
692
|
end
|
data/lib/libdetect.rb
CHANGED
data/site/css/style.css
CHANGED
@@ -95,12 +95,12 @@ input.search {
|
|
95
95
|
background: url(../images/search_icon.png) 5px 50% no-repeat white;
|
96
96
|
}
|
97
97
|
|
98
|
-
a small {
|
98
|
+
a small {
|
99
99
|
font-size: 0.8em;
|
100
100
|
color: #aaa;
|
101
101
|
}
|
102
102
|
|
103
|
-
h2 small {
|
103
|
+
h2 small {
|
104
104
|
font-size: 0.8em;
|
105
105
|
font-weight: normal;
|
106
106
|
color: #666;
|
@@ -117,18 +117,25 @@ table.methods tr td.methodName a {
|
|
117
117
|
font-weight: bold;
|
118
118
|
}
|
119
119
|
|
120
|
-
table.funcTable tr td
|
120
|
+
table.funcTable tr td,
|
121
|
+
table.structTable tr td {
|
121
122
|
padding: 5px 10px;
|
122
123
|
border-bottom: 1px solid #eee;
|
123
124
|
}
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
125
|
+
|
126
|
+
.enumTable .var,
|
127
|
+
.funcTable .var,
|
128
|
+
.structTable .var {
|
128
129
|
font-weight: bold;
|
129
130
|
color: #833;
|
130
131
|
}
|
131
132
|
|
133
|
+
.enumTable .type,
|
134
|
+
.funcTable .type,
|
135
|
+
.structTable .type {
|
136
|
+
text-align: right;
|
137
|
+
}
|
138
|
+
|
132
139
|
code.params {
|
133
140
|
white-space: pre-wrap; /* css-3 */
|
134
141
|
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
@@ -152,7 +159,9 @@ code.params {
|
|
152
159
|
|
153
160
|
.returns { margin-bottom: 15px; }
|
154
161
|
|
155
|
-
h1.funcTitle
|
162
|
+
h1.funcTitle,
|
163
|
+
h1.enumTitle,
|
164
|
+
h1.structTitle {
|
156
165
|
font-size: 1.6em;
|
157
166
|
}
|
158
167
|
h3.funcDesc {
|
@@ -255,6 +264,3 @@ p.functionList a.introd {
|
|
255
264
|
color: #933;
|
256
265
|
}
|
257
266
|
|
258
|
-
.type-comment {
|
259
|
-
padding-left: 3em;
|
260
|
-
}
|