module Linguist

Constants

STRATEGIES

Internal: The strategies used to detect the language of a file.

A strategy is an object that has a `.call` method that takes two arguments:

 blob - An object that quacks like a blob.
 languages - An Array of candidate Language objects that were returned by the
             previous strategy.

A strategy should return an Array of Language candidates.

Strategies are called in turn until a single Language is returned.

VERSION

Attributes

instrumenter[RW]

Public: Set an instrumenter.

class CustomInstrumenter
  def instrument(name, payload = {})
    warn "Instrumenting #{name}: #{payload[:blob]}"
  end
end

Linguist.instrumenter = CustomInstrumenter.new

The instrumenter must conform to the `ActiveSupport::Notifications` interface, which defines `#instrument` and accepts:

name - the String name of the event (e.g. “linguist.detected”) payload - a Hash of the exception context.

Public Class Methods

detect(blob, allow_empty: false) click to toggle source

Public: Detects the Language of the blob.

blob - an object that includes the Linguist `BlobHelper` interface;

see Linguist::LazyBlob and Linguist::FileBlob for examples

Returns Language or nil.

# File lib/linguist.rb, line 18
def detect(blob, allow_empty: false)
  # Bail early if the blob is binary or empty.
  return nil if blob.likely_binary? || blob.binary? || (!allow_empty && blob.empty?)

  Linguist.instrument("linguist.detection", :blob => blob) do
    # Call each strategy until one candidate is returned.
    languages = []
    returning_strategy = nil

    STRATEGIES.each do |strategy|
      returning_strategy = strategy
      candidates = Linguist.instrument("linguist.strategy", :blob => blob, :strategy => strategy, :candidates => languages) do
        strategy.call(blob, languages)
      end
      if candidates.size == 1
        languages = candidates
        break
      elsif candidates.size > 1
        # More than one candidate was found, pass them to the next strategy.
        languages = candidates
      else
        # No candidates, try the next strategy
      end
    end

    Linguist.instrument("linguist.detected", :blob => blob, :strategy => returning_strategy, :language => languages.first)

    languages.first
  end
end
instrument(*args) { || ... } click to toggle source

Internal: Perform instrumentation on a block

Linguist.instrument("linguist.dosomething", :blob => blob) do
  # logic to instrument here.
end
# File lib/linguist.rb, line 92
def instrument(*args, &bk)
  if instrumenter
    instrumenter.instrument(*args, &bk)
  elsif block_given?
    yield
  end
end