Class: UniProp::Version

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/uniprop/inspects.rb,
lib/uniprop/unicode_elements.rb

Direct Known Subclasses

EfficientVersion

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(prop_data, version_name) ⇒ Version

Returns a new instance of Version.



595
596
597
598
599
600
601
602
603
604
605
606
607
# File 'lib/uniprop/unicode_elements.rb', line 595

def initialize(prop_data, version_name)
  @prop_data = prop_data
  @version_name = version_name
  @major, @minor, @tiny = self.class.parse(@version_name).values
  @cache_path = @prop_data.cache_path + Pathname.new(@version_name)
  @unicode_beta = @prop_data.settings.unicode_beta(@version_name)
  @excluded_extensions = @prop_data.settings.excluded_extensions(@version_name).map { _1.downcase }
  @excluded_directories = @prop_data.settings.excluded_directories(@version_name).map { _1.downcase }
  @excluded_files = @prop_data.settings.excluded_files(@version_name).map { _1.downcase }
  @included_files = @prop_data.settings.included_files(@version_name).map { _1.downcase }
  @property_aliases_file_name = "propertyaliases"
  @property_value_aliases_file_name = "propertyvaluealiases"
end

Instance Attribute Details

#cache_pathObject

Returns the value of attribute cache_path.



592
593
594
# File 'lib/uniprop/unicode_elements.rb', line 592

def cache_path
  @cache_path
end

#directoryObject

Returns the value of attribute directory.



592
593
594
# File 'lib/uniprop/unicode_elements.rb', line 592

def directory
  @directory
end

#excluded_directoriesObject (readonly)

Returns the value of attribute excluded_directories.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def excluded_directories
  @excluded_directories
end

#excluded_extensionsObject (readonly)

Returns the value of attribute excluded_extensions.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def excluded_extensions
  @excluded_extensions
end

#excluded_filesObject (readonly)

Returns the value of attribute excluded_files.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def excluded_files
  @excluded_files
end

#included_filesObject (readonly)

Returns the value of attribute included_files.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def included_files
  @included_files
end

#majorObject (readonly)

Returns the value of attribute major.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def major
  @major
end

#minorObject (readonly)

Returns the value of attribute minor.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def minor
  @minor
end

#prop_dataObject (readonly)

Returns the value of attribute prop_data.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def prop_data
  @prop_data
end

#property_aliases_file_nameObject (readonly)

Returns the value of attribute property_aliases_file_name.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def property_aliases_file_name
  @property_aliases_file_name
end

#property_value_aliases_file_nameObject (readonly)

Returns the value of attribute property_value_aliases_file_name.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def property_value_aliases_file_name
  @property_value_aliases_file_name
end

#tinyObject (readonly)

Returns the value of attribute tiny.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def tiny
  @tiny
end

#unicode_betaObject (readonly)

Returns the value of attribute unicode_beta.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def unicode_beta
  @unicode_beta
end

#version_nameObject (readonly)

Returns the value of attribute version_name.



593
594
595
# File 'lib/uniprop/unicode_elements.rb', line 593

def version_name
  @version_name
end

Class Method Details

.name_to_weight(version_name) ⇒ Integer

バージョン名からweightを算出

Parameters:

  • version_name (String)

Returns:

  • (Integer)


626
627
628
629
# File 'lib/uniprop/unicode_elements.rb', line 626

def self.name_to_weight(version_name)
  parsed_version_name = parse(version_name)
  parsed_version_name[:major]*10000 + parsed_version_name[:minor]*100 + parsed_version_name[:tiny]
end

.parse(version_name) ⇒ Hash<Symbol,Integer>

バージョン名を対応するx.y.z形式に変換する

Parameters:

  • version_name (String)

Returns:

  • (Hash<Symbol,Integer>)

    Symbolはmajor,minor,tiny



612
613
614
615
616
617
618
619
620
621
# File 'lib/uniprop/unicode_elements.rb', line 612

def self.parse(version_name)
  case version_name
  when /^(\d+)\.(\d+)\.(\d+)$/,  /^(\d+)\.(\d+)-Update(\d+)$/
    return {major: $1.to_i, minor: $2.to_i, tiny: $3.to_i}
  when /^(\d+)\.(\d+)-Update$/
    return {major: $1.to_i, minor: $2.to_i, tiny: 0}
  else
    raise ParseError
  end
end

Instance Method Details

#<=>(other) ⇒ Object



