Chapter 4.  Sources

Table of Contents

File: tmdoc.rb
Overview
Code
File: constant.rb
Overview
Code
File: environment.rb
Overview
Code
File: transformer/localizable-string.rb
Overview
Code
File: transformer/core-into-module/transformer.rb
Overview
Code
File: transformer/core-into-module/constant.rb
Overview
Code
File: transformer/core-into-module/evaluater.rb
Overview
Code
File: transformer/core-into-module/resolver.rb
Overview
Code
File: transformer/module-into-object/transformer.rb
Overview
Code
File: transformer/module-into-object/module.rb
Overview
Code
File: transformer/module-into-object/source.rb
Overview
Code
File: transformer/module-into-object/path.rb
Overview
Code
File: transformer/object-into-document/transformer.rb
Overview
Code
File: transformer/object-into-document/module.rb
Overview
Code
File: transformer/object-into-document/module-infobox.rb
Overview
Code
File: transformer/object-into-document/source.rb
Overview
Code
File: transformer/object-into-document/node.rb
Overview
Code
File: transformer/object-into-document/link.rb
Overview
Code
File: transformer/object-into-document/path.rb
Overview
Code
File: transformer/document-into-docbook/transformer.rb
Overview
Code
File: transformer/document-into-docbook/overview.rb
Overview
Code
File: transformer/document-into-docbook/module.rb
Overview
Code
File: transformer/document-into-docbook/module-infobox.rb
Overview
Code
File: transformer/document-into-docbook/source.rb
Overview
Code
File: transformer/document-into-docbook/node.rb
Overview
Code
File: transformer/document-into-docbook/link.rb
Overview
Code
File: transformer/document-into-docbook/id.rb
Overview
Code
File: reader/reader.rb
Overview
Code
File: reader/ruby1.8/scanner.rb
Overview
Code
File: reader/ruby1.8/parser.rb
Code
File: reader/ruby1.8/parser/parser.rb
Overview
Code
File: reader/ruby1.8/parser/node.rb
Overview
Code
File: reader/ruby1.8/parser/leaf.rb
Overview
Code
File: reader/ruby1.8/parser/common.rb
Overview
Code
File: reader/ruby1.8/parser/types.rb
Overview
Code
File: writer/writer.rb
Overview
Code
File: writer/docbook/writer.rb
Overview
Code
File: model/abstraction.rb
Overview
Code
File: model/core.rb
Code
File: model/core/store.rb
Overview
Code
File: model/core/physical.rb
Overview
Code
File: model/core/logical.rb
Overview
Code
File: model/module.rb
Code
File: model/module/store.rb
Overview
Code
File: model/module/physical.rb
Overview
Code
File: model/module/logical.rb
Overview
Code
File: model/object.rb
Code
File: model/object/store.rb
Overview
Code
File: model/object/physical.rb
Overview
Code
File: model/object/logical.rb
Code
File: model/object/logical/path.rb
Overview
Code
File: model/object/logical/abstraction.rb
Overview
Code
File: model/object/logical/leaf.rb
Overview
Code
File: model/object/logical/node.rb
Overview
Code
File: model/object/logical/relationship.rb
Overview
Code
File: model/object/logical/location.rb
Overview
Code
File: model/document.rb
Code
File: model/document/store.rb
Overview
Code
File: model/document/abstraction.rb
Overview
Code
File: model/document/overview.rb
Overview
Code
File: model/document/module.rb
Overview
Code
File: model/document/module-infobox.rb
Overview
Code
File: model/document/source.rb
Overview
Code
File: model/document/node.rb
Overview
Code
File: model/document/link.rb
Overview
Code
File: model/document/path.rb
Overview
Code
File: model/docbook.rb
Overview
Code
File: tmstd.rb
Code
File: tmstd/assertion.rb
Overview
Code
File: tmstd/logger.rb
Overview
Code
File: tmstd/lsm.rb
Code
File: tmstd/lsm/abstraction.rb
Overview
Code
File: tmstd/lsm/sum.rb
Overview
Code
File: tmstd/lsm/collection/sequence.rb
Overview
Code
File: tmstd/lsm/collection/set.rb
Overview
Code
File: tmstd/lsm/collection/map.rb
Overview
Code
File: tmstd/xml.rb
Overview
Code
File: tmstd/docbook.rb
Code
File: tmstd/docbook/abstraction.rb
Overview
Code
File: tmstd/docbook/factory.rb
Overview
Code
File: tmstd/docbook/leaf.rb
Overview
Code
File: tmstd/docbook/node.rb
Code
File: tmstd/docbook/node/element.rb
Overview
Code
File: tmstd/docbook/node/content.rb
Overview
Code
File: tmstd/treeable.rb
Overview
Code
File: tmstd/cache.rb
Overview
Code

