diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..9eb31f35 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + - package-ecosystem: bundler + directory: "/" + schedule: + interval: weekly diff --git a/.github/workflows/assets.yml b/.github/workflows/assets.yml index 39c128e6..1ec6e948 100644 --- a/.github/workflows/assets.yml +++ b/.github/workflows/assets.yml @@ -13,30 +13,31 @@ jobs: BUNDLE_WITHOUT: "secryst:jsexec" SKIP_JS: "1" steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Checkout monorepo + uses: actions/checkout@v7 with: repository: interscript/interscript - - name: Run bootstrap script + - name: Bootstrap packages run: ruby bootstrap.rb - - name: Use Ruby + - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: "3.0" + ruby-version: "3.3" bundler-cache: true + working-directory: ruby - name: Install bundle - working-directory: ./ruby + working-directory: ruby run: bundle install --jobs 4 --retry 3 --with jsexec --without secryst - - name: Generate visualization json - working-directory: ./ruby + - name: Generate visualization JSON + working-directory: ruby run: bundle exec rake generate_visualization_json - - name: Archive json files from the previous step - uses: thedoctor0/zip-release@master + - name: Archive visualization JSON + uses: thedoctor0/zip-release@v0.7.6 with: filename: 'vis_json.zip' path: ./vis_json/*.json @@ -44,9 +45,9 @@ jobs: exclusions: '*.git*' type: zip - - name: Upload artifacts + - name: Upload visualization artifact id: upload_vis_json - uses: svenstaro/upload-release-action@2.2.1 + uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ruby/vis_json.zip @@ -55,11 +56,11 @@ jobs: overwrite: true - name: Generate metadata - working-directory: ./ruby + working-directory: ruby run: bundle exec rake generate_metadata_json - - name: Archive metadata from the previous step - uses: thedoctor0/zip-release@master + - name: Archive metadata + uses: thedoctor0/zip-release@v0.7.6 with: filename: 'metadata.zip' path: ./metadata.json @@ -69,7 +70,7 @@ jobs: - name: Upload metadata id: upload_metadata - uses: svenstaro/upload-release-action@2.2.1 + uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} file: ruby/metadata.zip @@ -77,15 +78,7 @@ jobs: tag: ${{ github.ref }} overwrite: true - - name: Output link + - name: Output links run: | echo ${{ steps.upload_vis_json.outputs.browser_download_url }} echo ${{ steps.upload_metadata.outputs.browser_download_url }} - -# - name: Trigger deploy at interscript.org -# uses: peter-evans/repository-dispatch@v1 -# with: -# token: ${{ secrets.INTERSCRIPT_CI_TOKEN }} -# repository: interscript/interscript.org -# event-type: ${{ github.repository }} -# client-payload: '{ "ref": "${{ github.ref }}" }' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 00000000..8be16966 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,27 @@ +name: codeql + +on: + push: + branches: [main] + pull_request: + schedule: + - cron: "0 0 * * 0" # weekly + +permissions: + actions: read + contents: read + security-events: write + +jobs: + analyze: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + language: [ruby] + steps: + - uses: actions/checkout@v7 + - uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + - uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/rake.yml b/.github/workflows/rake.yml index 6a789f3e..b52b40da 100644 --- a/.github/workflows/rake.yml +++ b/.github/workflows/rake.yml @@ -8,36 +8,50 @@ on: jobs: rspec: - name: Test on Ruby ${{ matrix.ruby }} ${{ matrix.os }} + name: Test on Ruby ${{ matrix.ruby }} / ${{ matrix.os }} runs-on: ${{ matrix.os }} - continue-on-error: true strategy: fail-fast: false matrix: - ruby: [ 3.3, 3.2, 3.1, "3.0", 2.7, 2.6 ] - os: [ ubuntu-latest, windows-latest, macos-latest ] + ruby: ["3.3", "3.4"] + os: [ubuntu-latest, windows-latest, macos-latest] env: BUNDLE_WITHOUT: "secryst" SKIP_JS: "1" steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Checkout monorepo + uses: actions/checkout@v7 with: repository: interscript/interscript - - name: Run bootstrap script + - name: Bootstrap packages run: ruby bootstrap.rb - - name: Use Ruby + - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true + working-directory: ruby - - name: Run RSpecs - working-directory: ./ruby + - name: Install Python helper and gems + working-directory: ruby run: | pip install regex bundle install --with=jsexec - bundle exec rspec + + - name: RSpec + working-directory: ruby + run: bundle exec rspec + + standard: + name: StandardRB + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.4" + bundler-cache: true + - run: bundle exec standardrb diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d8de6a2e..76279b00 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,60 +9,45 @@ jobs: release: runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Checkout monorepo + uses: actions/checkout@v7 with: repository: interscript/interscript - - name: Run bootstrap script + - name: Bootstrap packages run: ruby bootstrap.rb - uses: ruby/setup-ruby@v1 with: - ruby-version: '3.0' + ruby-version: '3.3' + bundler-cache: true + working-directory: ruby - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v7 with: - node-version: 14.x + node-version: '22' + cache: npm + cache-dependency-path: js/package-lock.json - # For now let's install without secryst, as we don't necessarily need it. - # We may need to change it once we start to depend on secryst maps. - - name: Install bundle - working-directory: ./ruby + - name: Install gems + working-directory: ruby run: bundle install --jobs 4 --retry 3 --with jsexec --without secryst - name: Test Ruby package - working-directory: ./ruby + working-directory: ruby run: bundle exec rake - name: Test JS package - working-directory: ./js + working-directory: js run: npm install && npm run prepareMaps && npm test - name: Publish to rubygems.org env: - RUBYGEMS_API_KEY: ${{secrets.INTERSCRIPT_RUBYGEMS_API_KEY}} + RUBYGEMS_API_KEY: ${{ secrets.INTERSCRIPT_RUBYGEMS_API_KEY }} + working-directory: ruby run: | - gem install gem-release mkdir -p ~/.gem - touch ~/.gem/credentials - cat > ~/.gem/credentials << EOF - --- - :rubygems_api_key: ${RUBYGEMS_API_KEY} - EOF + printf -- "---\n:rubygems_api_key: %s\n" "$RUBYGEMS_API_KEY" > ~/.gem/credentials chmod 0600 ~/.gem/credentials - pushd ruby - git status + gem install gem-release gem release - popd - - # Let's keep it commented out for now. Please uncomment it once you are ready with - # interscript-api to support Interscript v2. - # - #- name: Trigger interscript-api - # uses: peter-evans/repository-dispatch@v1 - # with: - # token: ${{ secrets.INTERSCRIPT_CI_PAT_TOKEN }} - # repository: interscript/interscript-api - # event-type: ${{ github.repository }} - # client-payload: '{ "ref": "${{ github.ref }}" }' diff --git a/.standard.yml b/.standard.yml new file mode 100644 index 00000000..98e956f1 --- /dev/null +++ b/.standard.yml @@ -0,0 +1,11 @@ +# StandardRB config — enforce Ruby style on lib/, leave specs/bin/exe flexible for now. +# Existing violations in lib/ were auto-fixed in this PR; remaining violations are +# tracked in TODO.complete/06-standardrb-ruby-gems.md. +ignore: + - "bin/**/*" + - "exe/**/*" + - "spec/**/*" + - "docs/**/*" + - "reference-docs/**/*" + - "pkg/**/*" + - "vendor/**/*" diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..86c162cd --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +All notable changes to this project are documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [Latest] + +See GitHub releases for detailed release notes: https://github.com/interscript/interscript-ruby/releases diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..388ac39f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,42 @@ +# Contributing + +Thanks for your interest in contributing! + +## Development setup + +```bash +git clone +cd +bundle install # Ruby projects +# or +npm ci # JS projects +``` + +## Workflow + +1. Fork → branch from `main` +2. Make changes with tests +3. Run `bundle exec rspec` (Ruby) or `npm test` (JS) locally +4. Run `bundle exec standardrb` (Ruby) or `npm run lint` (JS) +5. Open a PR with a clear description + +## Code style + +- Ruby: enforced by [StandardRB](https://github.com/standardrb/standard) +- JavaScript: enforced by ESLint + Prettier +- Python: enforced by ruff + +## Commit messages + +Use [Conventional Commits](https://www.conventionalcommits.org/): + +``` +feat: add new transliteration system +fix: correct off-by-one in CALT lookup +chore: bump dependencies +docs: clarify README +``` + +## Releases + +Maintainers tag releases following semver. CI publishes on tag push. diff --git a/Gemfile b/Gemfile index cf4f70d5..906c6f5c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,44 +1,41 @@ source "https://rubygems.org" -# Specify your gem's dependencies in interscript.gemspec gemspec -gem "rake", "~> 12.0" -gem "rspec", "~> 3.0" +gem "rake", "~> 13.0" +gem "rspec", "~> 3.13" gem "interscript-maps", path: "../maps" -unless Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.7") - group :secryst do - if File.exist? "../../secryst" - gem "secryst", path: "../../secryst" - else - gem "secryst" - end +group :secryst do + if File.exist?("../../secryst") + gem "secryst", path: "../../secryst" + else + gem "secryst" end end -gem 'regexp_parser' +gem "regexp_parser" unless ENV["SKIP_JS"] group :jsexec do - gem 'mini_racer' + gem "mini_racer" end end unless ENV["SKIP_PYTHON"] group :pyexec do - gem 'pycall' + gem "pycall" end end group :rababa do - gem 'rababa', "~> 0.1.1" + gem "rababa", "~> 0.1.1" end -gem 'pry' +gem "pry" +gem "iso-639-data" +gem "iso-15924" -gem 'iso-639-data' -gem 'iso-15924' - -gem 'simplecov', require: false, group: :test +gem "simplecov", require: false, group: :test +gem "standard", group: :development, require: false diff --git a/README.md b/README.md index 5f31b89b..cddf8812 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +image:https://github.com/interscript/interscript-ruby/actions/workflows/rake.yml/badge.svg["CI status", link="https://github.com/interscript/interscript-ruby/actions/workflows/rake.yml"] # Interscript Documentation is available directory higher in file README.adoc. diff --git a/Rakefile b/Rakefile index e5ed34b3..ef60206b 100644 --- a/Rakefile +++ b/Rakefile @@ -25,15 +25,15 @@ task :compile, [:compiler, :target] do |t, args| maps = Interscript.maps maps = Interscript.exclude_maps(maps, compiler: compiler, platform: false) - + maps.each do |map| - code = compiler.(map).code + code = compiler.call(map).code File.write(args[:target] + "/" + map + "." + ext, code) maplist[map] = nil end Interscript.maps(libraries: true).each do |map| - code = compiler.(map).code + code = compiler.call(map).code File.write(args[:target] + "/" + map + "." + ext, code) end @@ -45,12 +45,12 @@ task :generate_visualization_html do require "interscript" require "interscript/visualize" - FileUtils.rm_rf(dir = __dir__+"/visualizations/") + FileUtils.rm_rf(dir = __dir__ + "/visualizations/") FileUtils.mkdir_p(dir) Interscript.maps.each do |map| - html = Interscript::Visualize.(map) - File.write(dir+map+".html", html) + html = Interscript::Visualize.call(map) + File.write(dir + map + ".html", html) end end @@ -60,16 +60,15 @@ task :generate_metadata_json do require "interscript" require "interscript/compiler/javascript" - FileUtils.rm_rf(file = __dir__+"/metadata.json") + FileUtils.rm_rf(file = __dir__ + "/metadata.json") hash = Interscript.maps.map do |map| parsed_map = Interscript.parse(map) md = parsed_map.metadata.to_hash md["test"] = parsed_map.tests&.data&.first md["skip_js"] = Interscript.exclude_maps([map], - compiler: Interscript::Compiler::Javascript, - platform: false, - ).empty? + compiler: Interscript::Compiler::Javascript, + platform: false).empty? [map, md] end.to_h @@ -81,12 +80,12 @@ task :generate_json do require "json" require "interscript" - FileUtils.rm_rf(dir = __dir__+"/json/") + FileUtils.rm_rf(dir = __dir__ + "/json/") FileUtils.mkdir_p(dir) (Interscript.maps + Interscript.maps(libraries: true)).each do |map| json = JSON.pretty_generate(Interscript.parse(map).to_hash) - File.write(dir+map+".json", json) + File.write(dir + map + ".json", json) end end @@ -96,14 +95,14 @@ task :generate_visualization_json do require "json" require "interscript/visualize" - FileUtils.rm_rf(dir = __dir__+"/vis_json/") + FileUtils.rm_rf(dir = __dir__ + "/vis_json/") FileUtils.mkdir_p(dir) (Interscript.maps + Interscript.maps(libraries: true)).each do |map_name| map = Interscript.parse(map_name) map.stages.each do |stage_name, stage| json = JSON.pretty_generate(stage.to_visualization_array(map)) - File.write(dir+map_name+"_#{stage_name}.json", json) + File.write(dir + map_name + "_#{stage_name}.json", json) end end end @@ -113,7 +112,7 @@ task :generate_authority_json do require "json" require "iso-639-data" - FileUtils.rm_rf(dir = __dir__+"/auth_json/") + FileUtils.rm_rf(dir = __dir__ + "/auth_json/") FileUtils.mkdir_p(dir) %w[iso icao din].each do |auth| @@ -122,10 +121,10 @@ task :generate_authority_json do end.sort.map do |map_name| map = Interscript.parse(map_name) tests = map.tests&.data&.first(2)&.transpose || [] - std, lang = map.metadata.data[:language].split(':') + std, lang = map.metadata.data[:language].split(":") { - lang: std.end_with?("-3") ? Iso639Data.iso_639_3[lang]['Ref_Name'] : Iso639Data.iso_639_2[lang]['eng'], + lang: std.end_with?("-3") ? Iso639Data.iso_639_3[lang]["Ref_Name"] : Iso639Data.iso_639_2[lang]["eng"], isoName: map.metadata.data[:name], systemName: map_name, samples: tests[0] || [], @@ -135,8 +134,8 @@ task :generate_authority_json do end json = JSON.pretty_generate(out) - File.write(dir+auth+".json", json) + File.write(dir + auth + ".json", json) end end -task :default => :spec +task default: :spec diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..4c1f49be --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Security Policy + +## Supported Versions + +The latest released version of this project receives security fixes. + +## Reporting a Vulnerability + +Please **do not** open public GitHub issues for security vulnerabilities. + +Report privately via one of: + +- **GitHub Security Advisories** — Security tab → "Report a vulnerability" (preferred) +- **Email** — open.source@ribose.com + +We acknowledge reports within 72 hours and aim to ship a fix within 30 days for critical issues. Coordinated disclosure is supported. + +## Disclosure + +Public disclosure happens after a fix is released, on a timeline agreed with the reporter. diff --git a/exe/interscript b/exe/interscript index 061b1844..26d3c4ee 100755 --- a/exe/interscript +++ b/exe/interscript @@ -1,3 +1,4 @@ +#!/usr/bin/env ruby require 'interscript/command' if ARGV.any? && !Interscript::Command.all_tasks.key?(ARGV.first) diff --git a/interscript.gemspec b/interscript.gemspec index f52349fc..e07e6ef8 100644 --- a/interscript.gemspec +++ b/interscript.gemspec @@ -1,32 +1,38 @@ -require_relative 'lib/interscript/version' +require_relative "lib/interscript/version" Gem::Specification.new do |spec| - spec.name = "interscript" - spec.version = Interscript::VERSION - spec.summary = %q{Interoperable script conversion systems} - spec.description = %q{Interoperable script conversion systems} - spec.authors = ["Ribose Inc."] - spec.email = ["open.source@ribose.com"] + spec.name = "interscript" + spec.version = Interscript::VERSION + spec.summary = "Interoperable script conversion systems" + spec.description = "Interoperable script conversion systems." + spec.authors = ["Ribose Inc."] + spec.email = ["open.source@ribose.com"] - spec.date = %q{2019-11-17} - spec.homepage = "https://www.interscript.com" - spec.license = "BSD-2-Clause" - - spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0") + spec.homepage = "https://www.interscript.com" + spec.license = "BSD-2-Clause" + spec.required_ruby_version = ">= 3.3.0" spec.metadata["homepage_uri"] = spec.homepage - spec.metadata["source_code_uri"] = "https://github.com/interscript/interscript" + spec.metadata["source_code_uri"] = "https://github.com/interscript/interscript-ruby" + spec.metadata["changelog_uri"] = "https://github.com/interscript/interscript-ruby/releases" + spec.metadata["bug_tracker_uri"] = "https://github.com/interscript/interscript-ruby/issues" + spec.metadata["rubygems_mfa_required"] = "true" - # Specify which files should be added to the gem when it is released. - # The `git ls-files -z` loads the files in the RubyGem that have been added into git. - spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do - `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + spec.files = Dir.chdir(__dir__) do + Dir[ + "lib/**/*", + "exe/**/*", + "docs/**/*", + "README*", + "LICENSE*", + "*.gemspec" + ].select { |f| File.file?(f) } end - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] spec.add_dependency "thor" - spec.add_dependency "interscript-maps", "~> #{Interscript::VERSION.split('.')[0,2].join(".")}.0a" + spec.add_dependency "interscript-maps", "~> #{Interscript::VERSION.split(".")[0, 2].join(".")}.0a" spec.add_dependency "text" end diff --git a/lib/interscript.rb b/lib/interscript.rb index 21c9c2fc..cada6920 100644 --- a/lib/interscript.rb +++ b/lib/interscript.rb @@ -13,7 +13,7 @@ class MapLogicError < StandardError; end class << self def load_path - @load_path ||= ['.', *Interscript.map_locations] + @load_path ||= [".", *Interscript.map_locations] end def locate map_name @@ -33,26 +33,26 @@ def parse(map_name) Interscript::DSL.parse(map_name) end - def load(system_code, maps={}, compiler: Interscript::Interpreter) - maps[[system_code, compiler.name]] ||= compiler.(system_code) + def load(system_code, maps = {}, compiler: Interscript::Interpreter) + maps[[system_code, compiler.name]] ||= compiler.call(system_code) end # Transliterates the string. - def transliterate(system_code, string, maps={}, compiler: Interscript::Interpreter) + def transliterate(system_code, string, maps = {}, compiler: Interscript::Interpreter) # The current best implementation is Interpreter - load(system_code, maps, compiler: compiler).(string) + load(system_code, maps, compiler: compiler).call(string) end # Gives each possible value of the transliteration. - def transliterate_each(system_code, string, maps={}, &block) - load(system_code, maps).(string, each: true, &block) + def transliterate_each(system_code, string, maps = {}, &block) + load(system_code, maps).call(string, each: true, &block) end - def transliterate_file(system_code, input_file, output_file, maps={}, compiler: Interscript::Interpreter) + def transliterate_file(system_code, input_file, output_file, maps = {}, compiler: Interscript::Interpreter) input = File.read(input_file) output = transliterate(system_code, input, maps, compiler: compiler) - File.open(output_file, 'w') do |f| + File.open(output_file, "w") do |f| f.puts(output) end @@ -67,17 +67,17 @@ def transliterate_file(system_code, input_file, output_file, maps={}, compiler: def detect(source, destination, **kwargs) detector = Detector.new detector.set_from_kwargs(**kwargs) - detector.(source, destination) + detector.call(source, destination) end def map_gems - @map_gems ||= Gem.find_latest_files('interscript-maps.yaml').map do |i| + @map_gems ||= Gem.find_latest_files("interscript-maps.yaml").map do |i| [i, YAML.load_file(i)] end.to_h end def map_locations - @map_locations ||= map_gems.map do |i,v| + @map_locations ||= map_gems.map do |i, v| paths = v["paths"].dup paths += v["staging"] if ENV["INTERSCRIPT_STAGING"] && v["staging"] @@ -88,15 +88,15 @@ def map_locations end def secryst_index_locations - @secryst_index_locations ||= map_gems.map do |i,v| + @secryst_index_locations ||= map_gems.map do |i, v| v["secryst-models"] end.compact.flatten end def rababa_configs - @rababa_configs ||= map_gems.map do |i,v| + @rababa_configs ||= map_gems.map do |i, v| v["rababa-configs"] - end.compact.inject({}) do |a,b| + end.compact.inject({}) do |a, b| a.merge(b) end end @@ -104,8 +104,8 @@ def rababa_configs # This code is borrowed from Secryst and should end up in Rababa, but for now, # let's keep it here. def rababa_provision(model_name, model_uri) - require 'fileutils' - require 'open-uri' + require "fileutils" + require "open-uri" # We provision the environment in the following way: # First, we try the RABABA_DATA environment variable. If that's available, @@ -129,18 +129,18 @@ def rababa_provision(model_name, model_uri) break rescue end - + raise ExternalUtilError, "Can't find a writable path for Rababa. Consider setting a RABABA_DATA environment variable" unless write_path model_path = "#{write_path}/model-#{model_name}.onnx" # Redownload every hour if File.exist?(model_path) && File.mtime(model_path) + 3600 >= Time.now - return model_path + model_path else data = URI.open(model_uri, encoding: "BINARY").read File.binwrite(model_path, data) - return model_path + model_path end end @@ -148,7 +148,7 @@ def map_aliases return @map_aliases if @map_aliases @map_aliases = {} - map_gems.each do |i,v| + map_gems.each do |i, v| (v["aliases"] || {}).each do |code, value| value.each do |al, map| @map_aliases[al] = map["alias_to"] @@ -172,9 +172,9 @@ def maps(basename: true, load_path: false, select: "*", libraries: false) # To be used by tests # and builders. It uses the `skip` directive in interscript-maps.yaml def exclude_maps(maps, compiler:, platform: true) - map_gems.each do |i,v| + map_gems.each do |i, v| [compiler.name, (Gem::Platform.local.os if platform)].compact.each do |name| - skips = v.dig('skip', name) || [] + skips = v.dig("skip", name) || [] skips.each do |skip| skip_re = /#{Regexp.escape(skip).gsub("\\*", ".*?")}/ maps = maps.grep_v(skip_re) @@ -186,12 +186,12 @@ def exclude_maps(maps, compiler:, platform: true) end end -require 'interscript/stdlib' +require "interscript/stdlib" require "interscript/compiler" require "interscript/interpreter" -require 'interscript/dsl' -require 'interscript/node' +require "interscript/dsl" +require "interscript/node" -require 'interscript/detector' +require "interscript/detector" diff --git a/lib/interscript/command.rb b/lib/interscript/command.rb index aa017e27..10ecfad7 100644 --- a/lib/interscript/command.rb +++ b/lib/interscript/command.rb @@ -1,25 +1,25 @@ -require 'thor' -require 'interscript' -require 'json' +require "thor" +require "interscript" +require "json" module Interscript # Command line interface class Command < Thor - desc '', 'Transliterate text' - option :system, aliases: '-s', required: true, desc: 'Transliteration system' - option :output, aliases: '-o', required: false, desc: 'Output file' - option :compiler, aliases: '-c', required: false, desc: 'Compiler (eg. Interscript::Compiler::Python)' + desc "", "Transliterate text" + option :system, aliases: "-s", required: true, desc: "Transliteration system" + option :output, aliases: "-o", required: false, desc: "Output file" + option :compiler, aliases: "-c", required: false, desc: "Compiler (eg. Interscript::Compiler::Python)" # Was this option really well thought out? The last parameter is a cache, isn't it? - #option :map, aliases: '-m', required: false, default: "{}", desc: 'Transliteration mapping json' + # option :map, aliases: '-m', required: false, default: "{}", desc: 'Transliteration mapping json' def translit(input) compiler = if options[:compiler] - compiler = options[:compiler].split("::").last.downcase - require "interscript/compiler/#{compiler}" - Object.const_get(options[:compiler]) - else - Interscript::Interpreter - end + compiler = options[:compiler].split("::").last.downcase + require "interscript/compiler/#{compiler}" + Object.const_get(options[:compiler]) + else + Interscript::Interpreter + end if options[:output] Interscript.transliterate_file(options[:system], input, options[:output], compiler: compiler) @@ -28,14 +28,14 @@ def translit(input) end end - desc 'list', 'Prints allowed transliteration systems' + desc "list", "Prints allowed transliteration systems" def list Interscript.maps(load_path: true).each do |path| puts path end end - desc 'stats', 'Prints statistics about the maps we have' + desc "stats", "Prints statistics about the maps we have" def stats maps = Interscript.maps(load_path: true) parsed_maps = maps.map { |i| [i, Interscript.parse(i)] }.to_h @@ -44,7 +44,7 @@ def stats end authorities, languages, source_scripts, target_scripts = 4.times.map do |i| - maps.group_by { |map| map.split('-')[i] } + maps.group_by { |map| map.split("-")[i] } end puts <<~END diff --git a/lib/interscript/compiler/javascript.rb b/lib/interscript/compiler/javascript.rb index 07a79ed4..eae07204 100644 --- a/lib/interscript/compiler/javascript.rb +++ b/lib/interscript/compiler/javascript.rb @@ -1,9 +1,9 @@ begin - require 'mini_racer' + require "mini_racer" rescue LoadError # Ignore loading error end -require 'json' +require "json" class Interscript::Compiler::Javascript < Interscript::Compiler def compile(map, debug: false) @@ -12,24 +12,23 @@ def compile(map, debug: false) @parallel_regexps = {} @debug = debug c = "var map = function(Interscript) {" - c << "Interscript.define_map(#{map.name.inspect}, function(Interscript, map) {\n"; + c << "Interscript.define_map(#{map.name.inspect}, function(Interscript, map) {\n" c << "map.dependencies = #{map.dependencies.map(&:full_name).to_json};\n" - c map.aliases.each do |name, value| val = compile_item(value.data, map, :str) c << "map.aliases.#{name} = #{val};\n" - val = '"'+compile_item(value.data, map, :re)+'"' + val = '"' + compile_item(value.data, map, :re) + '"' c << "map.aliases_re.#{name} = #{val};\n" end map.stages.each do |_, stage| c << compile_rule(stage, @map, true) end - @parallel_trees.each do |k,v| + @parallel_trees.each do |k, v| c << "map.cache.PTREE_#{k} = #{v.to_json};\n" end - @parallel_regexps.each do |k,v| + @parallel_regexps.each do |k, v| v = "[\"#{v[0]}\", #{v[1].to_json}]" c << "map.cache.PRE_#{k} = #{v};\n" end @@ -44,10 +43,10 @@ def compile(map, debug: false) def parallel_regexp_compile(subs_hash) # puts subs_hash.inspect - regexp = subs_hash.each_with_index.map do |p,i| - "(?<_%d>%s)" % [i,p[0]] + subs_hash.each_with_index.map do |p, i| + "(?<_%d>%s)" % [i, p[0]] end.join("|") - subs_regexp = regexp + # puts subs_regexp.inspect end @@ -90,7 +89,7 @@ def compile_rule(r, map = @map, wrapper = false) a = [] Interscript::Stdlib.deterministic_sort_by_max_length(r.children).each do |i| raise Interscript::SystemConversionError, "Can't parallelize #{i.class}" unless Interscript::Node::Rule::Sub === i - + next if i.reverse_run == true a << [build_regexp(i, map), compile_item(i.to, map, :parstr)] end @@ -102,13 +101,13 @@ def compile_rule(r, map = @map, wrapper = false) c += "s = Interscript.parallel_regexp_gsub(s, map.cache.PRE_#{ah});\n" end when Interscript::Node::Rule::Sub - from = %{"#{build_regexp(r, map).gsub("/", "\\\\/")}"} - if r.to == :upcase - to = 'function(a){return a.toUpperCase();}' + from = %("#{build_regexp(r, map).gsub("/", "\\\\/")}") + to = if r.to == :upcase + "function(a){return a.toUpperCase();}" elsif r.to == :downcase - to = 'function(a){return a.toLowerCase();}' + "function(a){return a.toLowerCase();}" else - to = compile_item(r.to, map, :str) + compile_item(r.to, map, :str) end c += "s = Interscript.gsub(s, #{from}, #{to});\n" when Interscript::Node::Rule::Funcall @@ -127,7 +126,7 @@ def compile_rule(r, map = @map, wrapper = false) c end - def build_regexp(r, map=@map) + def build_regexp(r, map = @map) from = compile_item(r.from, map, :re) before = compile_item(r.before, map, :re) if r.before after = compile_item(r.after, map, :re) if r.after @@ -144,7 +143,7 @@ def build_regexp(r, map=@map) re end - def compile_item i, doc=@map, target=nil + def compile_item i, doc = @map, target = nil i = i.first_string if %i[str parstr].include? target i = Interscript::Node::Item.try_convert(i) if target == :parstr @@ -152,7 +151,7 @@ def compile_item i, doc=@map, target=nil target = :par end - out = case i + case i when Interscript::Node::Item::Alias astr = if i.map d = doc.dep_aliases[i.map].document @@ -173,14 +172,14 @@ def compile_item i, doc=@map, target=nil end if target == :str - astr = astr.sub("_ALIASTYPE(", "(") + astr.sub("_ALIASTYPE(", "(") elsif target == :re - astr = %{"+#{astr.sub("_ALIASTYPE(", "_re(")}+"} + %("+#{astr.sub("_ALIASTYPE(", "_re(")}+") elsif parstr && stdlib_alias - astr = Interscript::Stdlib::ALIASES[i.name] + Interscript::Stdlib::ALIASES[i.name] elsif target == :par # raise NotImplementedError, "Can't use aliases in parallel mode yet" - astr = Interscript::Stdlib::ALIASES[i.name] + Interscript::Stdlib::ALIASES[i.name] end when Interscript::Node::Item::String if target == :str @@ -195,7 +194,7 @@ def compile_item i, doc=@map, target=nil if target == :par i.children.map do |j| compile_item(j, doc, target) - end.reduce([""]) do |j,k| + end.reduce([""]) do |j, k| Array(j).product(Array(k)).map(&:join) end elsif target == :str @@ -212,9 +211,9 @@ def compile_item i, doc=@map, target=nil Interscript::Node::Item::MaybeSome, Interscript::Node::Item::Some - resuffix = { Interscript::Node::Item::Maybe => "?" , - Interscript::Node::Item::Some => "+" , - Interscript::Node::Item::MaybeSome => "*" }[i.class] + resuffix = {Interscript::Node::Item::Maybe => "?", + Interscript::Node::Item::Some => "+", + Interscript::Node::Item::MaybeSome => "*"}[i.class] if target == :par raise Interscript::SystemConversionError, "Can't use a MaybeSome in a #{target} context" @@ -241,7 +240,7 @@ def compile_item i, doc=@map, target=nil case i.value when Array data = i.data.map { |j| compile_item(j, doc, target) } - "(?:"+data.join("|")+")" + "(?:" + data.join("|") + ")" when String "[#{Regexp.escape(i.value)}]" when Range @@ -270,28 +269,28 @@ def load ctx = self.class.ctx unless ctx ctx = MiniRacer::Context.new - ctx.eval File.read(__dir__+"/../../../../js/test-compiler/xregexp.js") + ctx.eval File.read(__dir__ + "/../../../../js/test-compiler/xregexp.js") # Compatibility with Safari: will come later - #ctx.eval File.read(__dir__+"/../../../js/xregexp-oniguruma.js") - ctx.eval File.read(__dir__+"/../../../../js/src/stdlib.js") + # ctx.eval File.read(__dir__+"/../../../js/xregexp-oniguruma.js") + ctx.eval File.read(__dir__ + "/../../../../js/src/stdlib.js") self.class.ctx = ctx end - #puts @code + # puts @code ctx.eval @code self.class.maps_loaded[@map.name] = true end end - def call(str, stage=:main) + def call(str, stage = :main) load self.class.ctx.eval "Interscript.transliterate(#{@map.name.to_json}, #{str.to_json}, #{stage.to_json})" end def self.read_debug_data - self.ctx.eval "globalThis.map_debug || []" + ctx.eval "globalThis.map_debug || []" end def self.reset_debug_data - self.ctx.eval "globalThis.map_debug = []" + ctx.eval "globalThis.map_debug = []" end end diff --git a/lib/interscript/compiler/python.rb b/lib/interscript/compiler/python.rb index 13722091..37705ad2 100644 --- a/lib/interscript/compiler/python.rb +++ b/lib/interscript/compiler/python.rb @@ -1,4 +1,4 @@ -require 'pycall' +require "pycall" class Interscript::Compiler::Python < Interscript::Compiler def escape(val) @@ -8,9 +8,9 @@ def escape(val) when Symbol val.to_s.inspect when Hash - "{"+ - val.map { |k,v| "#{escape k}:#{escape v}" }.join(",")+ - "}" + "{" + + val.map { |k, v| "#{escape k}:#{escape v}" }.join(",") + + "}" when Array "[" + val.map { |i| escape i }.join(",") + "]" when nil @@ -66,21 +66,21 @@ def compile(map, debug: false) map.stages.each do |_, stage| compile_rule(stage, @map, true) end - @parallel_trees.each do |k,v| + @parallel_trees.each do |k, v| emit "_PTREE_#{k} = #{escape v}" end - @parallel_regexps.each do |k,v| - v = %{["#{v[0]}", #{escape v[1]}]} + @parallel_regexps.each do |k, v| + v = %(["#{v[0]}", #{escape v[1]}]) emit "_PRE_#{k} = #{v}" end end def parallel_regexp_compile(subs_hash) # puts subs_hash.inspect - regexp = subs_hash.each_with_index.map do |p,i| - "(?P<_%d>%s)" % [i,p[0]] + subs_hash.each_with_index.map do |p, i| + "(?P<_%d>%s)" % [i, p[0]] end.join("|") - subs_regexp = regexp + # puts subs_regexp.inspect end @@ -139,12 +139,12 @@ def compile_rule(r, map = @map, wrapper = false) end when Interscript::Node::Rule::Sub from = new_regexp build_regexp(r, map) - if r.to == :upcase - to = 'interscript.stdlib.upper' + to = if r.to == :upcase + "interscript.stdlib.upper" elsif r.to == :downcase - to = 'interscript.stdlib.lower' + "interscript.stdlib.lower" else - to = compile_item(r.to, map, :str) + compile_item(r.to, map, :str) end emit "s = #{from}.sub(#{to}, s)" when Interscript::Node::Rule::Funcall @@ -162,7 +162,7 @@ def compile_rule(r, map = @map, wrapper = false) end end - def build_regexp(r, map=@map) + def build_regexp(r, map = @map) from = compile_item(r.from, map, :re) before = compile_item(r.before, map, :re) if r.before after = compile_item(r.after, map, :re) if r.after @@ -178,7 +178,7 @@ def build_regexp(r, map=@map) re end - def compile_item i, doc=@map, target=nil + def compile_item i, doc = @map, target = nil i = i.first_string if %i[str parstr].include? target i = Interscript::Node::Item.try_convert(i) if target == :parstr @@ -186,7 +186,7 @@ def compile_item i, doc=@map, target=nil target = :par end - out = case i + case i when Interscript::Node::Item::Alias astr = if i.map d = doc.dep_aliases[i.map].document @@ -207,14 +207,14 @@ def compile_item i, doc=@map, target=nil end if target == :str - astr = astr.sub("_ALIASTYPE(", "(") + astr.sub("_ALIASTYPE(", "(") elsif target == :re - astr = "\"+#{astr.sub("_ALIASTYPE(", "_re(")}+\"" + "\"+#{astr.sub("_ALIASTYPE(", "_re(")}+\"" elsif parstr && stdlib_alias - astr = Interscript::Stdlib::ALIASES[i.name] + Interscript::Stdlib::ALIASES[i.name] elsif target == :par # raise NotImplementedError, "Can't use aliases in parallel mode yet" - astr = Interscript::Stdlib::ALIASES[i.name] + Interscript::Stdlib::ALIASES[i.name] end when Interscript::Node::Item::String if target == :str @@ -229,7 +229,7 @@ def compile_item i, doc=@map, target=nil if target == :par i.children.map do |j| compile_item(j, doc, target) - end.reduce([""]) do |j,k| + end.reduce([""]) do |j, k| Array(j).product(Array(k)).map(&:join) end elsif target == :str @@ -246,9 +246,9 @@ def compile_item i, doc=@map, target=nil Interscript::Node::Item::MaybeSome, Interscript::Node::Item::Some - resuffix = { Interscript::Node::Item::Maybe => "?" , - Interscript::Node::Item::Some => "+" , - Interscript::Node::Item::MaybeSome => "*" }[i.class] + resuffix = {Interscript::Node::Item::Maybe => "?", + Interscript::Node::Item::Some => "+", + Interscript::Node::Item::MaybeSome => "*"}[i.class] if target == :par raise Interscript::SystemConversionError, "Can't use a Maybe in a #{target} context" @@ -275,7 +275,7 @@ def compile_item i, doc=@map, target=nil case i.value when Array data = i.data.map { |j| compile_item(j, doc, target) } - "(?:"+data.join("|")+")" + "(?:" + data.join("|") + ")" when String "[#{re_escape(i.value)}]" when Range @@ -302,13 +302,17 @@ def load end ctx = self.class.ctx - python_src_path = File.join(__dir__, '..', '..', '..', '..', 'python', 'src') + python_src_path = File.join(__dir__, "..", "..", "..", "..", "python", "src") unless ctx PyCall.sys.path.append(python_src_path) self.class.ctx = PyCall.import_module("interscript") end - #puts @code - Dir.mkdir("#{python_src_path}/interscript/maps") rescue nil + # puts @code + begin + Dir.mkdir("#{python_src_path}/interscript/maps") + rescue + nil + end File.write("#{python_src_path}/interscript/maps/#{@map.name}.py", @code) self.class.ctx.load_map(@map.name) @@ -316,16 +320,16 @@ def load end end - def call(str, stage=:main) + def call(str, stage = :main) load self.class.ctx.transliterate(@map.name, str, stage.to_s) end def self.read_debug_data - (ctx['map_debug'] || []).map(&:to_a).to_a + (ctx["map_debug"] || []).map(&:to_a).to_a end def self.reset_debug_data - ctx['map_debug'].clear + ctx["map_debug"].clear end end diff --git a/lib/interscript/compiler/ruby.rb b/lib/interscript/compiler/ruby.rb index dcdefcdf..5c672dfe 100644 --- a/lib/interscript/compiler/ruby.rb +++ b/lib/interscript/compiler/ruby.rb @@ -19,22 +19,21 @@ def compile(map, debug: false) c << "def self.get_alias_re(map,name); @maps[map].aliases_re[name]; end\n" c << "def self.transliterate(map,string,stage=:main); @maps[map].stages[stage].(string); end\n" c << "end; end; end\n" - c map.aliases.each do |name, value| val = compile_item(value.data, map, :str) c << "Interscript::Maps.add_map_alias(#{map.name.inspect}, #{name.inspect}, #{val})\n" - val = '/'+compile_item(value.data, map, :re).gsub('/', '\\\\/')+'/' + val = "/" + compile_item(value.data, map, :re).gsub("/", '\\\\/') + "/" c << "Interscript::Maps.add_map_alias_re(#{map.name.inspect}, #{name.inspect}, #{val})\n" end map.stages.each do |_, stage| c << compile_rule(stage, @map, true) end - @parallel_trees.each do |k,v| + @parallel_trees.each do |k, v| c << "Interscript::Maps::Cache::PTREE_#{k} ||= #{v.inspect}\n" end - @parallel_regexps.each do |k,v| + @parallel_regexps.each do |k, v| c << "Interscript::Maps::Cache::PRE_#{k} ||= #{v.inspect}\n" end @code = c @@ -51,7 +50,7 @@ def compile_rule(r, map = @map, wrapper = false) r.children.each do |t| comp = compile_rule(t, map) c += comp - c += %{$map_debug << [s.dup, #{@map.name.to_s.inspect}, #{r.name.to_s.inspect}, #{t.inspect.inspect}, #{comp.inspect}]\n} if @debug + c += %($map_debug << [s.dup, #{@map.name.to_s.inspect}, #{r.name.to_s.inspect}, #{t.inspect.inspect}, #{comp.inspect}]\n) if @debug end c += "s\n" c += "end\n" @@ -93,12 +92,12 @@ def compile_rule(r, map = @map, wrapper = false) end when Interscript::Node::Rule::Sub from = "/#{build_regexp(r, map).gsub("/", "\\\\/")}/" - if r.to == :upcase - to = '&:upcase' + to = if r.to == :upcase + "&:upcase" elsif r.to == :downcase - to = '&:downcase' + "&:downcase" else - to = compile_item(r.to, map, :str) + compile_item(r.to, map, :str) end c += "s.gsub!(#{from}, #{to})\n" when Interscript::Node::Rule::Funcall @@ -117,7 +116,7 @@ def compile_rule(r, map = @map, wrapper = false) c end - def build_regexp(r, map=@map) + def build_regexp(r, map = @map) from = compile_item(r.from, map, :re) before = compile_item(r.before, map, :re) if r.before after = compile_item(r.after, map, :re) if r.after @@ -133,7 +132,7 @@ def build_regexp(r, map=@map) re end - def compile_item i, doc=@map, target=nil + def compile_item i, doc = @map, target = nil i = i.first_string if %i[str parstr].include? target i = Interscript::Node::Item.try_convert(i) if target == :parstr @@ -141,7 +140,7 @@ def compile_item i, doc=@map, target=nil target = :par end - out = case i + case i when Interscript::Node::Item::Alias astr = if i.map d = doc.dep_aliases[i.map].document @@ -162,14 +161,14 @@ def compile_item i, doc=@map, target=nil end if target == :str - astr = astr.sub("_ALIASTYPE(", "(") + astr.sub("_ALIASTYPE(", "(") elsif target == :re - astr = "\#{#{astr.sub("_ALIASTYPE(", "_re(")}}" + "\#{#{astr.sub("_ALIASTYPE(", "_re(")}}" elsif parstr && stdlib_alias - astr = Interscript::Stdlib::ALIASES[i.name] + Interscript::Stdlib::ALIASES[i.name] elsif target == :par # raise NotImplementedError, "Can't use aliases in parallel mode yet" - astr = Interscript::Stdlib::ALIASES[i.name] + Interscript::Stdlib::ALIASES[i.name] end when Interscript::Node::Item::String if target == :str @@ -184,7 +183,7 @@ def compile_item i, doc=@map, target=nil if target == :par i.children.map do |j| compile_item(j, doc, target) - end.reduce([""]) do |j,k| + end.reduce([""]) do |j, k| Array(j).product(Array(k)).map(&:join) end elsif target == :str @@ -201,9 +200,9 @@ def compile_item i, doc=@map, target=nil Interscript::Node::Item::MaybeSome, Interscript::Node::Item::Some - resuffix = { Interscript::Node::Item::Maybe => "?" , - Interscript::Node::Item::Some => "+" , - Interscript::Node::Item::MaybeSome => "*" }[i.class] + resuffix = {Interscript::Node::Item::Maybe => "?", + Interscript::Node::Item::Some => "+", + Interscript::Node::Item::MaybeSome => "*"}[i.class] if target == :par raise Interscript::SystemConversionError, "Can't use a Maybe in a #{target} context" @@ -230,7 +229,7 @@ def compile_item i, doc=@map, target=nil case i.value when Array data = i.data.map { |j| compile_item(j, doc, target) } - "(?:"+data.join("|")+")" + "(?:" + data.join("|") + ")" when String "[#{Regexp.escape(i.value)}]" when Range @@ -252,7 +251,7 @@ def load end end - def call(str, stage=:main) + def call(str, stage = :main) load Interscript::Maps.transliterate(@map.name, str, stage) end diff --git a/lib/interscript/detector.rb b/lib/interscript/detector.rb index b22f43cf..2a209722 100644 --- a/lib/interscript/detector.rb +++ b/lib/interscript/detector.rb @@ -26,8 +26,8 @@ def initialize end def set_from_kwargs(**kwargs) - kwargs.each do |k,v| - self.public_send(:"#{k}=", v) + kwargs.each do |k, v| + public_send(:"#{k}=", v) end end @@ -41,8 +41,8 @@ def call(source, destination) [map, try_dest] end.map do |map, try_dest| - dist = @distance_computer.(try_dest, destination) - + dist = @distance_computer.call(try_dest, destination) + [map, dist] end.sort_by(&:last).to_h @@ -59,4 +59,4 @@ def call(source, destination) module DistanceComputer Levenshtein = Text::Levenshtein.method(:distance) end -end \ No newline at end of file +end diff --git a/lib/interscript/dsl.rb b/lib/interscript/dsl.rb index 60301454..c9a7e6c3 100644 --- a/lib/interscript/dsl.rb +++ b/lib/interscript/dsl.rb @@ -52,7 +52,7 @@ def self.parse(map_name, reverse: true) md_reading = false md_indent = nil - md_inner_indent = nil + nil file.each do |l| if md_reading && l =~ /\A#{md_indent}\}\s*\z/ md_reading = false @@ -73,7 +73,7 @@ def self.parse(map_name, reverse: true) obj = Interscript::DSL::Document.new(map_name) obj.instance_eval ruby, exc_fname, 1 - yaml = if yaml =~ /\A\s*\z/ + yaml = if /\A\s*\z/.match?(yaml) {} else unsafe_load = if YAML.respond_to? :unsafe_load @@ -85,7 +85,7 @@ def self.parse(map_name, reverse: true) end md = Interscript::DSL::Metadata.new(yaml: true, map_name: map_name, library: library) do - yaml.each do |k,v| + yaml.each do |k, v| public_send(k.to_sym, v) end end @@ -95,12 +95,12 @@ def self.parse(map_name, reverse: true) end end -require 'interscript/dsl/symbol_mm' -require 'interscript/dsl/items' +require "interscript/dsl/symbol_mm" +require "interscript/dsl/items" -require 'interscript/dsl/document' -require 'interscript/dsl/group' -require 'interscript/dsl/stage' -require 'interscript/dsl/metadata' -require 'interscript/dsl/tests' -require 'interscript/dsl/aliases' +require "interscript/dsl/document" +require "interscript/dsl/group" +require "interscript/dsl/stage" +require "interscript/dsl/metadata" +require "interscript/dsl/tests" +require "interscript/dsl/aliases" diff --git a/lib/interscript/dsl/aliases.rb b/lib/interscript/dsl/aliases.rb index da9c831f..f8cc91bf 100644 --- a/lib/interscript/dsl/aliases.rb +++ b/lib/interscript/dsl/aliases.rb @@ -5,7 +5,7 @@ class Interscript::DSL::Aliases def initialize(&block) @node = {} - self.instance_exec(&block) + instance_exec(&block) end def def_alias(name, value) diff --git a/lib/interscript/dsl/document.rb b/lib/interscript/dsl/document.rb index 89f35c98..60e4a486 100644 --- a/lib/interscript/dsl/document.rb +++ b/lib/interscript/dsl/document.rb @@ -6,7 +6,7 @@ class Interscript::DSL::Document def initialize(name = nil, &block) @node = Interscript::Node::Document.new @node.name = name if name - self.instance_exec &block if block_given? + instance_exec(&block) if block_given? end def metadata(&block) @@ -22,7 +22,10 @@ def tests(&block) def aliases(&block) aliases = Interscript::DSL::Aliases.new(&block) @node.aliases = aliases.node - @node.aliases.transform_values { |v| v.doc_name = @node.name; v } + @node.aliases.transform_values { |v| + v.doc_name = @node.name + v + } end def dependency(full_name, **kargs) @@ -38,7 +41,7 @@ def dependency(full_name, **kargs) end def stage(name = :main, dont_reverse: false, &block) - puts "stage(#{name}) from #{self.inspect}" if $DEBUG + puts "stage(#{name}) from #{inspect}" if $DEBUG stage = Interscript::DSL::Stage.new(name, &block) stage.node.doc_name = @node.name stage.node.dont_reverse = dont_reverse diff --git a/lib/interscript/dsl/group.rb b/lib/interscript/dsl/group.rb index 1283a16f..3c5da955 100644 --- a/lib/interscript/dsl/group.rb +++ b/lib/interscript/dsl/group.rb @@ -5,7 +5,7 @@ class Interscript::DSL::Group def initialize(&block) @node = Interscript::Node::Group.new - self.instance_exec(&block) + instance_exec(&block) end def run(stage, **kwargs) @@ -16,20 +16,27 @@ def run(stage, **kwargs) end def sub(from, to, **kwargs, &block) - puts "sub(#{from.inspect},#{to}, kwargs = #{ - kwargs.inspect - }) from #{self.inspect}" if $DEBUG + if $DEBUG + puts "sub(#{from.inspect},#{to}, kwargs = #{ + kwargs.inspect + }) from #{inspect}" + end rule = Interscript::Node::Rule::Sub.new(from, to, **kwargs) @node.children << rule end - def upcase; :upcase; end - def downcase; :downcase; end + def upcase + :upcase + end + + def downcase + :downcase + end Interscript::Stdlib.available_functions.each do |fun| define_method fun do |**kwargs| - puts "funcall(#{fun}, #{kwargs.inspect}) from #{self.inspect}" if $DEBUG + puts "funcall(#{fun}, #{kwargs.inspect}) from #{inspect}" if $DEBUG rule = Interscript::Node::Rule::Funcall.new(fun, **kwargs) @node.children << rule @@ -37,10 +44,10 @@ def downcase; :downcase; end end def parallel(**kwargs, &block) - puts "parallel(#{chars.inspect}) from #{self.inspect}" if $DEBUG + puts "parallel(#{chars.inspect}) from #{inspect}" if $DEBUG group = Interscript::DSL::Group::Parallel.new(**kwargs, &block) @node.children << group.node end end -require 'interscript/dsl/group/parallel' +require "interscript/dsl/group/parallel" diff --git a/lib/interscript/dsl/group/parallel.rb b/lib/interscript/dsl/group/parallel.rb index d19dbff3..6ffd660d 100644 --- a/lib/interscript/dsl/group/parallel.rb +++ b/lib/interscript/dsl/group/parallel.rb @@ -1,6 +1,6 @@ class Interscript::DSL::Group::Parallel < Interscript::DSL::Group def initialize(reverse_run: nil, &block) @node = Interscript::Node::Group::Parallel.new(reverse_run: reverse_run) - self.instance_exec(&block) + instance_exec(&block) end end diff --git a/lib/interscript/dsl/items.rb b/lib/interscript/dsl/items.rb index 6b80d64b..193f24c7 100644 --- a/lib/interscript/dsl/items.rb +++ b/lib/interscript/dsl/items.rb @@ -4,51 +4,55 @@ module Interscript::DSL::Items def method_missing sym, *args, **kwargs, &block super if args.length > 0 super if kwargs.length > 0 - super if sym.to_s =~ /[?!=]\z/ - super unless sym.to_s =~ /\A[\w\d]+\z/ + super if /[?!=]\z/.match?(sym.to_s) + super unless /\A[\w\d]+\z/.match?(sym.to_s) super if block_given? Interscript::Node::Item::Alias.new(sym) end def any(*chars) - puts "any(#{chars.inspect}) from #{self.inspect}" if $DEBUG + puts "any(#{chars.inspect}) from #{inspect}" if $DEBUG Interscript::Node::Item::Any.new(*chars) end # a? def maybe(*chars) - puts "maybe(#{chars.inspect}) from #{self.inspect}" if $DEBUG + puts "maybe(#{chars.inspect}) from #{inspect}" if $DEBUG Interscript::Node::Item::Maybe.new(*chars) end def maybe_some(*chars) - puts "maybe_some(#{chars.inspect}) from #{self.inspect}" if $DEBUG + puts "maybe_some(#{chars.inspect}) from #{inspect}" if $DEBUG Interscript::Node::Item::MaybeSome.new(*chars) end def some(*chars) - puts "some(#{chars.inspect}) from #{self.inspect}" if $DEBUG + puts "some(#{chars.inspect}) from #{inspect}" if $DEBUG Interscript::Node::Item::Some.new(*chars) end # (...) def capture(expr) - puts "capture(#{expr.inspect}) from #{self.inspect}" if $DEBUG + puts "capture(#{expr.inspect}) from #{inspect}" if $DEBUG Interscript::Node::Item::CaptureGroup.new(expr) end # \1 def ref(int) - puts "ref(#{int.inspect}) from #{self.inspect}" if $DEBUG + puts "ref(#{int.inspect}) from #{inspect}" if $DEBUG Interscript::Node::Item::CaptureRef.new(int) end # Implementation of `map.x` - def map; Interscript::DSL::Items::Maps; end + def map + Interscript::DSL::Items::Maps + end # Implementation of `stage.x` - def stage; Stages.new; end + def stage + Stages.new + end # Implementation of `map.x` module Maps @@ -58,32 +62,38 @@ def [] map Symbol === map or raise Interscript::MapLogicError, "A map name must be a Symbol, not #{alias_name.class}" Map.new(map) end - alias method_missing [] + alias_method :method_missing, :[] end end # Implementation of `map.x.aliasname` and `map.x.stage.stagename` class Map - def initialize name; @name = name; end + def initialize name + @name = name + end # Implementation of `map.x.aliasname` def [] alias_name Symbol === alias_name or raise Interscript::MapLogicError, "An alias name must be a Symbol, not #{alias_name.class}" Interscript::Node::Item::Alias.new(alias_name, map: @name) end - alias method_missing [] + alias_method :method_missing, :[] # Implementation of `map.x.stage.stagename` - def stage; Stages.new(@name); end + def stage + Stages.new(@name) + end end # Implementation of `map.x.stage.stagename` and `stage.stagename` class Stages - def initialize map=nil; @map = map; end + def initialize map = nil + @map = map + end def [] stage Interscript::Node::Item::Stage.new(stage, map: @map) end - alias method_missing [] + alias_method :method_missing, :[] end end diff --git a/lib/interscript/dsl/metadata.rb b/lib/interscript/dsl/metadata.rb index 85c19497..bbcc164d 100644 --- a/lib/interscript/dsl/metadata.rb +++ b/lib/interscript/dsl/metadata.rb @@ -1,4 +1,4 @@ -require 'date' +require "date" class Interscript::DSL::Metadata attr_accessor :node @@ -7,27 +7,29 @@ def initialize(yaml: false, map_name: "", library: true, &block) raise Interscript::MapLogicError, "Can't evaluate metadata from Ruby context" unless yaml @map_name = map_name @node = Interscript::Node::MetaData.new - self.instance_exec(&block) + instance_exec(&block) @node[:nonstandard] = {} - NECESSARY_KEYS.each do |i| - unless @node.data.key? i - warn "[#{@map_name}] Necessary key #{i} wasn't defined. Defaulting to an empty string" - @node[i] = "" + unless library + NECESSARY_KEYS.each do |i| + unless @node.data.key? i + warn "[#{@map_name}] Necessary key #{i} wasn't defined. Defaulting to an empty string" + @node[i] = "" + end end - end unless library + end end - STANDARD_STRING_KEYS = %i{authority_id id - language source_script destination_script - name creation_date adoption_date description - character source confirmation_date original_description} + STANDARD_STRING_KEYS = %i[authority_id id + language source_script destination_script + name creation_date adoption_date description + character source confirmation_date original_description] + + STANDARD_ARRAY_KEYS = %i[notes implementation_notes original_notes url] - STANDARD_ARRAY_KEYS = %i{notes implementation_notes original_notes url} + NONSTANDARD_KEYS = %i[special_rules] - NONSTANDARD_KEYS = %i{special_rules} - - NECESSARY_KEYS = %i{name language source_script destination_script} + NECESSARY_KEYS = %i[name language source_script destination_script] STANDARD_STRING_KEYS.each do |sym| define_method sym do |stuff| diff --git a/lib/interscript/dsl/stage.rb b/lib/interscript/dsl/stage.rb index 9e0c24db..50bb1b86 100644 --- a/lib/interscript/dsl/stage.rb +++ b/lib/interscript/dsl/stage.rb @@ -1,6 +1,6 @@ class Interscript::DSL::Stage < Interscript::DSL::Group def initialize(name = :main, &block) @node = Interscript::Node::Stage.new(name) - self.instance_exec(&block) + instance_exec(&block) end end diff --git a/lib/interscript/dsl/symbol_mm.rb b/lib/interscript/dsl/symbol_mm.rb index 980ff5b8..8a851bd1 100644 --- a/lib/interscript/dsl/symbol_mm.rb +++ b/lib/interscript/dsl/symbol_mm.rb @@ -2,8 +2,8 @@ module Interscript::DSL::SymbolMM def method_missing sym, *args, **kwargs, &block super if args.length > 0 super if kwargs.length > 0 - super if sym.to_s =~ /[?!=]\z/ - super unless sym.to_s =~ /\A[\w\d]+\z/ + super if /[?!=]\z/.match?(sym.to_s) + super unless /\A[\w\d]+\z/.match?(sym.to_s) super if block_given? sym.to_sym diff --git a/lib/interscript/dsl/tests.rb b/lib/interscript/dsl/tests.rb index 601611b4..792bdd51 100644 --- a/lib/interscript/dsl/tests.rb +++ b/lib/interscript/dsl/tests.rb @@ -3,7 +3,7 @@ class Interscript::DSL::Tests def initialize(&block) @node = Interscript::Node::Tests.new - self.instance_exec(&block) + instance_exec(&block) end def test(from, to, reverse_run: nil) diff --git a/lib/interscript/interpreter.rb b/lib/interscript/interpreter.rb index 7db1dfb2..e1dcc8b1 100644 --- a/lib/interscript/interpreter.rb +++ b/lib/interscript/interpreter.rb @@ -1,13 +1,12 @@ class Interscript::Interpreter < Interscript::Compiler attr_accessor :map - def compile(map, _:nil) + def compile(map, _: nil) @map = map self end - def call(str, stage=:main, each: false, &block) + def call(str, stage = :main, each: false, &block) stage = @map.stages[stage] - s = if each e = Enumerator.new do |yielder| options = [] @@ -35,7 +34,7 @@ def call(str, stage=:main, each: false, &block) # unsure how it can be handled. # # This scenario is described in a commented out test. - type, value, hash = f.resume + _, value, _ = f.resume if options_set f.resume(choices[i][iter]) else @@ -82,10 +81,10 @@ def execute_rule r if r.cached_tree @str = Interscript::Stdlib.parallel_replace_tree(@str, r.cached_tree) elsif r.subs_regexp && r.subs_replacements - if $DEBUG_RE - @str = Interscript::Stdlib.parallel_regexp_gsub_debug(@str, r.subs_regexp, r.subs_replacements) + @str = if $DEBUG_RE + Interscript::Stdlib.parallel_regexp_gsub_debug(@str, r.subs_regexp, r.subs_replacements) else - @str = Interscript::Stdlib.parallel_regexp_gsub(@str, r.subs_regexp, r.subs_replacements) + Interscript::Stdlib.parallel_regexp_gsub(@str, r.subs_regexp, r.subs_replacements) end else begin @@ -100,7 +99,7 @@ def execute_rule r next if i.reverse_run == true subs_array << [build_item(i.from, :par), build_item(i.to, :parstr)] end - tree = Interscript::Stdlib.parallel_replace_compile_tree(subs_array) #.sort_by{|k,v| -k.length}) + tree = Interscript::Stdlib.parallel_replace_compile_tree(subs_array) # .sort_by{|k,v| -k.length}) @str = Interscript::Stdlib.parallel_replace_tree(@str, tree) r.cached_tree = tree # $using_tree = true @@ -129,12 +128,12 @@ def execute_rule r execute_rule(t) end when Interscript::Node::Rule::Sub - if r.to == :upcase - @str = @str.gsub(Regexp.new(build_regexp(r)), &:upcase) + @str = if r.to == :upcase + @str.gsub(Regexp.new(build_regexp(r)), &:upcase) elsif r.to == :downcase - @str = @str.gsub(Regexp.new(build_regexp(r)), &:downcase) + @str.gsub(Regexp.new(build_regexp(r)), &:downcase) else - @str = @str.gsub(Regexp.new(build_regexp(r)), build_item(r.to, :str)) + @str.gsub(Regexp.new(build_regexp(r)), build_item(r.to, :str)) end when Interscript::Node::Rule::Funcall @str = Interscript::Stdlib::Functions.public_send(r.name, @str, **r.kwargs) @@ -168,12 +167,12 @@ def build_regexp(r) re end - def build_item i, target=nil, doc=@map + def build_item i, target = nil, doc = @map i = i.nth_string if %i[str parstr].include? target i = Interscript::Node::Item.try_convert(i) target = :par if target == :parstr - out = case i + case i when Interscript::Node::Item::Alias if i.map d = doc.dep_aliases[i.map].document @@ -193,14 +192,14 @@ def build_item i, target=nil, doc=@map when Interscript::Node::Item::String if [:str, :par].include? target i.data - else#if target == :re + else # if target == :re Regexp.escape(i.data) end when Interscript::Node::Item::Group if target == :par i.children.map do |j| build_item(j, target, doc) - end.reduce([""]) do |j,k| + end.reduce([""]) do |j, k| Array(j).product(Array(k)).map(&:join) end else @@ -215,9 +214,9 @@ def build_item i, target=nil, doc=@map Interscript::Node::Item::MaybeSome, Interscript::Node::Item::Some - resuffix = { Interscript::Node::Item::Maybe => "?" , - Interscript::Node::Item::Some => "+" , - Interscript::Node::Item::MaybeSome => "*" }[i.class] + resuffix = {Interscript::Node::Item::Maybe => "?", + Interscript::Node::Item::Some => "+", + Interscript::Node::Item::MaybeSome => "*"}[i.class] if target == :par raise Interscript::SystemConversionError, "Can't use a MaybeSome in a #{target} context" @@ -242,7 +241,7 @@ def build_item i, target=nil, doc=@map case i.value when Array data = i.data.map { |j| build_item(j, target, doc) } - "(?:"+data.join("|")+")" + "(?:" + data.join("|") + ")" when String "[#{Regexp.escape(i.value)}]" when Range diff --git a/lib/interscript/node.rb b/lib/interscript/node.rb index bb8569c8..bb7f6995 100644 --- a/lib/interscript/node.rb +++ b/lib/interscript/node.rb @@ -1,4 +1,3 @@ - class Interscript::Node def initialize raise NotImplementedError, "You can't construct a Node directly" @@ -9,20 +8,18 @@ def ==(other) end def to_hash - { :class => self.class.to_s, - :question => "is something missing?" - } + {class: self.class.to_s, + question: "is something missing?"} end end - require "interscript/node/group" require "interscript/node/document" require "interscript/node/metadata" -require 'interscript/node/alias_def' -require 'interscript/node/dependency' -require 'interscript/node/tests' +require "interscript/node/alias_def" +require "interscript/node/dependency" +require "interscript/node/tests" require "interscript/node/stage" require "interscript/node/rule" diff --git a/lib/interscript/node/alias_def.rb b/lib/interscript/node/alias_def.rb index 48eb1912..2b0deb5b 100644 --- a/lib/interscript/node/alias_def.rb +++ b/lib/interscript/node/alias_def.rb @@ -9,13 +9,13 @@ def initialize(name, data) def ==(other) super && - self.name == other.name && - self.data == other.data + name == other.name && + data == other.data end def to_hash - { :class => self.class.to_s, - :name => @name, - :data => @data.to_hash } + {class: self.class.to_s, + name: @name, + data: @data.to_hash} end end diff --git a/lib/interscript/node/dependency.rb b/lib/interscript/node/dependency.rb index 1afbb26d..780c3eb6 100644 --- a/lib/interscript/node/dependency.rb +++ b/lib/interscript/node/dependency.rb @@ -15,15 +15,15 @@ def reverse def ==(other) super && - self.full_name == other.full_name && - self.import == other.import && - self.name == other.name + full_name == other.full_name && + import == other.import && + name == other.name end def to_hash - { :class => self.class.to_s, - :name => @name, - :full_name => @full_name, - :import => @import } + {class: self.class.to_s, + name: @name, + full_name: @full_name, + import: @import} end end diff --git a/lib/interscript/node/document.rb b/lib/interscript/node/document.rb index 2eea64e1..ee8485a4 100644 --- a/lib/interscript/node/document.rb +++ b/lib/interscript/node/document.rb @@ -62,18 +62,18 @@ def self.reverse_name(name) def ==(other) self.class == other.class && - self.metadata == other.metadata && - self.tests == other.tests && - self.stages == other.stages && - self.aliases == other.aliases + metadata == other.metadata && + tests == other.tests && + stages == other.stages && + aliases == other.aliases end def to_hash - { :class => self.class.to_s, :metadata => @metadata&.to_hash, - :tests => @tests&.to_hash, - :dependencies => @dependencies.map{|x| x.to_hash}, - :dep_aliases => @dep_aliases.transform_values(&:to_hash), - :aliases => @aliases.transform_values(&:to_hash), - :stages => @stages.transform_values(&:to_hash) } + {class: self.class.to_s, metadata: @metadata&.to_hash, + tests: @tests&.to_hash, + dependencies: @dependencies.map { |x| x.to_hash }, + dep_aliases: @dep_aliases.transform_values(&:to_hash), + aliases: @aliases.transform_values(&:to_hash), + stages: @stages.transform_values(&:to_hash)} end end diff --git a/lib/interscript/node/group.rb b/lib/interscript/node/group.rb index 0b86212c..f0a26937 100644 --- a/lib/interscript/node/group.rb +++ b/lib/interscript/node/group.rb @@ -6,34 +6,34 @@ def initialize(reverse_run: nil) @children = [] end - def reorder_children(source,target) + def reorder_children(source, target) @children[source], @children[target] = @children[target], @children[source] self end def apply_order(order) children_new = [nil] * @children.size - order.each_with_index do |pos,idx| + order.each_with_index do |pos, idx| children_new[idx] = @children[pos] end @children = children_new - #@children[source], @children[target] = @children[target], @children[source] + # @children[source], @children[target] = @children[target], @children[source] self end def reverse self.class.new(reverse_run: reverse_run.nil? ? nil : !reverse_run).tap do |r| - r.children = self.children.reverse.map(&:reverse) + r.children = children.reverse.map(&:reverse) end end def to_hash - { :class => self.class.to_s, - :children => @children.map{|x| x.to_hash} } + {class: self.class.to_s, + children: @children.map { |x| x.to_hash }} end def ==(other) - super && self.children == other.children && self.reverse_run == other.reverse_run + super && children == other.children && reverse_run == other.reverse_run end def inspect diff --git a/lib/interscript/node/item.rb b/lib/interscript/node/item.rb index fe2e81de..7584620d 100644 --- a/lib/interscript/node/item.rb +++ b/lib/interscript/node/item.rb @@ -7,23 +7,23 @@ def initialize item def + other this = self - this = this.children if Interscript::Node::Item::Group === this + this = this.children if Interscript::Node::Item::Group === this other = other.children if Interscript::Node::Item::Group === other - this = Array(this) + this = Array(this) other = Array(other) - this = this.map { |i| Interscript::Node::Item.try_convert(i) } + this = this.map { |i| Interscript::Node::Item.try_convert(i) } other = other.map { |i| Interscript::Node::Item.try_convert(i) } middle = [] if Interscript::Node::Item::String === this.last && - Interscript::Node::Item::String === other.first + Interscript::Node::Item::String === other.first - middle = [this.last + other.first] - this = this[0..-2] - other = this[1..-1] + middle = [this.last + other.first] + this = this[0..-2] + other = this[1..-1] end g = Interscript::Node::Item::Group.new(*this, *middle, *other) @@ -32,8 +32,8 @@ def + other end def to_hash - { :class => self.class.to_s, - :item => self.item } + {class: self.class.to_s, + item: item} end def ==(other) diff --git a/lib/interscript/node/item/alias.rb b/lib/interscript/node/item/alias.rb index cfd4a58d..19bc4706 100644 --- a/lib/interscript/node/item/alias.rb +++ b/lib/interscript/node/item/alias.rb @@ -16,7 +16,7 @@ def boundary_like? def max_length if stdlib? - ([:none].include? name) ? 0 : 1 + [:none].include?(name) ? 0 : 1 else return 1 if name == :unicode_hangul raise NotImplementedError, "can't get a max length of this alias" @@ -24,24 +24,28 @@ def max_length end # Not implemented properly - def downcase; self; end - def upcase; self; end + def downcase + self + end + + def upcase + self + end def first_string self end - alias nth_string first_string + alias_method :nth_string, :first_string def to_hash - { :class => self.class.to_s, - :name => name, - :map => map, - } + {class: self.class.to_s, + name: name, + map: map} end def ==(other) - super && self.name == other.name && self.map == other.map + super && name == other.name && map == other.map end def inspect diff --git a/lib/interscript/node/item/any.rb b/lib/interscript/node/item/any.rb index 6e5a786f..cf138247 100644 --- a/lib/interscript/node/item/any.rb +++ b/lib/interscript/node/item/any.rb @@ -25,8 +25,13 @@ def data end end - def downcase; self.class.new(self.data.map(&:downcase)); end - def upcase; self.class.new(self.data.map(&:upcase)); end + def downcase + self.class.new(data.map(&:downcase)) + end + + def upcase + self.class.new(data.map(&:upcase)) + end def first_string case @value @@ -44,17 +49,17 @@ def nth_string d = data Fiber.yield(:prepare) - id = Fiber.yield(:select_nth_string, d.count, self.hash) + id = Fiber.yield(:select_nth_string, d.count, hash) Fiber.yield(:selection) Interscript::Node::Item.try_convert(value[id]).nth_string end def max_length - self.data.map(&:max_length).max + data.map(&:max_length).max end def to_hash - hash = { :class => self.class.to_s } + hash = {class: self.class.to_s} case @value when Array @@ -74,7 +79,7 @@ def to_hash end def ==(other) - super && self.data == other.data + super && data == other.data end def inspect diff --git a/lib/interscript/node/item/capture.rb b/lib/interscript/node/item/capture.rb index 7e9502ea..0bf2634d 100644 --- a/lib/interscript/node/item/capture.rb +++ b/lib/interscript/node/item/capture.rb @@ -15,16 +15,21 @@ def nth_string data.nth_string end - def downcase; self.dup.tap { |i| i.data = i.data.downcase }; end - def upcase; self.dup.tap { |i| i.data = i.data.upcase }; end + def downcase + dup.tap { |i| i.data = i.data.downcase } + end + + def upcase + dup.tap { |i| i.data = i.data.upcase } + end def to_hash - { :class => self.class.to_s, - :data => self.data.to_hash } + {class: self.class.to_s, + data: data.to_hash} end def ==(other) - super && self.data == other.data + super && data == other.data end def inspect @@ -44,15 +49,15 @@ def first_string self end - alias nth_string first_string + alias_method :nth_string, :first_string def to_hash - { :class => self.class.to_s, - :id => self.id } + {class: self.class.to_s, + id: id} end def ==(other) - super && self.id == other.id + super && id == other.id end def inspect diff --git a/lib/interscript/node/item/group.rb b/lib/interscript/node/item/group.rb index b503efa1..d0a62bac 100644 --- a/lib/interscript/node/item/group.rb +++ b/lib/interscript/node/item/group.rb @@ -7,23 +7,23 @@ def initialize *children end end - def +(item) - item = Interscript::Node::Item.try_convert(item) - out = self.dup - if Interscript::Node::Item::Group === item - out.children += item.children + def +(other) + other = Interscript::Node::Item.try_convert(other) + out = dup + if Interscript::Node::Item::Group === other + out.children += other.children else - out.children << item + out.children << other end out.verify! out end def compact - out = self.dup do |n| + out = dup do |n| n.children = n.children.reject do |i| (Interscript::Node::Alias === i && i.name == :none) || - (Interscript::Node::String === i && i.data == "") + (Interscript::Node::String === i && i.data == "") end end @@ -36,15 +36,20 @@ def compact end end - def downcase; self.dup.tap { |i| i.children = i.children.map(&:downcase) }; end - def upcase; self.dup.tap { |i| i.children = i.children.map(&:upcase) }; end + def downcase + dup.tap { |i| i.children = i.children.map(&:downcase) } + end + + def upcase + dup.tap { |i| i.children = i.children.map(&:upcase) } + end # Verify if a group is valid def verify! wrong = @children.find do |i| Interscript::Node::Item::Stage === i || - ! (Interscript::Node::Item === i) || - i.class == Interscript::Node::Item + !(Interscript::Node::Item === i) || + i.class == Interscript::Node::Item end if wrong @@ -53,11 +58,11 @@ def verify! end def first_string - self.children.map(&:first_string).reduce(&:+) + children.map(&:first_string).reduce(&:+) end def nth_string - self.children.map(&:nth_string).reduce(&:+) + children.map(&:nth_string).reduce(&:+) end def max_length @@ -65,12 +70,12 @@ def max_length end def to_hash - { :class => self.class.to_s, - :children => self.children.map{|x| x.to_hash} } + {class: self.class.to_s, + children: children.map { |x| x.to_hash }} end def ==(other) - super && self.children == other.children + super && children == other.children end def inspect diff --git a/lib/interscript/node/item/repeat.rb b/lib/interscript/node/item/repeat.rb index a0f21570..fa14e01a 100644 --- a/lib/interscript/node/item/repeat.rb +++ b/lib/interscript/node/item/repeat.rb @@ -18,12 +18,12 @@ def max_length end def to_hash - { :class => self.class.to_s, - :data => self.data.to_hash } + {class: self.class.to_s, + data: data.to_hash} end def ==(other) - super && self.data == other.data + super && data == other.data end def inspect diff --git a/lib/interscript/node/item/stage.rb b/lib/interscript/node/item/stage.rb index a4c95de7..8bb88fae 100644 --- a/lib/interscript/node/item/stage.rb +++ b/lib/interscript/node/item/stage.rb @@ -7,14 +7,13 @@ def initialize(name, map: nil) end def to_hash - { :class => self.class.to_s, - :name => name, - :map => map, - } + {class: self.class.to_s, + name: name, + map: map} end def ==(other) - super && self.name == other.name && self.map == other.map + super && name == other.name && map == other.map end def inspect diff --git a/lib/interscript/node/item/string.rb b/lib/interscript/node/item/string.rb index 7c7853bb..55127730 100644 --- a/lib/interscript/node/item/string.rb +++ b/lib/interscript/node/item/string.rb @@ -5,39 +5,44 @@ def initialize data end def to_hash - { :class => self.class.to_s, - :data => self.data } + {class: self.class.to_s, + data: data} end def max_length - self.data.length + data.length end def first_string - self.data + data end - def downcase; self.dup.tap { |i| i.data = i.data.downcase }; end - def upcase; self.dup.tap { |i| i.data = i.data.upcase }; end + def downcase + dup.tap { |i| i.data = i.data.downcase } + end + + def upcase + dup.tap { |i| i.data = i.data.upcase } + end - alias nth_string first_string + alias_method :nth_string, :first_string def + other - if self.data == "" + if data == "" Interscript::Node::Item.try_convert(other) elsif Interscript::Node::Item::String === self && - (Interscript::Node::Item::String === other || ::String === other) + (Interscript::Node::Item::String === other || ::String === other) other = Interscript::Node::Item.try_convert(other) - Interscript::Node::Item::String.new(self.data + other.data) + Interscript::Node::Item::String.new(data + other.data) else super end end def ==(other) - super && self.data == other.data + super && data == other.data end def inspect @@ -47,12 +52,12 @@ def inspect # stdext class String - alias plus_before_interscript + + alias_method :plus_before_interscript, :+ def + other if Interscript::Node === other Interscript::Node::Item.try_convert(self) + other else - self.plus_before_interscript(other) + plus_before_interscript(other) end end end diff --git a/lib/interscript/node/metadata.rb b/lib/interscript/node/metadata.rb index 28b4f7e3..99604d66 100644 --- a/lib/interscript/node/metadata.rb +++ b/lib/interscript/node/metadata.rb @@ -1,12 +1,13 @@ class Interscript::Node::MetaData < Interscript::Node attr_accessor :data - def initialize data={} + def initialize data = {} @data = data end - def []=(k,v) + def []=(k, v) @data[k] = v end + def [](k) @data[k] end @@ -18,11 +19,11 @@ def reverse end def ==(other) - super && self.data == other.data + super && data == other.data end def to_hash - {:class => self.class.to_s, - :data => @data} + {class: self.class.to_s, + data: @data} end end diff --git a/lib/interscript/node/rule.rb b/lib/interscript/node/rule.rb index fb0b15b7..03dd9115 100644 --- a/lib/interscript/node/rule.rb +++ b/lib/interscript/node/rule.rb @@ -1,6 +1,6 @@ class Interscript::Node::Rule < Interscript::Node def ==(other) - super && self.reverse_run == other.reverse_run + super && reverse_run == other.reverse_run end end diff --git a/lib/interscript/node/rule/funcall.rb b/lib/interscript/node/rule/funcall.rb index e6a54874..fd7edd8f 100644 --- a/lib/interscript/node/rule/funcall.rb +++ b/lib/interscript/node/rule/funcall.rb @@ -7,10 +7,9 @@ def initialize name, reverse_run: nil, **kwargs end def to_hash - { :class => self.class.to_s, - :name => self.name, - :kwargs => self.kwargs - } + {class: self.class.to_s, + name: name, + kwargs: kwargs} end def reverse @@ -19,7 +18,7 @@ def reverse end def == - super && self.name == other.name && self.kwargs == other.kwargs + super && name == other.name && kwargs == other.kwargs end def inspect diff --git a/lib/interscript/node/rule/run.rb b/lib/interscript/node/rule/run.rb index 78644c07..ad426a4a 100644 --- a/lib/interscript/node/rule/run.rb +++ b/lib/interscript/node/rule/run.rb @@ -6,18 +6,17 @@ def initialize stage, reverse_run: nil end def to_hash - { :class => self.class.to_s, - :stage => self.stage.to_hash } + {class: self.class.to_s, + stage: stage.to_hash} end def reverse Interscript::Node::Rule::Run.new(stage, - reverse_run: reverse_run.nil? ? nil : !reverse_run - ) + reverse_run: reverse_run.nil? ? nil : !reverse_run) end def ==(other) - super && self.stage == other.stage + super && stage == other.stage end def inspect diff --git a/lib/interscript/node/rule/sub.rb b/lib/interscript/node/rule/sub.rb index 7086e456..8fb5a46c 100644 --- a/lib/interscript/node/rule/sub.rb +++ b/lib/interscript/node/rule/sub.rb @@ -5,23 +5,23 @@ class Interscript::Node::Rule::Sub < Interscript::Node::Rule attr_accessor :reverse_run attr_accessor :priority - def initialize (from, to, - before: nil, not_before: nil, - after: nil, not_after: nil, - priority: nil, reverse_run: nil) + def initialize(from, to, + before: nil, not_before: nil, + after: nil, not_after: nil, + priority: nil, reverse_run: nil) self.from = Interscript::Node::Item.try_convert from - if to == :upcase - self.to = :upcase + self.to = if to == :upcase + :upcase elsif to == :downcase - self.to = :downcase + :downcase else - self.to = Interscript::Node::Item.try_convert to + Interscript::Node::Item.try_convert to end self.priority = priority - #raise TypeError, "Can't supply both before and not_before" if before && not_before - #raise TypeError, "Can't supply both after and not_after" if after && not_after + # raise TypeError, "Can't supply both before and not_before" if before && not_before + # raise TypeError, "Can't supply both after and not_after" if after && not_after self.reverse_run = reverse_run @@ -32,34 +32,33 @@ def initialize (from, to, end def max_length - len = self.from.max_length - len += self.before.max_length if self.before - len += self.after.max_length if self.after - len += self.not_before.max_length if self.not_before - len += self.not_after.max_length if self.not_after - len += self.priority if self.priority + len = from.max_length + len += before.max_length if before + len += after.max_length if after + len += not_before.max_length if not_before + len += not_after.max_length if not_after + len += priority if priority len end def to_hash - puts self.from.inspect if $DEBUG + puts from.inspect if $DEBUG puts params.inspect if $DEBUG - hash = { :class => self.class.to_s, - :from => self.from.to_hash, - :to => Symbol === self.to ? self.to : self.to.to_hash, - :reverse_run => self.reverse_run, - :before => self.before&.to_hash, - :not_before => self.not_before&.to_hash, - :after => self.after&.to_hash, - :not_after => self.not_after&.to_hash, - :priority => self.priority - } - - hash[:before] = self.before&.to_hash if self.before - hash[:not_before] = self.not_before&.to_hash if self.not_before - hash[:after] = self.after&.to_hash if self.after - hash[:not_after] = self.not_after&.to_hash if self.not_after - hash[:priority] = self.priority if self.priority + hash = {class: self.class.to_s, + from: from.to_hash, + to: (Symbol === to) ? to : to.to_hash, + reverse_run: reverse_run, + before: before&.to_hash, + not_before: not_before&.to_hash, + after: after&.to_hash, + not_after: not_after&.to_hash, + priority: priority} + + hash[:before] = before&.to_hash if before + hash[:not_before] = not_before&.to_hash if not_before + hash[:after] = after&.to_hash if after + hash[:not_after] = not_after&.to_hash if not_after + hash[:priority] = priority if priority hash end @@ -76,12 +75,12 @@ def reverse end # A special case: sub "a", "" shouldn't be present in a reverse map - rrun = self.reverse_run.nil? ? nil : !self.reverse_run + rrun = reverse_run.nil? ? nil : !reverse_run if rrun.nil? && !has_assertions? && - (xfrom == "" || - (Interscript::Node::Item::String === xfrom && xfrom.data == '') || - (Interscript::Node::Item::Alias === xfrom && xfrom.name == :none) - ) + (xfrom == "" || + (Interscript::Node::Item::String === xfrom && xfrom.data == "") || + (Interscript::Node::Item::Alias === xfrom && xfrom.name == :none) + ) rrun = true end @@ -92,10 +91,9 @@ def reverse reverse_run: rrun, - priority: priority ? -priority : nil - ) + priority: priority ? -priority : nil) end - + def has_assertions? !!(before || not_before || not_after || after) end @@ -140,10 +138,10 @@ def reverse_transfer from, to end # This part is about moving backreferences - state = {left:[], right:[]} + state = {left: [], right: []} - from = reverse_transfer_visit(from, :from, state) - to = reverse_transfer_visit(to, :to, state) + from = reverse_transfer_visit(from, :from, state) + to = reverse_transfer_visit(to, :to, state) [from, to] end @@ -198,23 +196,23 @@ def reverse_transfer from, to def ==(other) super && - self.from == other.from && - self.to == other.to && - self.before == other.before && - self.after == other.after && - self.not_before == other.not_before && - self.not_after == other.not_after && - self.priority == other.priority + from == other.from && + to == other.to && + before == other.before && + after == other.after && + not_before == other.not_before && + not_after == other.not_after && + priority == other.priority end def inspect out = "sub " params = [] params << @from.inspect - if Symbol === @to - params << @to.to_s + params << if Symbol === @to + @to.to_s else - params << @to.inspect + @to.inspect end params << "reverse_run: #{@reverse_run.inspect}" unless @reverse_run.nil? diff --git a/lib/interscript/node/stage.rb b/lib/interscript/node/stage.rb index a61ae865..fe417f79 100644 --- a/lib/interscript/node/stage.rb +++ b/lib/interscript/node/stage.rb @@ -9,29 +9,26 @@ def initialize(name = :main, reverse_run: nil, doc_name: nil, dont_reverse: fals end def to_hash - { :class => self.class.to_s, - :name => name, - :children => @children.map{|x| x.to_hash} } + {class: self.class.to_s, + name: name, + children: @children.map { |x| x.to_hash }} end def reverse return self if dont_reverse - @reverse ||= begin - self.class.new(name, - doc_name: Interscript::Node::Document.reverse_name(doc_name), - reverse_run: reverse_run.nil? ? nil : !reverse_run - ).tap do |r| - r.children = self.children.reverse.map(&:reverse) - end + @reverse ||= self.class.new(name, + doc_name: Interscript::Node::Document.reverse_name(doc_name), + reverse_run: reverse_run.nil? ? nil : !reverse_run).tap do |r| + r.children = children.reverse.map(&:reverse) end end def ==(other) super && - self.name == other.name && - self.reverse_run == other.reverse_run && - self.dont_reverse == other.dont_reverse + name == other.name && + reverse_run == other.reverse_run && + dont_reverse == other.dont_reverse end def inspect diff --git a/lib/interscript/node/tests.rb b/lib/interscript/node/tests.rb index f440cd98..3789a15d 100644 --- a/lib/interscript/node/tests.rb +++ b/lib/interscript/node/tests.rb @@ -1,6 +1,6 @@ class Interscript::Node::Tests < Interscript::Node attr_accessor :data - def initialize data=[] + def initialize data = [] @data = data end @@ -9,17 +9,17 @@ def <<(pair) end def reverse - self.class.new(data.map do |from,to,reverse_run| - [to, from, reverse_run == nil ? nil : !reverse_run] + self.class.new(data.map do |from, to, reverse_run| + [to, from, reverse_run.nil? ? nil : !reverse_run] end) end def ==(other) - super && self.data == other.data + super && data == other.data end def to_hash - { :class => self.class.to_s, - :data => @data } + {class: self.class.to_s, + data: @data} end end diff --git a/lib/interscript/stdlib.rb b/lib/interscript/stdlib.rb index 2f9100d7..60812946 100644 --- a/lib/interscript/stdlib.rb +++ b/lib/interscript/stdlib.rb @@ -1,6 +1,6 @@ class Interscript::Stdlib ALIASES = { - any_character: '.', + any_character: ".", none: "", space: " ", whitespace: "[\\b \\t\\0\\r\\n]", @@ -19,7 +19,7 @@ class Interscript::Stdlib } def self.re_only_alias?(a) - ! %i[none space].include?(a) + !%i[none space].include?(a) end def self.boundary_like_alias?(a) @@ -30,10 +30,10 @@ def self.boundary_like_alias?(a) def self.parallel_regexp_compile(subs_hash) # puts subs_hash.inspect - regexp = subs_hash.each_with_index.map do |p,i| - "(?<_%d>%s)" % [i,p[0]] + regexp = subs_hash.each_with_index.map do |p, i| + "(?<_%d>%s)" % [i, p[0]] end.join("|") - subs_regexp = Regexp.compile(regexp) + Regexp.compile(regexp) # puts subs_regexp.inspect end @@ -50,7 +50,7 @@ def self.parallel_regexp_gsub_debug(string, subs_regexp, subs_array) # only gathering debug info, test data is available in maps_analyze_staging $subs_matches = [] $subs_regexp = subs_regexp - #$subs_array = subs_array + # $subs_array = subs_array string.gsub(subs_regexp) do |match| lm = Regexp.last_match # puts lm.inspect @@ -65,28 +65,27 @@ def self.parallel_regexp_gsub_debug(string, subs_regexp, subs_array) end end - def self.parallel_replace_compile_hash(a) h = {} - a.each do |from,to| + a.each do |from, to| h[from] = to end h end - def self.parallel_replace_hash(str,h) + def self.parallel_replace_hash(str, h) newstr = "" len = str.length max_key_len = h.keys.map(&:length).max i = 0 while i < len max_key_len.downto(1).each do |checked_len| - substr = str[i,checked_len] + substr = str[i, checked_len] if h[substr] newstr << h[substr] i += substr.length - elsif checked_len==1 - newstr << str[i,1] + elsif checked_len == 1 + newstr << str[i, 1] i += 1 end end @@ -130,8 +129,8 @@ def self.parallel_replace_tree(str, tree) match, repl = nil, nil j = 0 - while j < len-i - cc = str[i+j] + while j < len - i + cc = str[i + j] if branch.include? cc.ord branch = branch[cc.ord] sub << cc @@ -167,7 +166,7 @@ def self.deterministic_sort_by_max_length(ary) # Deterministic on Linux: # ary.sort_by{ |rule| -rule.max_length } - ary.each_with_index.sort_by{ |rule,idx| -rule.max_length*100000 + idx }.map(&:first) + ary.each_with_index.sort_by { |rule, idx| -rule.max_length * 100000 + idx }.map(&:first) end def self.available_functions @@ -186,31 +185,31 @@ def self.reverse_function unseparate: :separate, rababa: :rababa_reverse, - rababa_reverse: :rababa, + rababa_reverse: :rababa } end module Functions def self.title_case(output, word_separator: " ") output = output.gsub(/^(.)/, &:upcase) - output = output.gsub(/#{word_separator}(.)/, &:upcase) unless word_separator == '' + output = output.gsub(/#{word_separator}(.)/, &:upcase) unless word_separator == "" output end def self.downcase(output, word_separator: nil) if word_separator output = output.gsub(/^(.)/, &:downcase) - output = output.gsub(/#{word_separator}(.)/, &:downcase) unless word_separator == '' + output.gsub(/#{word_separator}(.)/, &:downcase) unless word_separator == "" else output.downcase end end - def self.compose(output, _:nil) + def self.compose(output, _: nil) output.unicode_normalize(:nfc) end - def self.decompose(output, _:nil) + def self.decompose(output, _: nil) output.unicode_normalize(:nfd) end @@ -224,7 +223,11 @@ def self.unseparate(output, separator: " ") @secryst_models = {} def self.secryst(output, model:) - require "secryst" rescue nil # Try to load secryst, but don't fail hard if not possible. + begin + require "secryst" + rescue + nil + end # Try to load secryst, but don't fail hard if not possible. unless defined? Secryst raise Interscript::ExternalUtilError, "Secryst is not loaded. Please read docs/Usage_with_Secryst.adoc" end @@ -238,14 +241,18 @@ def self.secryst(output, model:) end def self.rababa(output, config:) - require "rababa" rescue nil # Try to load rababa, but don't fail hard if not possible. + begin + require "rababa" + rescue + nil + end # Try to load rababa, but don't fail hard if not possible. unless defined? Rababa raise Interscript::ExternalUtilError, "Rababa is not loaded. Please read docs/Usage_with_Rababa.adoc" end config_value = Interscript.rababa_configs[config] - model_uri = config_value['model'] - rababa_config = config_value['config'] + model_uri = config_value["model"] + rababa_config = config_value["config"] model_path = Interscript.rababa_provision(config, model_uri) @rababa_diacritizer ||= Rababa::Diacritizer.new(model_path, rababa_config) @@ -263,7 +270,7 @@ def self.rababa_reverse(output, config:) # Rababa::Diacritizer.allocate.remove_diacritics(output) # Unfortunately, this is broken as of now. - output.gsub(/[\u064e\u064b\u064f\u064c\u0650\u064d\u0652\u0651]/, '') + output.gsub(/[\u064e\u064b\u064f\u064c\u0650\u064d\u0652\u0651]/, "") end end end diff --git a/lib/interscript/utils/helpers.rb b/lib/interscript/utils/helpers.rb index 71999d6c..6de26861 100644 --- a/lib/interscript/utils/helpers.rb +++ b/lib/interscript/utils/helpers.rb @@ -1,6 +1,6 @@ module Interscript::Utils module Helpers - def document name=nil, &block + def document name = nil, &block $example_id ||= 0 $example_id += 1 name ||= "example-#{$example_id}" @@ -20,14 +20,14 @@ def stage &block end class Interscript::Node::Document - def call(str, stage=:main, compiler=$compiler || Interscript::Interpreter, **kwargs) - compiler.(self).(str, stage, **kwargs) + def call(str, stage = :main, compiler = $compiler || Interscript::Interpreter, **kwargs) + compiler.call(self).call(str, stage, **kwargs) end end module Interscript::DSL class << self - alias original_parse parse + alias_method :original_parse, :parse def parse(map_name, **kwargs) if $documents && $documents[map_name] $documents[map_name] @@ -36,4 +36,4 @@ def parse(map_name, **kwargs) end end end -end \ No newline at end of file +end diff --git a/lib/interscript/utils/regexp_converter.rb b/lib/interscript/utils/regexp_converter.rb index 6a1bea30..e3db612c 100644 --- a/lib/interscript/utils/regexp_converter.rb +++ b/lib/interscript/utils/regexp_converter.rb @@ -1,81 +1,80 @@ -require 'regexp_parser' - +require "regexp_parser" def process(node) children = if node.respond_to?(:expressions) && node.expressions - children = node.expressions.map.each { |expr| process(expr) } - end + node.expressions.map.each { |expr| process(expr) } + end # puts node.inspect out = case node - when Regexp::Expression::Root - children - when Regexp::Expression::Assertion::Lookbehind - [:lookbehind_start, children, :lookbehind_stop] - when Regexp::Expression::Assertion::NegativeLookbehind - [:negative_lookbehind_start, children, :negative_lookbehind_stop] - when Regexp::Expression::Assertion::Lookahead - [:lookahead_start, children, :lookahead_stop] - when Regexp::Expression::Assertion::NegativeLookahead - [:negative_lookahead_start, children, :negative_lookahead_stop] - when Regexp::Expression::Group::Capture - [:capture_start, children, :capture_stop] - when Regexp::Expression::CharacterSet - # puts children.inspect - if children.flatten.include? (:range_start) #or children.size > 1 - [:characterset_start, :array_start, children, :array_stop, :characterset_stop] - else - [:characterset_start, children, :characterset_stop] - end - when Regexp::Expression::Alternation - [:alternation_start, children, :alternation_stop] - when Regexp::Expression::Alternative - [:alternative_start, children, :alternative_stop] - when Regexp::Expression::CharacterSet::Range - lit1 = node.expressions[0].text - lit2 = node.expressions[1].text - [:range_start, lit1, :range_mid, lit2, :range_stop] - when Regexp::Expression::Anchor::WordBoundary - :boundary - when Regexp::Expression::Anchor::NonWordBoundary - :non_word_boundary - when Regexp::Expression::EscapeSequence::Backspace - :boundary # most probably boundary - when Regexp::Expression::CharacterType::Space - :space - when Regexp::Expression::Anchor::BeginningOfLine - :line_start - when Regexp::Expression::Anchor::EndOfLine - :line_end - when Regexp::Expression::CharacterType::Any - :any_character - when Regexp::Expression::Literal - node.text - when Regexp::Expression::EscapeSequence::Literal - node.text - when Regexp::Expression::EscapeSequence::Codepoint - node.text - when Regexp::Expression::PosixClass - '[' + node.text + ']' - when Regexp::Expression::UnicodeProperty::Script - node.text - when Regexp::Expression::Backreference::Number # why is there a space before after node.number? - [:backref_num_start, node.number, :backref_num_stop] - else - out = [:missing, node.class] + when Regexp::Expression::Root + children + when Regexp::Expression::Assertion::Lookbehind + [:lookbehind_start, children, :lookbehind_stop] + when Regexp::Expression::Assertion::NegativeLookbehind + [:negative_lookbehind_start, children, :negative_lookbehind_stop] + when Regexp::Expression::Assertion::Lookahead + [:lookahead_start, children, :lookahead_stop] + when Regexp::Expression::Assertion::NegativeLookahead + [:negative_lookahead_start, children, :negative_lookahead_stop] + when Regexp::Expression::Group::Capture + [:capture_start, children, :capture_stop] + when Regexp::Expression::CharacterSet + # puts children.inspect + if children.flatten.include?(:range_start) # or children.size > 1 + [:characterset_start, :array_start, children, :array_stop, :characterset_stop] + else + [:characterset_start, children, :characterset_stop] + end + when Regexp::Expression::Alternation + [:alternation_start, children, :alternation_stop] + when Regexp::Expression::Alternative + [:alternative_start, children, :alternative_stop] + when Regexp::Expression::CharacterSet::Range + lit1 = node.expressions[0].text + lit2 = node.expressions[1].text + [:range_start, lit1, :range_mid, lit2, :range_stop] + when Regexp::Expression::Anchor::WordBoundary + :boundary + when Regexp::Expression::Anchor::NonWordBoundary + :non_word_boundary + when Regexp::Expression::EscapeSequence::Backspace + :boundary # most probably boundary + when Regexp::Expression::CharacterType::Space + :space + when Regexp::Expression::Anchor::BeginningOfLine + :line_start + when Regexp::Expression::Anchor::EndOfLine + :line_end + when Regexp::Expression::CharacterType::Any + :any_character + when Regexp::Expression::Literal + node.text + when Regexp::Expression::EscapeSequence::Literal + node.text + when Regexp::Expression::EscapeSequence::Codepoint + node.text + when Regexp::Expression::PosixClass + "[" + node.text + "]" + when Regexp::Expression::UnicodeProperty::Script + node.text + when Regexp::Expression::Backreference::Number # why is there a space before after node.number? + [:backref_num_start, node.number, :backref_num_stop] + else + out = [:missing, node.class] - out << children if node.respond_to? :expressions - if node.respond_to? :quantifier and node.quantifier - # TODO add quantifier support - pp node - # out << process(node.quantifier) - end - out - end + out << children if node.respond_to? :expressions + if node.respond_to? :quantifier and node.quantifier + # TODO add quantifier support + pp node + # out << process(node.quantifier) + end + out + end if node.respond_to?(:quantifier) && node.quantifier&.token.to_s == "interval" && node.quantifier.max == node.quantifier.min out = [out] * node.quantifier.max elsif node.respond_to?(:quantifier) && node.quantifier qname = node.quantifier.token.to_s - out = ["#{qname}_start".to_sym, [out], "#{qname}_stop".to_sym] + out = [:"#{qname}_start", [out], :"#{qname}_stop"] end out end @@ -89,15 +88,15 @@ def process_root(node) if before.size == 1 root[:before] = before[0][1] node2.delete(before[0]) - elsif before.size >1 + elsif before.size > 1 # pp not_before a = [:alternation_start] - a << before.map{|x| [:alternative_start, x[1], :alternative_stop] } + a << before.map { |x| [:alternative_start, x[1], :alternative_stop] } a << [:alternation_stop] root[:before] = a # pp root[:not_before] - before.each{|n| node2.delete(n)} + before.each { |n| node2.delete(n) } end end @@ -108,15 +107,15 @@ def process_root(node) if not_before.size == 1 root[:not_before] = not_before[0][1] node2.delete(not_before[0]) - elsif not_before.size >1 + elsif not_before.size > 1 # pp not_before a = [:alternation_start] - a << not_before.map{|x| [:alternative_start, x[1], :alternative_stop] } + a << not_before.map { |x| [:alternative_start, x[1], :alternative_stop] } a << [:alternation_stop] root[:not_before] = a # pp root[:not_before] - not_before.each{|n| node2.delete(n)} + not_before.each { |n| node2.delete(n) } end end if after = node.select { |x| x[0] == :lookahead_start } @@ -126,15 +125,15 @@ def process_root(node) if after.size == 1 root[:after] = after[0][1] node2.delete(after[0]) - elsif after.size >1 + elsif after.size > 1 # pp not_before a = [:alternation_start] - a << after.map{|x| [:alternative_start, x[1], :alternative_stop] } + a << after.map { |x| [:alternative_start, x[1], :alternative_stop] } a << [:alternation_stop] root[:after] = a # pp root[:not_before] - after.each{|n| node2.delete(n)} + after.each { |n| node2.delete(n) } end end @@ -144,15 +143,15 @@ def process_root(node) if not_after.size == 1 root[:not_after] = not_after[0][1] node2.delete(not_after[0]) - elsif not_after.size >1 + elsif not_after.size > 1 # pp not_after a = [:alternation_start] - a << not_after.map{|x| [:alternative_start, x[1], :alternative_stop] } + a << not_after.map { |x| [:alternative_start, x[1], :alternative_stop] } a << [:alternation_stop] root[:not_after] = a # pp root[:not_after] - not_after.each{|n| node2.delete(n)} + not_after.each { |n| node2.delete(n) } end end @@ -163,57 +162,57 @@ def process_root(node) def stringify(node) tokens = node.flatten subs = { - characterset_start: 'any(', - characterset_stop: ')', - array_start: '[', - array_stop: ']', - capture_start: 'capture(', - capture_stop: ')', - zero_or_one_start: 'maybe(', - zero_or_one_stop: ')', - zero_or_more_start: 'maybe_some(', - zero_or_more_stop: ')', - one_or_more_start: 'some(', - one_or_more_stop: ')', - alternation_start: 'any([', - alternation_stop: '])', - alternative_start: '', - alternative_stop: '', - boundary: 'boundary', - non_word_boundary: 'non_word_boundary', - space: 'space', - line_start: 'line_start', - line_end: 'line_end', - any_character: 'any_character', - range_start: 'any(', - range_mid: '..', - range_stop: ')', - backref_num_start: 'ref(', - backref_num_stop: ')' + characterset_start: "any(", + characterset_stop: ")", + array_start: "[", + array_stop: "]", + capture_start: "capture(", + capture_stop: ")", + zero_or_one_start: "maybe(", + zero_or_one_stop: ")", + zero_or_more_start: "maybe_some(", + zero_or_more_stop: ")", + one_or_more_start: "some(", + one_or_more_stop: ")", + alternation_start: "any([", + alternation_stop: "])", + alternative_start: "", + alternative_stop: "", + boundary: "boundary", + non_word_boundary: "non_word_boundary", + space: "space", + line_start: "line_start", + line_end: "line_end", + any_character: "any_character", + range_start: "any(", + range_mid: "..", + range_stop: ")", + backref_num_start: "ref(", + backref_num_stop: ")" } str = [] tokens.each_with_index do |token, idx| prev = tokens[idx - 1] if idx > 0 left_side = %i[characterset_stop capture_stop - zero_or_one_stop zero_or_more_stop one_or_more_stop - boundary non_word_boundary - line_start any_character range_stop space - backref_num_stop] + zero_or_one_stop zero_or_more_stop one_or_more_stop + boundary non_word_boundary + line_start any_character range_stop space + backref_num_stop] right_side = %i[characterset_start capture_start - zero_or_one_start zero_or_more_start one_or_more_start - boundary non_word_boundary - line_end any_character range_start space - backref_num_start] - #if prev==:range_stop and token==:range_start + zero_or_one_start zero_or_more_start one_or_more_start + boundary non_word_boundary + line_end any_character range_start space + backref_num_start] + # if prev==:range_stop and token==:range_start # str << ' :adding_ranges ' - #end + # end if (prev.instance_of?(String) && right_side.include?(token)) or - (left_side.include?(prev) && token.instance_of?(String)) or - (left_side.include?(prev) && right_side.include?(token)) - str << ' + ' + (left_side.include?(prev) && token.instance_of?(String)) or + (left_side.include?(prev) && right_side.include?(token)) + str << " + " end - str << ', ' if prev == :alternative_stop and token == :alternative_start + str << ", " if prev == :alternative_stop and token == :alternative_start # str << '[' if prev == :characterset_start and token == :range_start # str << ']' if prev == :range_stop and token ==:characterset_stop if subs.include? token @@ -234,48 +233,48 @@ def stringify(node) end def stringify_root(root, indent: 0) - warning = '' + warning = "" root[:from] = [""] if root[:from] == [] - str = " "*indent+"sub #{stringify(root[:from])}, #{root[:to]}" + str = " " * indent + "sub #{stringify(root[:from])}, #{root[:to]}" [:before, :not_before, :after, :not_after].each do |look| # puts "#{look.inspect} = #{root[look]}" next unless root[look] str_look = stringify(root[look]) - str_look = "\"\"" if root[look] == [] || root[look] == nil - #if str_look.empty? #apparently it is empty sometimes. iso-mal-Mlym-Latn for example + str_look = "\"\"" if root[look] == [] || root[look].nil? + # if str_look.empty? #apparently it is empty sometimes. iso-mal-Mlym-Latn for example # warning << "warning: #{look} is empty string;" - #else - str << ", #{look}: #{str_look}" - #end + # else + str << ", #{look}: #{str_look}" + # end end - str = " "*indent+"# #{str} # warning: :" if str =~ /[^\[]:[^ \]]/ - str = " "*indent+"# #{str} # #{warning}" if !warning.empty? + str = " " * indent + "# #{str} # warning: :" if /[^\[]:[^ \]]/.match?(str) + str = " " * indent + "# #{str} # #{warning}" if !warning.empty? - str = " "*indent+"# #{str} # warning: :missing unimplemented" if str.include?(':missing') - str = " "*indent+"# #{str} # warning: :interval unimplemented" if str.include?(':interval') - str = " "*indent+"# #{str} # warning: :adding_ranges unimplemented" if str.include?(':adding_ranges') - if str.include?('zero_or_one') - str = " "*indent+"# #{str} # warning: zero_or_one" + str = " " * indent + "# #{str} # warning: :missing unimplemented" if str.include?(":missing") + str = " " * indent + "# #{str} # warning: :interval unimplemented" if str.include?(":interval") + str = " " * indent + "# #{str} # warning: :adding_ranges unimplemented" if str.include?(":adding_ranges") + if str.include?("zero_or_one") + str = " " * indent + "# #{str} # warning: zero_or_one" puts "str.includes 'zero_or_one'" pp root end # str = " "*indent+"# #{str} # warning: one_or_more" if str.include?('one_or_more') - str = " "*indent+"# #{str} # warning: :lookahead_start" if str.include?(':lookahead_start') + str = " " * indent + "# #{str} # warning: :lookahead_start" if str.include?(":lookahead_start") # str += " # original: #{root[:from]}" str end if __FILE__ == $0 - rs = File.open(__dir__+"/../../docs/utils/regexp_examples.txt").read.gsub(/([^\\^])\\u/, '\\1\\\\u').gsub(/\\\\b/, '\b') + rs = File.read(__dir__ + "/../../docs/utils/regexp_examples.txt").gsub(/([^\\^])\\u/, '\\1\\\\u').gsub("\\\\b", '\b') rs = rs.split("\n") rs.each do |r| puts r - tree = Regexp::Parser.parse(r, 'ruby/2.1') + tree = Regexp::Parser.parse(r, "ruby/2.1") conv = process(tree) pp conv root = process_root(conv) pp root - root[:to] = ['X'] + root[:to] = ["X"] str = stringify_root(root) puts str puts "\n\n" diff --git a/lib/interscript/visualize.rb b/lib/interscript/visualize.rb index 67d188d8..9e4add80 100644 --- a/lib/interscript/visualize.rb +++ b/lib/interscript/visualize.rb @@ -1,6 +1,6 @@ -require 'erb' -require 'interscript/visualize/nodes' -require 'interscript/visualize/json' +require "erb" +require "interscript/visualize/nodes" +require "interscript/visualize/json" def h(str) str.to_s.gsub("&", "&").gsub("<", "<").gsub(">", ">").gsub('"', """) @@ -8,14 +8,17 @@ def h(str) class Interscript::Visualize def self.def_template(template) - @template = ERB.new(File.read(__dir__+"/visualize/#{template}.html.erb")) + @template = ERB.new(File.read(__dir__ + "/visualize/#{template}.html.erb")) + end + + def get_binding + binding end - def get_binding; binding; end def self.call(*args) - return Map.(*args) if self == Interscript::Visualize + return Map.call(*args) if self == Interscript::Visualize - tplctx = self.new(*args) + tplctx = new(*args) @template.result(tplctx.get_binding) end @@ -29,14 +32,14 @@ def initialize(map_name) attr_reader :map def render_stage(map_name, stage) - Stage.(map_name, stage) + Stage.call(map_name, stage) end end class Group < self def_template :group - def initialize(map, group, style=nil) + def initialize(map, group, style = nil) @map = map @group = group @style = style @@ -44,18 +47,18 @@ def initialize(map, group, style=nil) attr_reader :map, :group - def render_group(map, group, style=nil) - Group.(map, group, style) + def render_group(map, group, style = nil) + Group.call(map, group, style) end end class Stage < Group def_template :group - def initialize(map_name, stage_name, style=nil) + def initialize(map_name, stage_name, style = nil) @map = Interscript.parse(map_name) @group = map.stages[stage_name] @style = style end - end -end \ No newline at end of file + end +end diff --git a/lib/interscript/visualize/json.rb b/lib/interscript/visualize/json.rb index e995b1cd..9b364de9 100644 --- a/lib/interscript/visualize/json.rb +++ b/lib/interscript/visualize/json.rb @@ -1,8 +1,8 @@ class Interscript::Node::Group - def to_visualization_array(map=self) + def to_visualization_array(map = self) out = [] - self.children.each do |rule| + children.each do |rule| case rule when Interscript::Node::Rule::Sub more = [] @@ -16,7 +16,7 @@ def to_visualization_array(map=self) out << { type: "Replace", from: rule.from.to_html(map), - to: Symbol === rule.to ? rule.to : rule.to.to_html(map), + to: (Symbol === rule.to) ? rule.to : rule.to.to_html(map), more: more } when Interscript::Node::Group::Parallel @@ -25,13 +25,13 @@ def to_visualization_array(map=self) children: rule.to_visualization_array(map) } when Interscript::Node::Rule::Funcall - more = rule.kwargs.map do |k,v| - "#{k.to_s.gsub("_", " ")}: #{v}" + more = rule.kwargs.map do |k, v| + "#{k.to_s.tr("_", " ")}: #{v}" end more << "reverse run: #{rule.reverse_run}" unless rule.reverse_run.nil? out << { - type: rule.name.to_s.gsub("_", " ").gsub(/^(.)/, &:upcase), + type: rule.name.to_s.tr("_", " ").gsub(/^(.)/, &:upcase), more: more.join(", ") } when Interscript::Node::Rule::Run @@ -50,7 +50,7 @@ def to_visualization_array(map=self) type: "Run", doc: doc.name, stage: stage, - more: more.join(", "), + more: more.join(", ") } else out << { @@ -62,4 +62,4 @@ def to_visualization_array(map=self) out end -end \ No newline at end of file +end diff --git a/lib/interscript/visualize/nodes.rb b/lib/interscript/visualize/nodes.rb index ea1e8031..6aa1af8b 100644 --- a/lib/interscript/visualize/nodes.rb +++ b/lib/interscript/visualize/nodes.rb @@ -3,9 +3,9 @@ class Alias < self def to_html(doc) if map n = doc.dep_aliases[map].full_name - "#{name.to_s.gsub("_", " ")} from map #{n}" + "#{name.to_s.tr("_", " ")} from map #{n}" else - "#{name.to_s.gsub("_", " ")}" + "#{name.to_s.tr("_", " ")}" end end end @@ -14,9 +14,9 @@ class Stage < self def to_html(doc) if map n = doc.dep_aliases[map].full_name - "stage #{name.to_s.gsub("_", " ")} from map #{n}" + "stage #{name.to_s.tr("_", " ")} from map #{n}" else - "#{name.to_s.gsub("_", " ")}" + "#{name.to_s.tr("_", " ")}" end end end @@ -26,15 +26,15 @@ def to_html(doc) "any (" + case @value when Array - value.map(&Interscript::Node::Item.method(:try_convert)).map{|i|i.to_html(doc)}.join(", ") + value.map(&Interscript::Node::Item.method(:try_convert)).map { |i| i.to_html(doc) }.join(", ") when ::String - value.split("").map(&Interscript::Node::Item.method(:try_convert)).map{|i|i.to_html(doc)}.join(", ") + value.split("").map(&Interscript::Node::Item.method(:try_convert)).map { |i| i.to_html(doc) }.join(", ") when Range - [value.begin, value.end].map(&Interscript::Node::Item.method(:try_convert)).map{|i|i.to_html(doc)}.join(" to ") + [value.begin, value.end].map(&Interscript::Node::Item.method(:try_convert)).map { |i| i.to_html(doc) }.join(" to ") else h(value.inspect) end + - ")" + ")" end end @@ -42,7 +42,7 @@ class CaptureGroup < self def to_html(doc) "capture group (" + data.to_html(doc) + - ")" + ")" end end @@ -50,13 +50,13 @@ class CaptureRef < self def to_html(_) "capture reference (" + id.to_s + - ")" + ")" end end class Group < self def to_html(doc) - @children.map{|i|i.to_html(doc)}.join(" + ") + @children.map { |i| i.to_html(doc) }.join(" + ") end end @@ -77,7 +77,7 @@ def to_html(doc) class String < self def to_html(_) out = "" - self.data.each_char do |i| + data.each_char do |i| out << "" out << "#{h i}" out << "#{"%04x" % i.ord}" @@ -86,4 +86,4 @@ def to_html(_) out end end -end \ No newline at end of file +end