File: transformer/document-into-docbook/source.rb

Overview
Module Structure
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: TmDoc#11
  module: Transformer
  module: DocumentIntoDocBook#13
  module: Source#15
has properties
module method: read_file / 3 #16
function: transform_sources / 7 #46
function: transform / 5 #90
function: transform_overview / 3 #141
constant: LINE_NUM_WIDTH #190
function: transform_code / 7 #192

Code

   1  # $Id: source.rb,v 1.11 2012/04/17 02:49:40 machan Exp $
   2 
   3  require 'tmdoc/tmstd'
   4  require 'tmdoc/tmstd/docbook'
   5  require 'tmdoc/constant'
   6  require 'tmdoc/model/document'
   7  require 'tmdoc/transformer/document-into-docbook/node'
   8  require 'tmdoc/transformer/localizable-string'
   9 
  10 
  11  module TmDoc
  12 
  13  module Transformer::DocumentIntoDocBook
  14 
  15  module Source
  16      def self.read_file(dir_name, file_name, env)
  17          ASSERT.kind_of dir_name,    String
  18          ASSERT.kind_of file_name,   String
  19          ASSERT.kind_of env,         ENV::Environment
  20 
  21          expand_file_path = Reader.check_file(dir_name, file_name, env)
  22          return nil unless expand_file_path
  23 
  24          lines = nil
  25          begin
  26              lines = IO.readlines(expand_file_path)
  27          rescue SystemCallError => exception
  28              LOG::Error.log(
  29                  "System call error in reading file\n" + "\t%s (%s)",
  30                  exception.to_s, exception.class.to_s
  31              )
  32              CMD.test_sensitive_level env, LOG::Error
  33          rescue IOError => exception
  34              LOG::Error.log "I/O error: '%s'", expand_file_path
  35              CMD.test_sensitive_level env, LOG::Error
  36          end
  37          return nil unless lines
  38 
  39          LSM::SeqOfString.new lines
  40      end
  41 
  42 
  43 
  44  module_function
  45 
  46      def transform_sources(
  47          md_sources, env, title, id, source_dir_name, tab_width, show_code
  48      )
  49          ASSERT.kind_of md_sources,      MDS::SeqOfSource
  50          ASSERT.kind_of env,             ENV::Environment
  51          ASSERT.kind_of title,           String
  52          ASSERT.kind_of id,              String
  53          ASSERT.kind_of source_dir_name, String
  54          ASSERT.kind_of tab_width,       Integer
  55          ASSERT.boolean show_code
  56 
  57          return nil if md_sources.empty?
  58 
  59          mb_documents = MBD::SeqOfDocument.new(
  60              md_sources.map { |md_source|
  61                  ASSERT.kind_of md_source, MDS::Source
  62 
  63                  LOG::Progress.log("\t\t%s", md_source.name)
  64 
  65                  transform(
  66                      md_source, env, source_dir_name, tab_width, show_code
  67                  )
  68              }.compact
  69          )
  70          return nil if mb_documents.empty?
  71 
  72          MBD::Node.new(
  73              id,
  74              DBOOK.chapter(:id => id) {
  75                  [
  76                      DBOOK.chapter_info {
  77                          [ DBOOK.title(title) ]
  78                      }
  79                  ] + mb_documents.map { |mb_document|
  80                      ASSERT.kind_of mb_document, MBD::Leaf
  81 
  82                      DBOOK.include(mb_document.name, OUTPUT_FILE_SUFFIX)
  83                  }
  84              },
  85              mb_documents
  86          )
  87      end
  88 
  89 
  90      def transform(md_file, env, source_dir_name, tab_width, show_code)
  91          ASSERT.kind_of md_file,         MDS::Source
  92          ASSERT.kind_of env,             ENV::Environment
  93          ASSERT.kind_of source_dir_name, String
  94          ASSERT.kind_of tab_width,       Integer
  95          ASSERT.boolean show_code
  96 
  97          name    = md_file.name
  98          title   = TLS::DIV_FILE + ': ' + name
  99          id      = Id.transform_file(name)
 100 
 101 
 102          mb_code =
 103              if show_code
 104                  lines = Source.read_file(source_dir_name, name, env)
 105 
 106                  if lines && (! lines.empty?)
 107                      transform_code(
 108                          lines,
 109                          env,
 110                          TLS::DIV_CODE,
 111                          id + Id::SEP + Id::DIV_NAME_OF_CODE,
 112                          name,
 113                          md_file.map_of_line_num_to_links,
 114                          tab_width
 115                      )
 116                  else
 117                      nil
 118                  end
 119              else
 120                  nil
 121              end
 122 
 123          MBD::Leaf.new(
 124              id,
 125 
 126              DBOOK.section(:id => id) {
 127                  [
 128                      DBOOK.section_info {
 129                          [ DBOOK.title(title) ]
 130                      },
 131 
 132                      transform_overview(id, md_file, show_code),
 133 
 134                      mb_code
 135                  ].compact
 136              }
 137          )
 138      end
 139 
 140 
 141      def transform_overview(file_id, md_file, show_code)
 142          ASSERT.kind_of file_id,     String
 143          ASSERT.kind_of md_file,     MDS::Source
 144          ASSERT.boolean show_code
 145 
 146          contents = [
 147              if md_file.a_module_structure
 148                  Node.transform_logical_structure(
 149                      md_file.a_module_structure,
 150                      TLS::DIV_M_STRUCTURE,
 151                      Id.transform_module_section(
 152                          file_id, Id::DIV_NAME_OF_M_STRUCTURE
 153                      ),
 154                      Id::DIV_NAME_OF_M_STRUCTURE,
 155                      :show_type_label            => true,
 156                      :show_line_num_in_infobox   => true,
 157                      :show_code                  => show_code
 158                  )
 159              else
 160                  nil
 161              end,
 162 
 163              if md_file.a_class_hierarchy
 164                  Node.transform_logical_structure(
 165                      md_file.a_class_hierarchy,
 166                      TLS::DIV_C_HIERARCHY,
 167                      Id.transform_module_section(
 168                          file_id, Id::DIV_NAME_OF_C_HIERARCHY
 169                      ),
 170                      Id::DIV_NAME_OF_C_HIERARCHY,
 171                      :show_above_link    => true,
 172                      :show_code          => show_code
 173                  )
 174              else
 175                  nil
 176              end
 177          ].compact
 178          return nil if contents.empty?
 179 
 180          DBOOK.section {
 181              [
 182                  DBOOK.section_info {
 183                      [ DBOOK.title(TLS::DIV_OVERVIEW) ]
 184                  }
 185              ] + contents
 186          }
 187      end
 188 
 189 
 190      LINE_NUM_WIDTH = 4
 191 
 192      def transform_code(
 193          lines,
 194          env,
 195          title,
 196          id,
 197          file_name,
 198          map_of_line_num_to_links,
 199          tab_width
 200      )
 201          ASSERT.kind_of lines,           LSM::SeqOfString
 202          ASSERT.kind_of env,             ENV::Environment
 203          ASSERT.kind_of title,           String
 204          ASSERT.kind_of id,              String
 205          ASSERT.kind_of file_name,       String
 206          ASSERT.kind_of(
 207              map_of_line_num_to_links,   MDL::MapOfLineNumToLinks
 208          )
 209          ASSERT.kind_of tab_width,       Integer
 210 
 211          contents = lines.map_with_index { |line, index|
 212              formating_line = line.chop.split(
 213                  /\t/
 214              ).inject('') { |result, elem|
 215                  n           = (result.length + tab_width) % tab_width
 216                  tab_stop    = ' ' * (tab_width - n)
 217 
 218                  result + tab_stop + elem
 219              }
 220              formated_line =
 221                  if formating_line.length >= tab_width
 222                      formating_line[
 223                          (tab_width - 1) .. (formating_line.length - 1)
 224                      ]
 225                  else
 226                      formating_line
 227                  end
 228 
 229              line_num    = index + 1
 230              links       = map_of_line_num_to_links.at line_num
 231 
 232              if links && links.length >= 1
 233                  md_link = links.first
 234                  link_id =
 235                      case md_link
 236                      when MDL::Module
 237                          Id.transform_module(
 238                              md_link.above_path, md_link.name
 239                          )
 240                      when MDL::Property
 241                          module_id = Id.transform_module(
 242                              *md_link.module_path.pop
 243                          )
 244 
 245                          Id.transform_property(
 246                              module_id, md_link.name, md_link.uniq_num
 247                          )
 248                      else
 249                          ASSERT.abort(
 250                              "Unknown md_link: %s", md_link.to_s
 251                          )
 252                      end
 253 
 254                  line_num_str        = line_num.to_s
 255                  line_num_width      = line_num_str.length
 256 
 257                  [
 258                      if line_num_width < LINE_NUM_WIDTH
 259                          DBOOK.text(
 260                              ' ' * (LINE_NUM_WIDTH - line_num_width)
 261                          )
 262                      else
 263                          nil
 264                      end,
 265 
 266                      DBOOK.anchor(
 267                          :id => Id.transform_line(file_name, line_num)
 268                      ),
 269 
 270                      Link.transform_text(link_id, line_num_str),
 271 
 272                      DBOOK.text(format(" %s\n", formated_line))
 273                  ].compact
 274              else
 275                  DBOOK.text(format("%4d %s\n", line_num, formated_line))
 276              end
 277          }.flatten
 278 
 279          DBOOK.section(:id => id) {
 280              [
 281                  DBOOK.section_info { [ DBOOK.title(title) ] },
 282 
 283                  DBOOK.program_listing { contents }
 284              ]
 285          }
 286      end
 287  end
 288 
 289  end # TmDoc::Transformer::DocumentIntoDocBook
 290 
 291  end # TmDoc