# module RDoc::Encoding

This class is a wrapper around File IO and Encoding that helps RDoc load files and convert them to the correct encoding.

### Public Class Methods

read_file(filename, encoding, force_transcode = false) click to toggle source

Reads the contents of `filename` and handles any encoding directives in the file.

The content will be converted to the `encoding`. If the file cannot be converted a warning will be printed and nil will be returned.

If `force_transcode` is true the document will be transcoded and any unknown character in the target encoding will be replaced with ‘?’

    # File lib/rdoc/encoding.rb, line 18
    def self.read_file filename, encoding, force_transcode = false
      content = open filename, "rb" do |f| f.read end
      content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ %rmswin|mingw/

      utf8 = content.sub!(%r\A\xef\xbb\xbf/, '')

      RDoc::Encoding.set_encoding content

      if Object.const_defined? :Encoding then
        encoding ||= Encoding.default_external
        orig_encoding = content.encoding

        if utf8 then
          content.force_encoding Encoding::UTF_8
          content.encode! encoding
        else
          # assume the content is in our output encoding
          content.force_encoding encoding
        end

        unless content.valid_encoding? then
          # revert and try to transcode
          content.force_encoding orig_encoding
          content.encode! encoding
        end

        unless content.valid_encoding? then
          warn "unable to convert #{filename} to #{encoding}, skipping"
          content = nil
        end
      end

      content
    rescue ArgumentError => e
      raise unless e.message =~ %runknown encoding name - (.*)/
      warn "unknown encoding name \"#{$1}\" for #{filename}, skipping"
      nil
    rescue Encoding::UndefinedConversionError => e
      if force_transcode then
        content.force_encoding orig_encoding
        content.encode! encoding, :undef => :replace, :replace => '?'
        content
      else
        warn "unable to convert #{e.message} for #{filename}, skipping"
        nil
      end
    rescue Errno::EISDIR, Errno::ENOENT
      nil
    end

set_encoding(string) click to toggle source

Sets the encoding of `string` based on the magic comment

    # File lib/rdoc/encoding.rb, line 71
    def self.set_encoding string
      first_line = string[%r\A(?:#!.*\n)?.*\n/]

      name = case first_line
             when %r^<\?xml[^?]*encoding=(["'])(.*?)\11// then $2
             when %r\b(?:en)?coding[=:]\s*([^\s;]+)/   then $1
             else                                           return
             end

      string.sub! first_line, ''

      return unless Object.const_defined? :Encoding

      enc = Encoding.find name
      string.force_encoding enc if enc
    end