994
# File 'lib/uniprop/unicode_elements.rb', line 994

def <=>(other)  weight <=> other.weight  end

#cache_files(reconfirm: false, since: true, reload: false) ⇒ Set<PropFile>

Note:

キャッシュに該当するディレクトリが存在しない場合、空のSetが返る

キャッシュに保存されているファイルを取得

Parameters:

  • reconfirm (Boolean) (defaults to: false)

    unicode.orgにアクセスし、キャッシュのファイルを全て最新バージョンに更新する

  • reload (Boolean) (defaults to: false)

    trueの場合、メモ化した値を使用せず、キャッシュを再読み込みする

Returns:



668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
# File 'lib/uniprop/unicode_elements.rb', line 668

def cache_files(reconfirm: false, since: true, reload: false)
  return @cache_files if @cache_files && !reconfirm && !reload

  # キャッシュを最新バージョンに更新
  if reconfirm
    cache_files(since: since).each { download_file(_1.basename_prefix, since: since)}
  end

  # Unihan.zipを展開
  UniPropUtils::FileManager.recursive_unzip(file_cache_paths)

  @cache_files = Set.new

  file_cache_paths.each do |path|
    # 4.1.0ではUnihan.zipの中のUnihan.txtと、そうでないUnihan.txtが存在し、ファイルの内容は同一
    # そのような場合に対処するため、basename_prefixが同一のPropFileオブジェクトが既に作成されている場合、オブジェクトの作成を行わない
    next if @cache_files.any? { _1.basename_prefix==UniPropUtils::FileManager.prefix(path) }

    propfile = create_propfile(path)
    @cache_files << propfile if propfile
  end

  @cache_files
end

#convert_property(content) ⇒ Property?/Array<Property?>

contentを対応するPropertyオブジェクトに変換して返す。対応するPropertyオブジェクトが無い場合にはnilを返す。contentがArrayの場合、再帰的に変換を実行。

Parameters:

  • content (String/Array<String>)

Returns:



927
928
929
930
931
932
933
# File 'lib/uniprop/unicode_elements.rb', line 927

def convert_property(content)
  if content.class==Array
    return content.map { convert_property(_1) }
  else
    return find_property(content) rescue nil
  end
end

#create_propfile(path) ⇒ PropFile

settings.rbの内容を考慮しながらPathnameオブジェクトからPropFileオブジェクトを作成

Parameters:

  • file_path (Pathname)

Returns:



703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
# File 'lib/uniprop/unicode_elements.rb', line 703

def create_propfile(path)
  return if UniPropUtils::FileManager.ext_no_dot(path).downcase != "txt" 
  
  # pathがPropertyAliases.txt, PropertyValueAliases.txtの場合、それらのクラスのインスタンスをreturn
  if UniPropUtils::FileManager.prefix(path).downcase == property_aliases_file_name
    return property_aliases_file
  elsif UniPropUtils::FileManager.prefix(path).downcase == property_value_aliases_file_name
    return property_value_aliases_file
  
  # UnihanのファイルにはUnihanFileのインスタンスをreturn
  elsif UniPropUtils::FileManager.unihan_file?(path, unihan_file_names)
    return PropFile::UnihanFile.new(path, self)
  else
    return PropFile.new(path, self)
  end
end

#download_file(file_name, since: true) ⇒ Object

ファイル名を指定してversionのファイルをダウンロード

Parameters:

  • file_name (String)

    Unicodeファイルのbasename_prefixに一致するファイル名



638
639
640
641
642
643
644
645
# File 'lib/uniprop/unicode_elements.rb', line 638

def download_file(file_name, since: true)
  if UniPropUtils::FileManager.unihan_file?(file_name)
    UniPropUtils::DownloaderWrapper.download_unihan(version_name, cache_path.parent, unicode_beta: unicode_beta, since: since)
    UniPropUtils::FileManager.recursive_unzip(file_cache_paths)
  else
    UniPropUtils::DownloaderWrapper.unicode_basename_download(file_name, version_name, cache_path.parent, unicode_beta: unicode_beta, since: since)
  end
end

#download_version_files(since: true) ⇒ Object

Versionに含まれるファイルのうち、settings.rbの記述に一致するファイルを全件unicode.orgからダウンロード



632
633
634
# File 'lib/uniprop/unicode_elements.rb', line 632

