summaryrefslogtreecommitdiff
path: root/support/rfil/lib/rfil/fontcollection.rb
blob: e206653d65793cb2426e66bee2951864a1e37e91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#--
# fontcollection.rb
# Last Change: Tue May 16 19:02:11 2006
#++

require 'rfil/rfi'
require 'rfil/font'
require 'rfil/helper'

module RFIL # :nodoc: 
  class RFI
    # A set of fonts (regular,bold,italic). Used to write an fd-file for
    # LaTeX or a typescript for ConTeXt. Register different fonts and set
    # encodings, so you dont't have to specify them in each font.
    
    class FontCollection
      include Helper
      def self.documented_as_accessor(*args) # :nodoc:
      end 
      def self.documented_as_reader(*args) # :nodoc:
      end 

      attr_accessor :vendor

      # attr_accessor :fontname
      
      # Name of the font (collection)
      attr_accessor :name
      
      # One object or one or more objects in an array that describe the
      # encoding of the postscript font. Object can either be a string
      # that represents the filename of the encoding ("8r.enc", "8r") or
      # an ENC object that already contains the encoding
      documented_as_accessor :mapenc

      # One object or one ore more objects in an array that describe the
      # encoding of the font TeX expects. Object can either be a string
      # that represents the filename of the encoding ("8r.enc", "8r") or
      # an ENC object that already contains the encoding
      documented_as_accessor :texenc

      # hash of directories for writing files. Default to current working
      # directory. The setting in the Font object overrides the setting here.
      attr_accessor :dirs

      attr_accessor :fonts

      # sans, roman, typewriter
      attr_accessor :style

      attr_accessor :write_vf

      attr_accessor :options
      
      # list of temps
      documented_as_reader :plugins
      
      def initialize()
        @kpse=Kpathsea.new
        @basedir=nil
        @name=nil
        @texenc=nil
        @mapenc=nil
        @write_vf=true
        @fonts=[]
        @options={:verbose=>false,:dryrun=>false}
        @style=nil
        @dirs={}
        @vendor=nil
        @fontname=nil
        set_dirs(Dir.getwd)
        @plugins={}
        # find temps-plugins
        $:.each{ |d|
          a=Dir.glob(d+"/rfil/rfi_plugin_*.rb")
          a.each{ |f|
            require f
          }
        }
        ObjectSpace.each_object(Class){ |x|
          if Plugin > x
            t = x.new(self)
            n = t.name
            if @plugins.has_key?(n)
              raise "Name already registered"
            end
            @plugins[n]=t
          end
        }
        # done initializing plugins
      end
      
      # Add a font to the collection. Return the number of the font.
      def register_font (font)
        unless font.respond_to?(:maplines)
          raise ArgumentError, "parameter does not look like a font"
        end
        fontnumber=@fonts.size
        @fonts << font
        return fontnumber
      end
      
      def run_plugin(name)

        raise "don't know plugin #{name}" unless @plugins.has_key?(name)
        
        # doc for run_plugin
        # Return the contents of the file that should be used by the TeX
        # macro package, i.e a typescript for ConTeXt or an fd-file for
        # Context. Return value is an Array of Hashes. The Hash has three
        # different keys:
        # [<tt>:type</tt>] The type of the file, should be either <tt>:fd</tt> or <tt>:typescript</tt>.
        # [<tt>:filename</tt>] the filename (without a path) of the file
        # [<tt>:contents</tt>] the contents of the file.

        files=@plugins[name].run_plugin
        if files.respond_to?(:each)
          files.each { |fh|
            dir=get_dir(fh[:type])
            filename=File.join(dir,fh[:filename])
            puts "writing file #{filename}" if @options[:verbose]
            
            unless @options[:dryrun]
              ensure_dir(dir)
              File.open(filename,"w") { |f| f << fh[:contents] }              
            end
          }
        end
      end
      def plugins #:nodoc:
        @plugins.keys
      end
      def mapfile
        mapfile=[]
        @fonts.each {|font|
          mapfile << font.maplines
        }
        mapfile.flatten
      end
      def mapenc        # :nodoc:
        return nil if @mapenc==:none
        @mapenc
      end
      def mapenc= (enc)  # :nodoc:
        set_mapenc(enc)
      end
      def texenc       # :nodoc:
        if @texenc
          @texenc
        else
          # @texenc not set
          ret=nil
          @kpse.open_file("8a.enc","enc") { |f|
            ret = [ENC.new(f)]
          }
          return ret
        end
      end
      def texenc= (enc) # :nodoc:
        @texenc=[]
        set_encarray(enc,@texenc)
      end
      def get_dir(type)
        @dirs[type]
      end
      def write_files(options={})
        mapdir=get_dir(:map); ensure_dir(mapdir)
        
        @fonts.each {|font|
          font.write_files(:mapfile => false)
          mapfile << font.maplines
        }
        mapfilename=File.join(mapdir,@name+".map")
        unless options[:dryrun]==true
          File.open(mapfilename, "w") {|file|
            file << mapfile.to_s
          }
        end
      end
    end
  end # class RFI
end # module RFIL