~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to lib/rdoc/encoding.rb

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# coding: US-ASCII
 
2
 
 
3
require 'rdoc'
 
4
 
 
5
##
 
6
# This class is a wrapper around File IO and Encoding that helps RDoc load
 
7
# files and convert them to the correct encoding.
 
8
 
 
9
module RDoc::Encoding
 
10
 
 
11
  ##
 
12
  # Reads the contents of +filename+ and handles any encoding directives in
 
13
  # the file.
 
14
  #
 
15
  # The content will be converted to the +encoding+.  If the file cannot be
 
16
  # converted a warning will be printed and nil will be returned.
 
17
  #
 
18
  # If +force_transcode+ is true the document will be transcoded and any
 
19
  # unknown character in the target encoding will be replaced with '?'
 
20
 
 
21
  def self.read_file filename, encoding, force_transcode = false
 
22
    content = open filename, "rb" do |f| f.read end
 
23
 
 
24
    utf8 = content.sub!(/\A\xef\xbb\xbf/, '')
 
25
 
 
26
    RDoc::Encoding.set_encoding content
 
27
 
 
28
    if Object.const_defined? :Encoding then
 
29
      encoding ||= Encoding.default_external
 
30
      orig_encoding = content.encoding
 
31
 
 
32
      if utf8 then
 
33
        content.force_encoding Encoding::UTF_8
 
34
        content.encode! encoding
 
35
      else
 
36
        # assume the content is in our output encoding
 
37
        content.force_encoding encoding
 
38
      end
 
39
 
 
40
      unless content.valid_encoding? then
 
41
        # revert and try to transcode
 
42
        content.force_encoding orig_encoding
 
43
        content.encode! encoding
 
44
      end
 
45
 
 
46
      unless content.valid_encoding? then
 
47
        warn "unable to convert #{filename} to #{encoding}, skipping"
 
48
        content = nil
 
49
      end
 
50
    end
 
51
 
 
52
    content
 
53
  rescue ArgumentError => e
 
54
    raise unless e.message =~ /unknown encoding name - (.*)/
 
55
    warn "unknown encoding name \"#{$1}\" for #{filename}, skipping"
 
56
    nil
 
57
  rescue Encoding::UndefinedConversionError => e
 
58
    if force_transcode then
 
59
      content.force_encoding orig_encoding
 
60
      content.encode! encoding, :undef => :replace, :replace => '?'
 
61
      content
 
62
    else
 
63
      warn "unable to convert #{e.message} for #{filename}, skipping"
 
64
      nil
 
65
    end
 
66
  rescue Errno::EISDIR, Errno::ENOENT
 
67
    nil
 
68
  end
 
69
 
 
70
  ##
 
71
  # Sets the encoding of +string+ based on the magic comment
 
72
 
 
73
  def self.set_encoding string
 
74
    first_line = string[/\A(?:#!.*\n)?.*\n/]
 
75
 
 
76
    name = case first_line
 
77
           when /^<\?xml[^?]*encoding=(["'])(.*?)\1/ then $2
 
78
           when /\b(?:en)?coding[=:]\s*([^\s;]+)/i   then $1
 
79
           else                                           return
 
80
           end
 
81
 
 
82
    string.sub! first_line, ''
 
83
 
 
84
    return unless Object.const_defined? :Encoding
 
85
 
 
86
    enc = Encoding.find name
 
87
    string.force_encoding enc if enc
 
88
  end
 
89
 
 
90
end
 
91