Class: UniProp::PropData

Inherits:
Object
  • Object
show all
Defined in:
lib/uniprop/inspects.rb,
lib/uniprop/propdata.rb,
lib/uniprop/metadata_generator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(settings_path, metadata_path = nil) ⇒ PropData

Note:

VersionMetaDataRecreator#output_metadata_revising_hintsなど、2つ以上のメタデータを使用して処理を行う場合がある。そのような場合に対応するため、PropDataは1つのsettings.rbと1つのメタデータを使用し、Unicodeのファイル全体を扱うためのクラスとした。

Returns a new instance of PropData.



7
8
9
10
11
12
# File 'lib/uniprop/propdata.rb', line 7

def initialize(settings_path, =nil)
  @settings = Settings.new(settings_path)
  cache_path_str = ENV["UniPropCache"] || @settings.cache_path
  @cache_path = Pathname.new(cache_path_str).cleanpath.expand_path
  @metadata_path = 
end

Instance Attribute Details

#cache_pathObject

Returns the value of attribute cache_path.



4
5
6
# File 'lib/uniprop/propdata.rb', line 4

def cache_path
  @cache_path
end

#excluded_directoriesObject (readonly)

Returns the value of attribute excluded_directories.



3
4
5
# File 'lib/uniprop/propdata.rb', line 3

def excluded_directories
  @excluded_directories
end

#excluded_extensionsObject (readonly)

Returns the value of attribute excluded_extensions.



3
4
5
# File 'lib/uniprop/propdata.rb', line 3

def excluded_extensions
  @excluded_extensions
end

#excluded_filesObject (readonly)

Returns the value of attribute excluded_files.



3
4
5
# File 'lib/uniprop/propdata.rb', line 3

def excluded_files
  @excluded_files
end

#metadata_pathObject (readonly)

Returns the value of attribute metadata_path.



3
4
5
# File 'lib/uniprop/propdata.rb', line 3

def 
  @metadata_path
end

#settingsObject

Returns the value of attribute settings.



4
5
6
# File 'lib/uniprop/propdata.rb', line 4

def settings
  @settings
end

Instance Method Details

#efficient_metadataEfficientMetadata

Returns:

  • (EfficientMetadata)

Raises:

  • (MetaDataNotFoundError)

    PropDataのinitialize時にmetadata_pathを指定していない場合に発生



95
96
97
98
99
100
101
102
103
104
# File 'lib/uniprop/propdata.rb', line 95

def 
  return @efficient_metadata if @efficient_metadata

  if 
    @efficient_metadata = EfficientMetaData.new(self, )
    return @efficient_metadata
  else
    raise(MetaDataNotFoundError, "This PropData object doesn't have metadata path.")
  end
end

#file_correspondence(version1, version2) ⇒ Hash<PropFile, PropFile>

version1とversion2の間で、ファイル名(basename_prefix)が同じPropFileのハッシュを作成

Parameters:

  • version1 (Version)

    キーとされるバージョン

  • version2 (Version)

    値とされるバージョン

Returns:



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/uniprop/propdata.rb', line 115

def file_correspondence(version1, version2)
  return @file_correspondences[version1][version2] if @file_correspondences&&@file_correspondences[version1]&&@file_correspondences[version1][version2]

  propfile_to_same_name_propfile = {}
  version1.files.each do |f1|
    version2.files.each do |f2|
      if Alias.canonical(f1.basename_prefix)==Alias.canonical(f2.basename_prefix)
        propfile_to_same_name_propfile[f1] = f2
        break # 1つのバージョン内にbasename_prefixが同じファイルは2つ以上無いので、1つ見つかった段階でbreakする
      end
    end
  end

  @file_correspondences ||= {}
  @file_correspondences[version1] ||= {}
  @file_correspondences[version1][version2] = propfile_to_same_name_propfile

  @file_correspondences[version1][version2]
end

#find_efficient_version(version_name) ⇒ EfficientVersion

Returns:



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/uniprop/propdata.rb', line 33

def find_efficient_version(version_name)
  weight = Version.name_to_weight(version_name)
  @weight_to_efficient_version ||= {}
  return @weight_to_efficient_version[weight] if @weight_to_efficient_version[weight]

  if .version_names.map { Version.name_to_weight(_1) }.include?(weight)
    @weight_to_efficient_version[weight] = EfficientVersion.new(self, version_name)
  else
    raise VersionNotMatchedError, "version #{version_name} is not exists"
  end

  @weight_to_efficient_version[weight]
end

#find_version(version_name, reconfirm: true) ⇒ Version

Parameters:

  • version_name (String)
  • reconfirm (Boolean) (defaults to: true)

    trueの場合、version_nameに対応するバージョンが見つからない時にバージョン一覧を取得する