def download_version_files(since: true)
  UniPropUtils::DownloaderWrapper.download_version(version_name, cache_path.parent, excluded_extensions, excluded_directories, excluded_files, included_files, unicode_beta: unicode_beta, since: since)
end

#file_cache_pathsArray<Pathname>

Note:

プログラム実行中にキャッシュの内容は変更されるため、メモ化は行わず、都度探索を行う

cache_pathに保存されているファイルのうち、settings.rbで使用する事にされているファイルのパスを取得

Returns:

  • (Array<Pathname>)


696
697
698
# File 'lib/uniprop/unicode_elements.rb', line 696

def file_cache_paths
  UniPropUtils::FileManager.filter_file(cache_path.glob('**/*'), excluded_extensions, excluded_directories, excluded_files, included_files)
end

#files(reconfirm: false, since: true, reload: false) ⇒ Set<PropFile>

Versionに含まれるPropFile一覧を取得する

Parameters:

  • reconfirm (Boolean) (defaults to: false)

    unicode.orgからファイルをダウンロードする処理は最初の1回のみ行われ、2回目以降はローカルキャッシュを参照するが、reconfirm==trueの場合、ローカルキャッシュの参照は行わず、再度unicode.orgからファイルをダウンロードする。

Returns:



650
651
652
653
654
655
656
657
658
659
660
661
# File 'lib/uniprop/unicode_elements.rb', line 650

def files(reconfirm: false, since: true, reload: false)
  if @files && !reconfirm && !reload
    return @files
  end

  if !cache_path.exist? || reconfirm
    download_version_files(since: since)
  end

  @files = cache_files(since: since, reload: reload)
  @files
end

#find_cache_file_path(file_name) ⇒ Pathname

file_nameに対応するファイルのキャッシュのパスを取得

Parameters:

  • file_name (String)

    Unicodeファイルのprefixに一致するファイル名

Returns:

  • (Pathname)

    file_nameに対応するキャッシュのローカルのパス

Raises:

  • (FileNotFoundError)

    ファイルがキャッシュに存在しない場合発生



724
725
726
727
728
729
730
731
732
# File 'lib/uniprop/unicode_elements.rb', line 724

def find_cache_file_path(file_name)
  path = file_cache_paths.find { Alias.canonical(UniPropUtils::FileManager.prefix(_1)) == Alias.canonical(file_name) }

  if path
    return path
  else
    raise(FileNotFoundError, "#{file_name} has not yet been downloaded.")
  end
end

#find_file(propfile, confirm: true) ⇒ PropFile

ファイル名/ファイルパスを指定してバージョン内のPropFileオブジェクトを取得

Parameters:

  • propfile (String/Pathname)
  • confirm (Boolean) (defaults to: true)

    trueの場合、ファイルが存在しない際にUnicode.orgからのダウンロードを試みる

Returns:

Raises:



746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
# File 'lib/uniprop/unicode_elements.rb', line 746

def find_file(propfile, confirm: true)
  if propfile.class==String
    file = files.find { |f| Alias.canonical(f.basename_prefix) == Alias.canonical(UniPropUtils::FileManager.prefix(propfile)) }
  elsif propfile.class==Pathname
    file = files.find { |f| f==propfile }
  end
  
  if file
    return file
  else
    if confirm==true
      if propfile.class==Pathname
        propfile = propfile.basename
      end
      download_file(UniPropUtils::FileManager.prefix(propfile))
      # ダウンロード後、キャッシュを再読み込みして再度検索を行う
      files(reload: true)
      return find_file(propfile, confirm: false)
    end

    raise(FileNotFoundError, "#{propfile} is not found.")
  end
end

#find_property(property) ⇒ Property

Version内に存在する、property_nameをaliasとして持つPropertyオブジェクトを取得

Parameters:

Returns:

Raises:



870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
# File 'lib/uniprop/unicode_elements.rb', line 870

def find_property(property)
  if property.class==String
    prop = properties.find { _1.has_alias?(property) }
  elsif property.class==Property
    # エイリアス名が長いほど、正しい答えを得られる可能性が高い
    # エイリアス名が短いほど、複数のプロパティが同じエイリアス名を持っている可能性が高い
    property.aliases.sort_by{ _1.size }.reverse_each do |prop_alias|
      return find_property(prop_alias) if has_property?(prop_alias)
    end
  end
  
  if prop
    return prop
  else
    raise PropertyNotFoundError.new(property)
  end
end

#find_unihan_property(property) ⇒ Property