File: tmdoc.rb

Overview

Module Structure

  module: <Toplevel Module>
  module: TmDoc#17
  module: Commander#19
has properties
module method: main / 2 #96
module method: parse_arguments / 1 #145
module method: check_input_directory / 1 #350
module method: check_output_directory / 1 #389
module method: execute / 2 #428
module method: test_sensitive_level / 2 #542
  class: Parameter#21
inherits from
  Abstract ( TmStd::Lsm::Product )
has properties
attribute: input_dir_name [R] #22
attribute: input_file_names [R] #23
attribute: output_dir_name [R] #24
attribute: log_file_name [R] #25
attribute: source_dir_name [R] #26
attribute: document_dir_name [R] #27
attribute: show_code [R] #28
attribute: show_module_siblings [R] #29
attribute: show_class_siblings [R] #30
attribute: sort_by_name [R] #31
attribute: book_title [R] #32
attribute: tab_width [R] #33
method: initialize / 10 #36
method: source_dir_name! / 1 #77
method: document_dir_name! / 1 #86

Class Hierarchy

Code

   1  # $Id: tmdoc.rb,v 1.19 2012/04/17 02:49:40 machan Exp $
   2 
   3  require 'optparse'
   4 
   5  require 'tmdoc/tmstd'
   6  require 'tmdoc/constant'
   7  require 'tmdoc/environment'
   8  require 'tmdoc/transformer/localizable-string'
   9  require 'tmdoc/transformer/core-into-module/transformer'
  10  require 'tmdoc/transformer/module-into-object/transformer'
  11  require 'tmdoc/transformer/object-into-document/transformer'
  12  require 'tmdoc/transformer/document-into-docbook/transformer'
  13  require 'tmdoc/reader/reader'
  14  require 'tmdoc/writer/writer'
  15 
  16 
  17  module TmDoc
  18 
  19  module Commander
  20 
  21  class Parameter < TmStd::Lsm::Product::Abstract
  22      attr_reader :input_dir_name,
  23                  :input_file_names,
  24                  :output_dir_name,
  25                  :log_file_name,
  26                  :source_dir_name,
  27                  :document_dir_name,
  28                  :show_code,
  29                  :show_module_siblings,
  30                  :show_class_siblings,
  31                  :sort_by_name,
  32                  :book_title,
  33                  :tab_width
  34 
  35 
  36      def initialize(
  37          input_dir_name,
  38          input_file_names,
  39          output_dir_name,
  40          log_file_name,
  41          show_code,
  42          show_module_siblings,
  43          show_class_siblings,
  44          sort_by_name,
  45          book_title,
  46          tab_width
  47      )
  48          ASSERT.opt_kind_of  input_dir_name,         String
  49          ASSERT.kind_of      input_file_names,       LSM::SeqOfString
  50          ASSERT.opt_kind_of  output_dir_name,        String
  51          ASSERT.opt_kind_of  log_file_name,          String
  52          ASSERT.boolean      show_code
  53          ASSERT.boolean      show_module_siblings
  54          ASSERT.boolean      show_class_siblings
  55          ASSERT.boolean      sort_by_name
  56          ASSERT.kind_of      book_title,             String
  57          ASSERT.kind_of      tab_width,              Integer
  58 
  59          @input_dir_name     = input_dir_name
  60          @input_file_names   = input_file_names
  61          @output_dir_name    = output_dir_name
  62          @log_file_name      = log_file_name
  63 
  64          @source_dir_name    = nil
  65          @document_dir_name  = nil
  66 
  67          @show_code              = show_code
  68          @show_module_siblings   = show_module_siblings
  69          @show_class_siblings    = show_class_siblings
  70          @sort_by_name           = sort_by_name
  71 
  72          @book_title = book_title
  73          @tab_width  = tab_width
  74      end
  75 
  76 
  77      def source_dir_name!(source_dir_name)
  78          ASSERT.kind_of source_dir_name, String
  79 
  80          @source_dir_name = source_dir_name
  81 
  82          nil
  83      end
  84 
  85 
  86      def document_dir_name!(document_dir_name)
  87          ASSERT.kind_of document_dir_name, String
  88 
  89          @document_dir_name = document_dir_name
  90 
  91          nil
  92      end
  93  end
  94 
  95 
  96      def Commander.main(argv, &block)
  97          ASSERT.kind_of argv,        Array
  98          ASSERT.opt_kind_of block,   Proc
  99 
 100          exit_code = 0
 101 
 102          begin
 103              param, env = Commander.parse_arguments argv
 104              ASSERT.kind_of param,   Parameter
 105              ASSERT.kind_of env,     ENV::Environment
 106 
 107              TmStd::Logger::File.verbose_level_event!(
 108                  env.verbose_level_event
 109              )
 110              TmStd::Logger::File.open(param.log_file_name) do
 111                  source_dir_name     = Commander.check_input_directory(
 112                                              param.input_dir_name
 113                                          )
 114                  param.source_dir_name! source_dir_name
 115 
 116                  document_dir_name   = Commander.check_output_directory(
 117                                              param.output_dir_name
 118                                          )
 119                  param.document_dir_name! document_dir_name
 120 
 121                  if block
 122                      block.call param, env
 123                  else
 124                      Commander.execute param, env
 125                  end
 126              end
 127          rescue TmStd::Exception::LogfileOpenError
 128              exit_code = 1
 129          rescue TmDoc::Exception::Abstraction::Exception => exception
 130              exit_code =
 131                  case exception
 132                  when Exception::NormalEnd;              0
 133                  when Exception::CommandArgumentError;   1
 134                  when Exception::OutputError;            2
 135                  when Exception::SensitivityAbort;       3
 136                  else
 137                      ASSERT.abort "Unknown exception: %s", exception.to_s
 138                  end
 139          end
 140 
 141          ASSERT.kind_of exit_code, Integer
 142      end
 143 
 144 
 145      def Commander.parse_arguments(argv)
 146          ASSERT.kind_of argv, Array
 147 
 148          input_dir_name  = nil
 149          output_dir_name = nil
 150          log_file_name   = nil
 151 
 152          show_code               = true
 153          show_module_siblings    = false
 154          show_class_siblings     = false
 155          sort_by_name            = false
 156 
 157          book_title              = TLS::BOOK_TITLE
 158          tab_width               = TAB_WIDTH
 159 
 160          verbose_level_event     = LOG::Progress
 161          sensitive_level_event   = LOG::Fatal
 162 
 163          debug           = false
 164          debug_model     = false
 165          debug_parser    = false
 166          debug_scanner   = false
 167 
 168          OptionParser.new { |opts|
 169              opts.on(
 170                  '-i DIRECTORY', '--input-dir DIRECTORY',
 171                  'Source files directory'
 172              ) do |dir_name|
 173                  input_dir_name = dir_name
 174              end
 175 
 176              opts.on(
 177                  '-o DIRECTORY', '--output-dir DIRECTORY',
 178                  'Document files directory'
 179              ) do |dir_name|
 180                  output_dir_name = dir_name
 181              end
 182 
 183              opts.on(
 184                  '-t STRING', '--title STRING',
 185                  'Title of the document'
 186              ) do |title|
 187                  book_title = title
 188              end
 189 
 190              opts.on(
 191                  '-e NUMBER', '--tab-width NUMBER', Integer,
 192                  'Tab width of source codes(default=8)'
 193              ) do |num|
 194                  unless 1 <= num && num <= 16
 195                      $stderr.printf(
 196                          "invalid argument(tab width): %s\n", num.to_s
 197                      )
 198                      raise TmDoc::Exception::CommandArgumentError
 199                  end
 200 
 201                  tab_width = num
 202              end
 203 
 204              opts.on(
 205                  '-c', '--[no-]show-code',
 206                  'Show source code'
 207              ) do |answer|
 208                  show_code = answer
 209              end
 210 
 211              opts.on(
 212                  '--[no-]show-module-siblings',
 213                  'Show siblings info of module structure'
 214              ) do |answer|
 215                  show_module_siblings = answer
 216              end
 217 
 218              opts.on(
 219                  '--[no-]show-class-siblings',
 220                  'Show siblings info of class hierarcy'
 221              ) do |answer|
 222                  show_class_siblings = answer
 223              end
 224 
 225              opts.on(
 226                  '-a', '--show-all',
 227                  'Enable all --show-XXX options'
 228              ) do |bool|
 229                  show_code               =
 230                  show_module_siblings    =
 231                  show_class_siblings     = bool
 232              end
 233 
 234              opts.on(
 235                  '--[no-]sort-by-name',
 236                  'Sort chapter sequence by module/class name'
 237              ) do |answer|
 238                  sort_by_name = answer
 239              end
 240 
 241              opts.on(
 242                  '-v LEVEL', '--verbose-level LEVEL',
 243                  'LEVEL is "progress", "info", "notice"..etc',
 244                  {
 245                      :debug      =>  LOG::Debug,
 246                      :progress   =>  LOG::Progress,
 247                      :info       =>  LOG::Information,
 248                      :notice     =>  LOG::Notice,
 249                      :warn       =>  LOG::Warning,
 250                      :error      =>  LOG::Error,
 251                      :fatal      =>  LOG::Fatal
 252                  }
 253              ) do |level_event|
 254                  verbose_level_event = level_event
 255              end
 256 
 257              opts.on(
 258                  '--quiet',
 259                  'Silent mode, equal to "-v fatal"'
 260              ) do |bool|
 261                  verbose_level_event = LOG::Fatal
 262              end
 263 
 264              opts.on(
 265                  '-s LEVEL', '--sensitive-level LEVEL',
 266                  'LEVEL is "notice", "warn", "error"..etc',
 267                  {
 268                      :notice     =>  LOG::Notice,
 269                      :warn       =>  LOG::Warning,
 270                      :error      =>  LOG::Error,
 271                      :fatal      =>  LOG::Fatal
 272                  }
 273              ) do |level_event|
 274                  sensitive_level_event = level_event
 275              end
 276 
 277              opts.on(
 278                  '-l FILE', '--log-file FILE',
 279                  'Logging file\'s name'
 280              ) do |file_name|
 281                  log_file_name = file_name
 282              end
 283 
 284              opts.on(
 285                  '--debug-model',            'For debugging'
 286              ) do |boolean|
 287                  debug_model = boolean
 288              end
 289 
 290              opts.on(
 291                  '--debug-parser',           'For debugging'
 292              ) do |boolean|
 293                  debug_parser = boolean
 294              end
 295 
 296              opts.on(
 297                  '--debug-scanner',          'For debugging'
 298              ) do |boolean|
 299                  debug_scanner = boolean
 300              end
 301 
 302              opts.on(
 303                  '--debug',                  'For debugging'
 304              ) do |boolean|
 305                  debug = boolean
 306              end
 307 
 308              opts.on(
 309                  '--[no-]assertion',         'For debugging'
 310              ) do |boolean|
 311                  ASSERT.disable!(! boolean)
 312              end
 313 
 314              begin
 315                  opts.banner     = 'tmdoc [OPTION ..] SOURCE_FILE ..'
 316                  opts.version    = TMDOC_VERSION
 317                  opts.parse!(argv)
 318              rescue OptionParser::ParseError => exception
 319                  $stderr.puts exception.to_s
 320 
 321                  raise Exception::CommandArgumentError
 322              end
 323          }
 324 
 325          param = Parameter.new(
 326              input_dir_name,
 327              LSM::SeqOfString.new(argv),
 328              output_dir_name,
 329              log_file_name,
 330              show_code,
 331              show_module_siblings,
 332              show_class_siblings,
 333              sort_by_name,
 334              book_title,
 335              tab_width
 336          )
 337          env = ENV::Environment.new(
 338              verbose_level_event,
 339              sensitive_level_event,
 340              debug,
 341              debug_model,
 342              debug_parser,
 343              debug_scanner
 344          )
 345 
 346          ASSERT.tuple_of [param, env], [Parameter, ENV::Environment]
 347      end
 348 
 349 
 350      def Commander.check_input_directory(input_dir_name)
 351          ASSERT.opt_kind_of input_dir_name, String
 352 
 353          expand_dir_name = File.expand_path(
 354              if input_dir_name
 355                  input_dir_name
 356              else
 357                  '.'
 358              end
 359          )
 360 
 361          unless File.exist?(expand_dir_name)
 362              LOG::Fatal.log(
 363                  "No such directory: '%s'", expand_dir_name
 364              )
 365              raise Exception::CommandArgumentError
 366          end
 367 
 368          dir_stat = File.stat(expand_dir_name)
 369          ASSERT.kind_of dir_stat, File::Stat
 370 
 371          unless dir_stat.directory?
 372              LOG::Fatal.log(
 373                  "Not a directory: '%s'", expand_dir_name
 374              )
 375              raise Exception::CommandArgumentError
 376          end
 377 
 378          unless dir_stat.readable?
 379              LOG::Fatal.log(
 380                  "Not a readable directory: '%s'", expand_dir_name
 381              )
 382              raise Exception::CommandArgumentError
 383          end
 384 
 385          ASSERT.kind_of expand_dir_name, String
 386      end
 387 
 388 
 389      def Commander.check_output_directory(output_dir_name)
 390          ASSERT.opt_kind_of output_dir_name, String
 391 
 392          expand_dir_name = File.expand_path(
 393              if output_dir_name
 394                  output_dir_name
 395              else
 396                  OUTPUT_DIR_NAME
 397              end
 398          )
 399 
 400          unless File.exist?(expand_dir_name)
 401              LOG::Fatal.log(
 402                  "No such directory: '%s'", expand_dir_name
 403              )
 404              raise Exception::CommandArgumentError
 405          end
 406 
 407          document_dir_stat = File.stat(expand_dir_name)
 408          ASSERT.kind_of document_dir_stat, File::Stat
 409 
 410          unless document_dir_stat.directory?
 411              LOG::Fatal.log(
 412                  "Not a directory: '%s'", expand_dir_name
 413              )
 414              raise Exception::CommandArgumentError
 415          end
 416 
 417          unless document_dir_stat.writable?
 418              LOG::Fatal.log(
 419                  "Not a writable directory: '%s'", expand_dir_name
 420              )
 421              raise Exception::CommandArgumentError
 422          end
 423 
 424          ASSERT.kind_of expand_dir_name, String
 425      end
 426 
 427 
 428      def Commander.execute(param, env)
 429          ASSERT.kind_of param,   Parameter
 430          ASSERT.kind_of env,     ENV::Environment
 431 
 432          LOG::Information.log 'Starting TmDoc.'
 433          LOG::Progress.log
 434          started_time = Time.now
 435 
 436 
 437          GC.enable
 438 
 439          LOG::Information.log 'Reading source files....'
 440          LOG::Progress.log
 441          mc_store = Reader.read(
 442              param.source_dir_name,
 443              param.input_file_names,
 444              env
 445          ) do |reading_file_name|
 446              LOG::Progress.log "\t%s", reading_file_name
 447          end
 448          mc_store.print if env.debug_model?
 449          LOG::Progress.log
 450 
 451 
 452          LOG::Information.log 'Making the module model....'
 453          mm_store = Transformer::CoreIntoModule.transform(
 454              mc_store,
 455              env
 456          )
 457          mc_store = nil      # for GC
 458          GC.start
 459          mm_store.print if env.debug_model?
 460          LOG::Progress.log
 461 
 462 
 463          LOG::Information.log 'Making the object model....'
 464          LOG::Progress.log
 465          LOG::Progress.log "\tTransforming...."
 466          mo_store = Transformer::ModuleIntoObject.transform(
 467              mm_store,
 468              env
 469          )
 470          LOG::Progress.log "\tIndexing...."
 471          mo_store.make_indexes!
 472          mm_store = nil      # for GC
 473          GC.start
 474          mo_store.print if env.debug_model?
 475          LOG::Progress.log
 476 
 477 
 478          LOG::Information.log 'Making the document model....'
 479          LOG::Progress.log
 480          md_store = Transformer::ObjectIntoDocument.transform(
 481              mo_store,
 482              env,
 483              param.show_module_siblings,
 484              param.show_class_siblings,
 485              param.show_code,
 486              param.sort_by_name
 487          )
 488          mo_store = nil      # for GC
 489          GC.start
 490          md_store.print if env.debug_model?
 491          LOG::Progress.log
 492 
 493 
 494          LOG::Information.log 'Making the DocBook model....'
 495          LOG::Progress.log
 496          mb_store = Transformer::DocumentIntoDocBook.transform(
 497              md_store,
 498              env,
 499              param.book_title,
 500              param.source_dir_name,
 501              param.tab_width,
 502              param.show_code
 503          )
 504          md_store = nil      # for GC
 505          GC.start
 506          mb_store.print if env.debug_model?
 507          LOG::Progress.log
 508 
 509 
 510          LOG::Information.log 'Writing the document to files....'
 511          LOG::Progress.log
 512          Writer.write(
 513              mb_store,
 514              param.document_dir_name,
 515              env
 516          ) do |writing_file_name|
 517              LOG::Progress.log "\t%s", writing_file_name
 518          end
 519          LOG::Progress.log
 520 
 521 
 522          elapsed_time    = (Time.now - started_time).to_i
 523          elapsed_sec     = elapsed_time % 60
 524          elapsed_min     = (elapsed_time / 60).to_i
 525          LOG::Information.log(
 526              "Finished TmDoc!!\n" +
 527                  "\telapsed time: %dsec%s",
 528              elapsed_time,
 529              (
 530                  if elapsed_min >= 1
 531                      format(" (%dm%ds)", elapsed_min, elapsed_sec)
 532                  else
 533                      ''
 534                  end
 535              )
 536          )
 537 
 538          nil
 539      end
 540 
 541 
 542      def Commander.test_sensitive_level(env, level_event)
 543          ASSERT.kind_of  env,            ENV::Environment
 544          ASSERT.subclass_of(
 545                          level_event,    TmStd::Logger::Event::Abstract
 546          )
 547 
 548          if level_event <= env.sensitive_level_event
 549              LOG::Fatal.log 'Sensitivity abort.'
 550              raise Exception::SensitivityAbort
 551          end
 552 
 553          nil
 554      end
 555  end
 556 
 557  end # TmDoc
 558 
 559 
 560  if $0 == __FILE__
 561      exit_code = TmDoc::Commander.main(ARGV)
 562      exit exit_code
 563  end