Returns:



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/uniprop/propdata.rb', line 50

def find_version(version_name, reconfirm: true)
  parsed_version_name = Version.parse(version_name)
      
  versions.each do |version|
    if version.major == parsed_version_name[:major] && version.minor == parsed_version_name[:minor] && version.tiny == parsed_version_name[:tiny] 
      return version
    end
  end

  # 一致するバージョンが見つからなかった場合
  if reconfirm
    versions(update: true) # バージョン一覧を更新
    find_version(version_name, reconfirm: false)
  else
    raise VersionNotMatchedError
  end
end

#generate_metadata(output_path, using_version, generated_version) ⇒ Object

メタデータを生成する

Parameters:

  • output_path (Pathname)

    メタデータを生成するパス

  • generated_version (Version)

    作成するメタデータのバージョン

  • using_version (Version/EfficientVersion)

    generated_versionのメタデータの生成に使用されるバージョン

Raises:

  • (FileExistsError)

    pathに既にファイルが存在している場合に発生。生成されたメタデータを修正した後に再度メソッドを実行してしまい、メタデータが上書きされる事を防ぐための措置。

  • (MetaDataExistsError)

    generated_versionのメタデータが既に存在する場合に発生



9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/uniprop/metadata_generator.rb', line 9

def (output_path, using_version, generated_version)
  if output_path.exist?
    raise FileExistsError.new(output_path)
  end

   = {}
  ["version_names"] = .version_names
  ["version_metadatas"] = .raw_version_metadatas
  ["version_metadatas"] << (using_version, generated_version)

  ["version_metadatas"].sort_by! { Version.name_to_weight(_1["version_name"]) }
  
  output_path.write(JSON.pretty_generate())
end

#generate_prop_property_metadata(version, property) ⇒ Hash<String,Object>

プロパティに関するメタデータを生成

Parameters:

Returns:

  • (Hash<String,Object>)

    プロパティに関するメタデータ



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/uniprop/metadata_generator.rb', line 84

def (version, property)
   = {}
  ["property_name"] = property.longest_alias
  
  ["positions"] = []
  positions = property.actual_positions.to_a
  
  positions.each do |position|
    ["positions"] << {
      "file_name" => position.propfile.basename_prefix,
      "block" => position.block,
      "range" => position.range.to_s,
      "columns" => position.columns.size==1 ? position.columns[0] : position.columns
    }
  end

  ["unihan"] = property.is_unihan_property?
  ["type"] = property.property_value_type.to_s
  ["derived"] = positions.any? { _1.propfile.is_derived? }
  
  
end

#generate_property_metadata(output_path, version) ⇒ Object

PropDataオブジェクト作成時に渡したメタデータを使用し、プロパティ中心のメタデータを生成

Parameters:

  • version (EfficientVersion)

    生成するバージョン

  • output_path (Pathname)

    メタデータを生成するパス



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/uniprop/metadata_generator.rb', line 53

def (output_path, version)
  if .has_raw_version_metadata?(version.version_name)
    return
  end

  md = .raw_version_metadatas

  if .has_raw_version_metadata?(version.version_name)
    puts "generating property metadata for #{version.version_name} ... "
    md << (version)
  else
    raise MetaDataNotFoundError, "metadata for #{version.version_name} is not found."
  end

  output_path.write(JSON.pretty_generate(md))
end

#generate_version_metadata(using_version, generated_version) ⇒ Hash<String,Object>

Returns version_metadataに相当するHash.

Returns:

  • (Hash<String,Object>)

    version_metadataに相当するHash



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/uniprop/metadata_generator.rb', line 25

def (using_version, generated_version)
  if using_version.prop_data != generated_version.prop_data
    raise PropDataDifferentError, "Unable to recreate metadata because the PropData objects of two versions passed when initialized are different."
  end

  prop_data = using_version.prop_data

  if prop_data..has_raw_version_metadata?(generated_version.version_name)
    raise MetaDataExistsError.new(generated_version.version_name)
  end

  recreator = VersionMetaDataRecreator.new(using_version, generated_version)

   = {}
  ["version_name"] = generated_version.version_name
  ["file_formats"] = recreator.generate_file_formats

  if generated_version.has_unihan?
    ["unihan_files"] = generated_version.unihanprop.unihan_files.map { _1.basename_prefix }
    ["unihan_properties"] = generated_version.unihanprop.unihan_properties.map { _1.longest_alias }
  end

  
end

#generate_vsn_property_metadata(version) ⇒ Hash<String,Object>

バージョン内のすべてのプロパティに対し、プロパティ中心のメタデータを生成