Parameters:

  • property_name (String)
  • property (String/Property)

Returns:

Raises:



899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
# File 'lib/uniprop/unicode_elements.rb', line 899

def find_unihan_property(property)
  if property.class==String
    prop = unihan_properties.find { _1.has_alias?(property) }
  elsif property.class==Property
    # エイリアス名が長いほど、正しい答えを得られる可能性が高い
    # エイリアス名が短いほど、複数のプロパティが同じエイリアス名を持っている可能性が高い
    property.aliases.sort_by{ _1.size }.reverse_each do |prop_alias|
      return find_unihan_property(prop_alias) if has_unihan_property?(prop_alias)
    end
  end
  
  if prop
    return prop
  else
    raise PropertyNotFoundError.new(property)
  end
end

#has_cache_file?(file_name) ⇒ Boolean

キャッシュにfile_nameが表すファイルが存在するかを判定

Returns:

  • (Boolean)


735
736
737
738
739
# File 'lib/uniprop/unicode_elements.rb', line 735

def has_cache_file?(file_name)
  return !!find_cache_file_path(file_name)
rescue
  false
end

#has_file?(propfile) ⇒ Boolean

Parameters:

  • propfile (String/Pathname)

Returns:

  • (Boolean)


771
772
773
774
775
# File 'lib/uniprop/unicode_elements.rb', line 771

def has_file?(propfile)
  !!find_file(propfile)
rescue
  false
end

#has_property?(prop) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


889
890
891
892
893
# File 'lib/uniprop/unicode_elements.rb', line 889

def has_property?(prop)
  !!find_property(prop)
rescue
  false
end

#has_unihan?Boolean

Returns:

  • (Boolean)


838
839
840
# File 'lib/uniprop/unicode_elements.rb', line 838

def has_unihan?
  unihan_files.size!=0
end

#has_unihan_property?(property) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


918
919
920
921
922
# File 'lib/uniprop/unicode_elements.rb', line 918

def has_unihan_property?(property)
  !!find_unihan_property(property)
rescue
  false
end

#has_version_metadata?Boolean

Returns:

  • (Boolean)


967
968
969
970
971
# File 'lib/uniprop/unicode_elements.rb', line 967

def has_version_metadata?
  !!
rescue
  false
end

#inspectObject



12
13
14
# File 'lib/uniprop/inspects.rb', line 12

def inspect
  "#<#{self.class.name} #{major}.#{minor}.#{tiny}>"
end

#properties(exclude_unihan: false) ⇒ Set<Property>

Note:

exclude_unihan==falseの場合であっても、PropertyAliasesに記述されていないUnihanのプロパティは取得されない

PropertyAliasesに記述されているProperty一覧を取得

Parameters:

  • exclude_unihan (Boolean) (defaults to: false)

    trueの場合、Unihanのプロパティを除外

Returns:



817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
# File 'lib/uniprop/unicode_elements.rb', line 817

def properties(exclude_unihan: false)
  if !@properties
    @properties = Set.new

    # PropertyAliasesをもとに、全プロパティのPropertyオブジェクトを作成
    property_aliases_file.property_value_type_to_shaped_lines.each do |property_value_type, shaped_lines|
      shaped_lines.each do |shaped_line|
        new_prop = Property.new(self, *shaped_line)
        new_prop.property_value_type = property_value_type.downcase
        @properties << new_prop
      end
    end
  end

  if exclude_unihan
    return @properties - unihan_properties
  else
    return @properties + unihan_properties
  end
end

#property_aliases_filePropertyAliases

ProeprtyAliasesに該当するPropFileを取得

Returns:

  • (PropertyAliases)


779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
# File 'lib/uniprop/unicode_elements.rb', line 779

def property_aliases_file
  return @property_aliases_file if @property_aliases_file

  if !has_cache_file?(property_aliases_file_name)
    download_file(property_aliases_file_name)
  end

  property_aliases_file_path = find_cache_file_path(property_aliases_file_name)
    
  if property_aliases_file_path
    @property_aliases_file = PropFile::PropertyAliases.new(property_aliases_file_path, self)
  end

  @property_aliases_file
end

#property_to_miscellaneous_formatsHash<Property,Hash<Symbol,String>>

Note:

settings.rbに定義が無いプロパティをキーに指定すると、空のハッシュを返す

settings.rbのPROPERTIES_INFORMATIONのmiscellaneous_formatsを、Propertyオブジェクトをキーとして整理する

