#==============================================================================
# ** NoteTag
#------------------------------------------------------------------------------
# Représente les tags dans les notes
#==============================================================================
module NoteTag
#--------------------------------------------------------------------------
# * Système de type
#--------------------------------------------------------------------------
BoolCoers = ->(x) do
value = begin eval(x) rescue true end
!!value
end
Types = {
int: {ext:[:int, :integer], coers:->(x){x.to_i}},
float: {ext:[:float, :double], coers:->(x){x.to_f}},
string: {ext:[:string, :text], coers:->(x){x.to_s}},
bool: {ext:[:bool, :boolean], coers:BoolCoers},
string_list: {ext:[:strings, :string_list, :texts, :text_list],
coers:->(x) do
x.scan(/[^,|^\s]+/)
end
},
int_list: {ext:[:int_list, :integer_list, :ints, :integers],
coers:->(x) do
x.scan(/[^,|^\s]+/).collect{|i|i.to_i}
end
},
float_list: {ext:[:float_list, :floats],
coers:->(x) do
x.scan(/[^,|^\s]+/).collect{|i|i.to_f}
end
},
bool_list: {ext:[:bool_list, :bools, :booleans, :boolean_list],
coers:->(x) do
x.scan(/[^,|^\s]+/).collect{|i|BoolCoers.(x)}
end
},
}
#--------------------------------------------------------------------------
# * API pour les classes
#--------------------------------------------------------------------------
module API
#--------------------------------------------------------------------------
# * Renvoi les tags de la méthode note
#--------------------------------------------------------------------------
def tags
@note.to_tags
end
end
#--------------------------------------------------------------------------
# * Méthodes publiques
#--------------------------------------------------------------------------
class << self
#--------------------------------------------------------------------------
# * Inférence de type (produit la bonne cellulue en fonction d'un symbole)
#--------------------------------------------------------------------------
def get_coersion(k)
return Types[k][:coers] if Types.has_key?(k)
i = Types.find{|e| e[1][:ext].include?(k)}
return Types[i[0]][:coers] if i
return Types[:string][:coers]
end
#--------------------------------------------------------------------------
# * Convertit une valeur en fonction de son type
#--------------------------------------------------------------------------
def cast(value, type)
get_coersion(type).(value)
end
#--------------------------------------------------------------------------
# * Convertit une ligne en Tag
#--------------------------------------------------------------------------
def convert(line)
return nil unless line =~ /^<.*>$/
if line =~ /^<(.+)>(.*)<\/\w+>/
type = :string
key = $1
value = $2
if key =~ /^(\w+)\s*:\s*(\w+)$/
key, type = $1, $2.to_sym
end
return Simple.new(key, value, type)
end
body = line =~ /^<\s*(.*)\s*\/>$/ && $1
return nil unless body
head, tail = body =~ /^(\w*)/ && [$1, $']
attributes = parse_attributes(tail)
return Complex.new(head, attributes)
end
#--------------------------------------------------------------------------
# * Construit les attributs
#--------------------------------------------------------------------------
def parse_attributes(str, acc = {})
return acc.select do |key, a|
a && a.keyword && a.value
end if !str || str.empty?
type = :string
key, value, tail =
str =~ /^\s*(\w+|\w+:\w+)\s*=\s*\\*"([^\\"]+)\\*"/ && [$1,$2,$']
if key =~ /^(\w+)\s*:\s*(\w+)$/
key, type = $1, $2.to_sym
end
acc[key.to_sym] = Simple.new(key, value, type) if key
parse_attributes(tail, acc)
end
end
#==============================================================================
# ** Simple
#------------------------------------------------------------------------------
# Représente une entité simple
# soit valeur
# soit valeur
#==============================================================================
class Simple
#--------------------------------------------------------------------------
# * Public instances variables
#--------------------------------------------------------------------------
attr_reader :keyword
attr_reader :value
attr_reader :type
#--------------------------------------------------------------------------
# * Object initialize
#--------------------------------------------------------------------------
def initialize(k, v, t=:string)
@type = t
@keyword = k
@value = NoteTag.cast(v, @type)
end
end
#==============================================================================
# ** Complex
#------------------------------------------------------------------------------
# Représente une entité complexe
# soit
# soit
#==============================================================================
class Complex
#--------------------------------------------------------------------------
# * Public instances variables
#--------------------------------------------------------------------------
attr_reader :keyword
attr_reader :attributes
#--------------------------------------------------------------------------
# * Object initialize
#--------------------------------------------------------------------------
def initialize(k, a)
@keyword = k
@attributes = a
end
#--------------------------------------------------------------------------
# * Accessor
#--------------------------------------------------------------------------
def method_missing(m, *rest)
return @attributes[m].value if @attributes.has_key?(m)
raise NoMethodError
end
end
end
#==============================================================================
# ** String
#------------------------------------------------------------------------------
# Ajoute la conversion des lignes en tags
#==============================================================================
class String
#--------------------------------------------------------------------------
# * Conversion d'une chaine un hash de tag
#--------------------------------------------------------------------------
def to_tags
tags = {}
self.split(/\n|\r\n/).each do |ln|
p ln
parsed = NoteTag.convert(ln)
tags[parsed.keyword] = parsed if parsed
end
tags
end
end
#==============================================================================
# ** Ajout des notes aux instances
#------------------------------------------------------------------------------
#==============================================================================
[RPG::BaseItem, RPG::Tileset, RPG::Map].each do |cls|
cls.send(:include, NoteTag::API)
end