Parameters:

Returns:

  • (Hash<String,Object>)

    versionのプロパティ中心のメタデータ



73
74
75
76
77
78
# File 'lib/uniprop/metadata_generator.rb', line 73

def (version)
   = {}
  ["version_name"] = version.version_name
  ["properties"] = version.properties.map { (version, _1) }
  
end

#has_metadata?Boolean

PropDataがメタデータに紐づけられているかを判定

Returns:

  • (Boolean)


107
108
109
# File 'lib/uniprop/propdata.rb', line 107

def has_metadata?
  !! rescue false
end

#inspectObject



77
78
79
# File 'lib/uniprop/inspects.rb', line 77

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

#latest_versionVersion

versionsのうち、最も新しいバージョンを取得

Returns:



76
77
78
# File 'lib/uniprop/propdata.rb', line 76

def latest_version
  versions.sort_by { _1.weight } .last
end

#metadataMetadata

Returns:

  • (Metadata)

Raises:

  • (MetaDataNotFoundError)

    PropDataのinitialize時にmetadata_pathを指定していない場合に発生



82
83
84
85
86
87
88
89
90
91
# File 'lib/uniprop/propdata.rb', line 82

def 
  return @metadata if @metadata

  if 
    @metadata = MetaData.new(self, )
    return @metadata
  else
    raise(MetaDataNotFoundError, "This PropData object doesn't have metadata path.")
  end
end

#oldest_versionVersion

vesionsのうち、最も古いバージョンを取得

Returns:



70
71
72
# File 'lib/uniprop/propdata.rb', line 70

def oldest_version
  versions.sort_by { _1.weight } .first
end

#property_metadata(path = nil) ⇒ PropertyMetadata

Note:

pathが指定されていない場合、メタデータの先頭にproperty_をつけたファイルを使用

Parameters:

  • path (Pathname) (defaults to: nil)

Returns:

  • (PropertyMetadata)

Raises:



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/uniprop/propdata.rb', line 176

def (path=nil)
  return @property_metadata if @property_metadata

  select_path = !!path
  path ||= .parent / ("property_"+.basename.to_s)

  if !path.exist?
    if select_path
      raise MetaDataNotFoundError, "#{path} is not found."
    else
      path.write([])
    end
  end

  @property_metadata = PropertyMetaData.new(self, path)
end

#unicode_managerUnicodeManager

Returns:



147
148
149
# File 'lib/uniprop/propdata.rb', line 147

def unicode_manager
  @unicode_manager ||= UnicodeManager.new(self)
end

#update_metadata(new_metadata) ⇒ Object

metadata_pathのファイルをnew_metadataの内容に上書き

Parameters:

  • new_metadata (Array/Hash)

    JSONとして解釈できるオブジェクト

Raises:



138
139
140
141
142
143
144
# File 'lib/uniprop/propdata.rb', line 138

def ()
  if  && .exist?
    .write(JSON.pretty_generate())
  else
    raise MetaDataNotFoundError
  end
end

#version_manager(version_name) ⇒ VersionManager

Parameters:

  • version_name (String)

Returns:



153
154
155
156
157
# File 'lib/uniprop/propdata.rb', line 153

def version_manager(version_name)
  vm = version_managers.find { _1.version.weight==Version.name_to_weight(version_name) }
  
  vm || raise(MetaDataNotFoundError, "MetaData for #{version_name} is not found.")
end

#version_managersArray<VersionManager>

メタデータに含まれる全バージョンのVersionManagerを作成

Returns:



161
162
163
164
165
166
167
168
169
170
# File 'lib/uniprop/propdata.rb', line 161

def version_managers
  return @version_managers if @version_managers
  
  @version_managers = .version_names
                        .filter { .has_raw_version_metadata?(_1) }
                        .map { find_efficient_version(_1) }
                        .map { VersionManager.new(_1) }

  @version_managers
end

#versions(update: false) ⇒ Set<Version>

Note:

メタデータが紐づけられていればその情報を使用し、紐づけられていなければUnicode.orgから情報を取得

unicode.orgから存在するバージョンの一覧を取得し、それを元にVersionオブジェクトを作成する

Parameters:

  • update (Boolean) (defaults to: false)

    trueの場合バージョン一覧を再取得

Returns:



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/uniprop/propdata.rb', line 18

def versions(update: false)
  return @versions if @versions && !update

  @versions = Set.new

  if has_metadata?
    .version_names(update_metadata: true, confirm: update).each { @versions << Version.new(self, _1) }
  else
    UniPropUtils::DownloaderWrapper.get_version_names.each { @versions << Version.new(self, _1) }
  end

  @versions
end