Returns:



976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
# File 'lib/uniprop/unicode_elements.rb', line 976

def property_to_miscellaneous_formats
  return @property_to_miscellaneous_formats if @property_to_miscellaneous_formats
  @property_to_miscellaneous_formats = Hash.new { |hash,key| hash[key]={} }

  properties.each do |prop|
    prop.uncanonicaled_aliases.each do |als|
      fmt = prop_data.settings.miscellaneous_format(version_name, als)

      if fmt
        @property_to_miscellaneous_formats[prop] = fmt
        break
      end
    end
  end

  @property_to_miscellaneous_formats
end

#property_to_property_valuesHash<Property, Array<PropertyValue>>

Returns:



853
854
855
856
857
858
859
860
861
862
863
864
# File 'lib/uniprop/unicode_elements.rb', line 853

def property_to_property_values
  return @property_to_property_values if @property_to_property_values

  @property_to_property_values = Hash.new { |hash, key| hash[key]=[] }

  property_value_aliases_file.netto_shaped_lines.each do |shaped_line|
    prop = find_property(shaped_line[0])
    @property_to_property_values[prop] << PropertyValue.new(prop, *shaped_line[1..])
  end

  @property_to_property_values
end

#property_value_aliases_filePropertyValueAliases

ProeprtyValueAliasesに該当するPropFileを取得

Returns:

  • (PropertyValueAliases)


797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
# File 'lib/uniprop/unicode_elements.rb', line 797

def property_value_aliases_file
  return @property_value_aliases_file if @property_value_aliases_file

  if !has_cache_file?(property_value_aliases_file_name)
    download_file(property_value_aliases_file_name)
  end

  property_value_aliases_file_path = find_cache_file_path(property_value_aliases_file_name)
    
  if property_value_aliases_file_path
    @property_value_aliases_file = PropFile::PropertyAliases.new(property_value_aliases_file_path, self)
  end

  @property_value_aliases_file
end

#unihan_file_namesArray<String>?

Returns settings.rbに記述されているUnihanファイル名.

Returns:

  • (Array<String>?)

    settings.rbに記述されているUnihanファイル名



941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
# File 'lib/uniprop/unicode_elements.rb', line 941

def unihan_file_names
  return @unihan_file_names if @unihan_file_names

  # キャッシュにUnihanファイルが無い場合、ダウンロードを試みる
  if file_cache_paths.all? { !UniPropUtils::FileManager.unihan_file?(_1) }
    begin
      UniPropUtils::DownloaderWrapper.download_unihan(version_name, cache_path.parent)
      UniPropUtils::FileManager.recursive_unzip(file_cache_paths)
    rescue FileNotFoundError
      # Unicode.orgの対象バージョンにもUnihan.zip, Unihan.txtが存在しない場合(FileNotFoundError)は処理を継続
      # downloader.rbに関する例外などはrescueしない
    end
  end

  @unihan_file_names = Set.new
  file_cache_paths.each { @unihan_file_names << UniPropUtils::FileManager.prefix(_1) if UniPropUtils::FileManager.unihan_file?(_1) }
  @unihan_file_names = @unihan_file_names.to_a
  @unihan_file_names
end

#unihan_filesArray<Property>

Returns Versionに含まれるUnihanファイル.

Returns:

  • (Array<Property>)

    Versionに含まれるUnihanファイル



936
937
938
# File 'lib/uniprop/unicode_elements.rb', line 936

def unihan_files
  @unihan_files ||= files.filter { _1.is_unihan_file? }
end

#unihan_propertiesObject

return [Array<Property>]



848
849
850
# File 'lib/uniprop/unicode_elements.rb', line 848

def unihan_properties
  unihanprop.unihan_properties
end

#unihanpropUnihanProp

Returns:



843
844
845
# File 'lib/uniprop/unicode_elements.rb', line 843

def unihanprop
  @unihanprop ||= UnihanProp.new(unihan_files)
end

#version_metadataVersionMetadata

Returns:

  • (VersionMetadata)

Raises:

  • (MetadataNotFoundError)

    Versionに対応するメタデータが存在しない場合に発生



963
964
965
# File 'lib/uniprop/unicode_elements.rb', line 963

def 
  @version_metadata ||= VersionMetaData.new(self, prop_data..(version_name))
end

#weightObject



996
# File 'lib/uniprop/unicode_elements.rb', line 996

def weight()  major*10000 + minor*100 + tiny  end