Class: Decode::Languages

Inherits:
Object
  • Object
show all
Defined in:
lib/decode/languages.rb

Overview

Represents a context for looking up languages based on file extension or name.

Constant Summary collapse

REFERENCE =
/\A(?<name>[a-z]+)?\s+(?<identifier>.*?)\z/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeLanguages

Initialize a new languages context.



21
22
23
24
# File 'lib/decode/languages.rb', line 21

def initialize
  @named = {}
  @extensions = {}
end

Instance Attribute Details

#extensionsObject (readonly)

Returns the value of attribute extensions.



30
31
32
# File 'lib/decode/languages.rb', line 30

def extensions
  @extensions
end

#namedObject (readonly)

Returns the value of attribute named.



27
28
29
# File 'lib/decode/languages.rb', line 27

def named
  @named
end

#The languages by extension.(languagesbyextension.) ⇒ Object (readonly)



30
# File 'lib/decode/languages.rb', line 30

attr :extensions

#The named languages.(namedlanguages.) ⇒ Object (readonly)



27
# File 'lib/decode/languages.rb', line 27

attr :named

Class Method Details

.allObject

Create a new languages context with all supported languages.



14
15
16
17
18
# File 'lib/decode/languages.rb', line 14

def self.all
  self.new.tap do |languages|
    languages.add(Language::Ruby.new)
  end
end

Instance Method Details

#add(language) ⇒ Object

Add a language to this context.



45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/decode/languages.rb', line 45

def add(language)
  # Register by name:
  language.names.each do |name|
    @named[name] = language
  end
  
  # Register by file extension:
  language.extensions.each do |extension|
    @extensions[extension] = language
  end
  
  return self
end

#fetch(name) ⇒ Object

Fetch a language by name, creating a generic language if needed.



62
63
64
65
66
67
68
69
70
# File 'lib/decode/languages.rb', line 62

def fetch(name)
  @named.fetch(name) do
    unless @named.frozen?
      @named[name] = Language::Generic.new(name)
    else
      nil
    end
  end
end

#freezeObject

Freeze the languages context to prevent further modifications.



33
34
35
36
37
38
39
40
# File 'lib/decode/languages.rb', line 33

def freeze
  return unless frozen?
  
  @named.freeze
  @extensions.freeze
  
  super
end

#parse_reference(text, default_language: nil) ⇒ Object

Parse a language agnostic reference.



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/decode/languages.rb', line 90

def parse_reference(text, default_language: nil)
  if match = REFERENCE.match(text)
    name = match[:name]
    identifier = match[:identifier]
    
    if name
      language = self.fetch(name) || default_language
    else
      language = default_language
    end
    
    if language && identifier
      return language.reference_for(identifier)
    end
  elsif default_language
    return default_language.reference_for(text)
  end
end

#reference_for(name, identifier) ⇒ Object

Create a reference for the given language and identifier.



113
114
115
# File 'lib/decode/languages.rb', line 113

def reference_for(name, identifier)
  self.fetch(name)&.reference_for(identifier)
end

#source_for(path) ⇒ Object

Create a source object for the given file path.



75
76
77
78
79
80
81
# File 'lib/decode/languages.rb', line 75

def source_for(path)
  extension = File.extname(path)
  
  if language = @extensions[extension]
    Source.new(path, language)
  end
end