jlpt 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.ja.md +246 -0
- data/README.md +224 -0
- data/assets/logo.png +0 -0
- data/bin/jlpt +7 -0
- data/lib/jlpt/active_model/validator.rb +43 -0
- data/lib/jlpt/analyzers/comparer.rb +44 -0
- data/lib/jlpt/analyzers/conjugation.rb +60 -0
- data/lib/jlpt/analyzers/corpus_stats.rb +38 -0
- data/lib/jlpt/analyzers/dokkai.rb +53 -0
- data/lib/jlpt/analyzers/exam_readiness.rb +52 -0
- data/lib/jlpt/analyzers/grammar.rb +50 -0
- data/lib/jlpt/analyzers/jukugo.rb +46 -0
- data/lib/jlpt/analyzers/loanwords.rb +54 -0
- data/lib/jlpt/analyzers/onomatopeia.rb +29 -0
- data/lib/jlpt/analyzers/pitch_accent.rb +51 -0
- data/lib/jlpt/analyzers/pos_profiler.rb +47 -0
- data/lib/jlpt/analyzers/simplifier.rb +48 -0
- data/lib/jlpt/analyzers/style_profiler.rb +62 -0
- data/lib/jlpt/analyzers/syntax.rb +43 -0
- data/lib/jlpt/cli.rb +121 -0
- data/lib/jlpt/core/analysis_result.rb +45 -0
- data/lib/jlpt/core/analyzer.rb +58 -0
- data/lib/jlpt/core/cache_manager.rb +90 -0
- data/lib/jlpt/core/config.rb +45 -0
- data/lib/jlpt/core/dictionary.rb +113 -0
- data/lib/jlpt/core/engine.rb +142 -0
- data/lib/jlpt/core/kanji.rb +54 -0
- data/lib/jlpt/core/kanji_details.rb +60 -0
- data/lib/jlpt/core/preprocessor.rb +48 -0
- data/lib/jlpt/core/tokenizer.rb +64 -0
- data/lib/jlpt/core/vocab_classifier.rb +48 -0
- data/lib/jlpt/data/kanji.json +2213 -0
- data/lib/jlpt/data/vocab.json +50298 -0
- data/lib/jlpt/formatters/batch_processor.rb +41 -0
- data/lib/jlpt/formatters/exporter.rb +55 -0
- data/lib/jlpt/formatters/furigana.rb +69 -0
- data/lib/jlpt/formatters/reporter.rb +72 -0
- data/lib/jlpt/version.rb +5 -0
- data/lib/jlpt.rb +50 -0
- metadata +184 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JLPT
|
|
4
|
+
# Batch Text, Subtitle, and Multi-Chapter Document Processor.
|
|
5
|
+
#
|
|
6
|
+
# Processes multiple text sections or chapters, generating difficulty roadmaps
|
|
7
|
+
# and per-section metric summaries.
|
|
8
|
+
#
|
|
9
|
+
module BatchProcessor
|
|
10
|
+
class << self
|
|
11
|
+
# Process a collection of text sections or chapters
|
|
12
|
+
#
|
|
13
|
+
# @param sections [Hash, Array<Hash>, Array<String>] sections mapping or list
|
|
14
|
+
# @return [Array<Hash>] roadmap of processed section difficulty metrics
|
|
15
|
+
def process(sections)
|
|
16
|
+
return [] if sections.nil? || sections.empty?
|
|
17
|
+
|
|
18
|
+
items = normalize_sections(sections)
|
|
19
|
+
items.map do |name, text|
|
|
20
|
+
res = JLPT.analyze(text)
|
|
21
|
+
{ name: name, recommended_level: res.recommended_level, score: res.score,
|
|
22
|
+
word_count: res.word_count, sentence_count: res.sentence_count }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def normalize_sections(sections)
|
|
29
|
+
if sections.is_a?(Hash)
|
|
30
|
+
sections.to_a
|
|
31
|
+
elsif sections.is_a?(Array)
|
|
32
|
+
sections.map.with_index do |sec, idx|
|
|
33
|
+
sec.is_a?(Hash) ? [sec[:name] || "Section #{idx + 1}", sec[:text] || ''] : ["Section #{idx + 1}", sec.to_s]
|
|
34
|
+
end
|
|
35
|
+
else
|
|
36
|
+
[]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JLPT
|
|
4
|
+
# Learner Tools and Anki Flashcard Exporter.
|
|
5
|
+
#
|
|
6
|
+
# Identifies new / unknown vocabulary above a learner's current target level
|
|
7
|
+
# and exports flashcards in Anki TSV/CSV format.
|
|
8
|
+
#
|
|
9
|
+
module Exporter
|
|
10
|
+
LEVEL_ORDER = { n5: 1, n4: 2, n3: 3, n2: 4, n1: 5, non_jlpt: 6, out_of_jlpt: 6 }.freeze
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
# Extract vocabulary words that exceed the learner's current level
|
|
14
|
+
#
|
|
15
|
+
# @param text [String] Japanese text
|
|
16
|
+
# @param target_level [Symbol, String] learner's mastered level (:n5, :n4, :n3, :n2)
|
|
17
|
+
# @return [Array<Hash>] array of unknown word hashes
|
|
18
|
+
def find_unknown(text, target_level: :n4)
|
|
19
|
+
target_val = LEVEL_ORDER[target_level.to_s.downcase.to_sym] || 2
|
|
20
|
+
classified = VocabClassifier.classify(text)
|
|
21
|
+
|
|
22
|
+
unknown = classified.flat_map do |lvl, words|
|
|
23
|
+
extract_words_above_target(lvl, words, target_val)
|
|
24
|
+
end
|
|
25
|
+
unknown.uniq { |item| item[:word] }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Export unknown words as Anki tab-separated values (TSV)
|
|
29
|
+
#
|
|
30
|
+
# @param text [String] Japanese text
|
|
31
|
+
# @param target_level [Symbol, String]
|
|
32
|
+
# @return [String] TSV formatted string
|
|
33
|
+
def to_anki_tsv(text, target_level: :n4)
|
|
34
|
+
items = find_unknown(text, target_level: target_level)
|
|
35
|
+
return '' if items.empty?
|
|
36
|
+
|
|
37
|
+
lines = items.map do |item|
|
|
38
|
+
"#{item[:word]}\t#{item[:word]}[#{item[:reading]}]\t#{item[:level].to_s.upcase}"
|
|
39
|
+
end
|
|
40
|
+
lines.join("\n")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def extract_words_above_target(lvl, words, target_val)
|
|
46
|
+
lvl_val = LEVEL_ORDER[lvl] || 6
|
|
47
|
+
return [] unless lvl_val > target_val
|
|
48
|
+
|
|
49
|
+
words.map do |w|
|
|
50
|
+
{ word: w, level: lvl, reading: Dictionary.reading_for(w) || w }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JLPT
|
|
4
|
+
# Furigana Generator and Romaji Transliteration Engine.
|
|
5
|
+
#
|
|
6
|
+
# Attaches Hiragana readings to Kanji words in HTML (<ruby>) or Markdown/Anki format,
|
|
7
|
+
# and provides Hepburn Romaji transliteration.
|
|
8
|
+
#
|
|
9
|
+
module Furigana
|
|
10
|
+
KANJI_REGEX = /[\u4E00-\u9FFF]/.freeze
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
# Render text with Furigana annotations
|
|
14
|
+
#
|
|
15
|
+
# @param text [String] Japanese input text
|
|
16
|
+
# @param format [Symbol] :html or :markdown (:anki)
|
|
17
|
+
# @return [String] formatted string
|
|
18
|
+
def render(text, format: :html)
|
|
19
|
+
tokens = Tokenizer.tokenize(text)
|
|
20
|
+
return '' if tokens.empty?
|
|
21
|
+
|
|
22
|
+
tokens.map { |token| render_token(token, format: format) }.join
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Transliterate Katakana/Hiragana to Hepburn Romaji
|
|
26
|
+
#
|
|
27
|
+
# @param text [String] Japanese text
|
|
28
|
+
# @return [String] Romaji string
|
|
29
|
+
def to_romaji(text)
|
|
30
|
+
tokens = Tokenizer.tokenize(text)
|
|
31
|
+
return '' if tokens.empty?
|
|
32
|
+
|
|
33
|
+
tokens.map { |t| kana_to_romaji(t[:reading]) }.join(' ').strip
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def render_token(token, format:)
|
|
39
|
+
surface = token[:surface]
|
|
40
|
+
return surface unless surface.match?(KANJI_REGEX)
|
|
41
|
+
|
|
42
|
+
reading = determine_furigana_reading(surface, token[:reading])
|
|
43
|
+
return surface if reading.empty?
|
|
44
|
+
|
|
45
|
+
format == :html ? "<ruby><rb>#{surface}</rb><rt>#{reading}</rt></ruby>" : "#{surface}[#{reading}]"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def determine_furigana_reading(surface, reading)
|
|
49
|
+
if reading && reading != surface
|
|
50
|
+
katakana_to_hiragana(reading)
|
|
51
|
+
else
|
|
52
|
+
Dictionary.reading_for(surface) || ''
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def katakana_to_hiragana(str)
|
|
57
|
+
str.tr('ァ-ン', 'ぁ-ん')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def kana_to_romaji(str)
|
|
61
|
+
return '' if str.nil?
|
|
62
|
+
|
|
63
|
+
str.tr('がぎぐげござじずぜぞだぢづでどばびぶべぼ', 'gagigugegozajizuzedodidudedobabibubebo')
|
|
64
|
+
.tr('あいうえおかきくけこさしすせそたちつてと', 'aiueokakikukesashisusesotachitsuteto')
|
|
65
|
+
.tr('なにぬねのはひふへほまみむめもやゆよらりるれろわをん', 'naninunenohahifuhemomamimumemoyayuyorarirurerowawon')
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JLPT
|
|
4
|
+
# Interactive Visual Reporter.
|
|
5
|
+
#
|
|
6
|
+
# Generates self-contained HTML reports with modern glassmorphism UI,
|
|
7
|
+
# difficulty level badges, progress bars, and GitHub-Flavored Markdown summaries.
|
|
8
|
+
#
|
|
9
|
+
module Reporter
|
|
10
|
+
class << self
|
|
11
|
+
# Render a beautiful, standalone HTML report for an AnalysisResult
|
|
12
|
+
#
|
|
13
|
+
# @param result [JLPT::AnalysisResult]
|
|
14
|
+
# @return [String] HTML string
|
|
15
|
+
def render_html(result)
|
|
16
|
+
furigana = Furigana.render(result.text, format: :html)
|
|
17
|
+
lvl = result.recommended_level.to_s.upcase
|
|
18
|
+
|
|
19
|
+
<<~HTML
|
|
20
|
+
<!DOCTYPE html>
|
|
21
|
+
<html lang="ja">
|
|
22
|
+
<head><meta charset="UTF-8"><title>JLPT Analysis Report - #{lvl}</title>#{html_style_block}</head>
|
|
23
|
+
<body>#{html_header_card(result)}<div class="card"><h2>Annotated Text</h2><div class="reading">#{furigana}</div></div></body>
|
|
24
|
+
</html>
|
|
25
|
+
HTML
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Render a Markdown report table
|
|
29
|
+
#
|
|
30
|
+
# @param result [JLPT::AnalysisResult]
|
|
31
|
+
# @return [String] Markdown string
|
|
32
|
+
def render_markdown(result)
|
|
33
|
+
<<~MARKDOWN
|
|
34
|
+
# JLPT Analysis Report
|
|
35
|
+
|
|
36
|
+
| Metric | Value |
|
|
37
|
+
| :--- | :--- |
|
|
38
|
+
| **Recommended Level** | #{result.recommended_level.to_s.upcase} |
|
|
39
|
+
| **Difficulty Score** | #{result.score} / 100 |
|
|
40
|
+
| **Kanji Density** | #{(result.kanji_density * 100).round(1)}% |
|
|
41
|
+
| **Word Count** | #{result.word_count} |
|
|
42
|
+
| **Sentence Count** | #{result.sentence_count} |
|
|
43
|
+
MARKDOWN
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def html_style_block
|
|
49
|
+
<<~CSS
|
|
50
|
+
<style>
|
|
51
|
+
body { font-family: system-ui, -apple-system, sans-serif; background: #0f172a; color: #f8fafc; padding: 2rem; }
|
|
52
|
+
.card { background: rgba(30, 41, 59, 0.8); border: 1px solid #334155; border-radius: 12px; padding: 1.5rem; margin-bottom: 1.5rem; backdrop-filter: blur(10px); }
|
|
53
|
+
.badge { display: inline-block; padding: 0.5rem 1rem; border-radius: 9999px; background: #6366f1; color: #fff; font-weight: bold; font-size: 1.25rem; }
|
|
54
|
+
.reading { line-height: 2.2; font-size: 1.2rem; }
|
|
55
|
+
rt { font-size: 0.75rem; color: #818cf8; }
|
|
56
|
+
</style>
|
|
57
|
+
CSS
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def html_header_card(result)
|
|
61
|
+
<<~CARD
|
|
62
|
+
<div class="card">
|
|
63
|
+
<h1>JLPT Difficulty Report</h1>
|
|
64
|
+
<p>Recommended Level: <span class="badge">#{result.recommended_level.to_s.upcase}</span></p>
|
|
65
|
+
<p>Difficulty Score: <strong>#{result.score} / 100</strong></p>
|
|
66
|
+
<p>Kanji Density: <strong>#{(result.kanji_density * 100).round(1)}%</strong> | Sentences: <strong>#{result.sentence_count}</strong></p>
|
|
67
|
+
</div>
|
|
68
|
+
CARD
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
data/lib/jlpt/version.rb
ADDED
data/lib/jlpt.rb
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'jlpt/version'
|
|
4
|
+
require_relative 'jlpt/core/config'
|
|
5
|
+
require_relative 'jlpt/core/engine'
|
|
6
|
+
require_relative 'jlpt/core/dictionary'
|
|
7
|
+
require_relative 'jlpt/core/preprocessor'
|
|
8
|
+
require_relative 'jlpt/core/tokenizer'
|
|
9
|
+
require_relative 'jlpt/core/kanji'
|
|
10
|
+
require_relative 'jlpt/core/kanji_details'
|
|
11
|
+
require_relative 'jlpt/core/vocab_classifier'
|
|
12
|
+
require_relative 'jlpt/core/analysis_result'
|
|
13
|
+
require_relative 'jlpt/core/cache_manager'
|
|
14
|
+
require_relative 'jlpt/core/analyzer'
|
|
15
|
+
require_relative 'jlpt/analyzers/grammar'
|
|
16
|
+
require_relative 'jlpt/analyzers/style_profiler'
|
|
17
|
+
require_relative 'jlpt/analyzers/pitch_accent'
|
|
18
|
+
require_relative 'jlpt/analyzers/conjugation'
|
|
19
|
+
require_relative 'jlpt/analyzers/corpus_stats'
|
|
20
|
+
require_relative 'jlpt/analyzers/dokkai'
|
|
21
|
+
require_relative 'jlpt/analyzers/jukugo'
|
|
22
|
+
require_relative 'jlpt/analyzers/loanwords'
|
|
23
|
+
require_relative 'jlpt/analyzers/comparer'
|
|
24
|
+
require_relative 'jlpt/analyzers/onomatopeia'
|
|
25
|
+
require_relative 'jlpt/analyzers/pos_profiler'
|
|
26
|
+
require_relative 'jlpt/analyzers/exam_readiness'
|
|
27
|
+
require_relative 'jlpt/analyzers/syntax'
|
|
28
|
+
require_relative 'jlpt/analyzers/simplifier'
|
|
29
|
+
require_relative 'jlpt/formatters/furigana'
|
|
30
|
+
require_relative 'jlpt/formatters/exporter'
|
|
31
|
+
require_relative 'jlpt/formatters/reporter'
|
|
32
|
+
require_relative 'jlpt/formatters/batch_processor'
|
|
33
|
+
require_relative 'jlpt/cli'
|
|
34
|
+
require_relative 'jlpt/active_model/validator'
|
|
35
|
+
|
|
36
|
+
# Main entry point for the JLPT Japanese text analysis library.
|
|
37
|
+
#
|
|
38
|
+
module JLPT
|
|
39
|
+
class Error < StandardError; end
|
|
40
|
+
|
|
41
|
+
class << self
|
|
42
|
+
# Analyze Japanese text and return difficulty metrics & JLPT recommendation
|
|
43
|
+
#
|
|
44
|
+
# @param text [String] Japanese text
|
|
45
|
+
# @return [JLPT::AnalysisResult]
|
|
46
|
+
def analyze(text)
|
|
47
|
+
Analyzer.analyze(text)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: jlpt
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jakub Polak
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-07-22 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: natto
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.2'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.2'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: bundler
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '13.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '13.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rspec
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '3.12'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.12'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rubocop
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '1.57'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '1.57'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: simplecov
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0.22'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0.22'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: yard
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0.9'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0.9'
|
|
111
|
+
description: Ruby library for Japanese morphological analysis, JLPT N5-N1 difficulty
|
|
112
|
+
scoring, furigana generation, kanji extraction, and pitch accent profiling.
|
|
113
|
+
email:
|
|
114
|
+
- jakub.polak.vz@gmail.com
|
|
115
|
+
executables:
|
|
116
|
+
- jlpt
|
|
117
|
+
extensions: []
|
|
118
|
+
extra_rdoc_files: []
|
|
119
|
+
files:
|
|
120
|
+
- LICENSE
|
|
121
|
+
- README.ja.md
|
|
122
|
+
- README.md
|
|
123
|
+
- assets/logo.png
|
|
124
|
+
- bin/jlpt
|
|
125
|
+
- lib/jlpt.rb
|
|
126
|
+
- lib/jlpt/active_model/validator.rb
|
|
127
|
+
- lib/jlpt/analyzers/comparer.rb
|
|
128
|
+
- lib/jlpt/analyzers/conjugation.rb
|
|
129
|
+
- lib/jlpt/analyzers/corpus_stats.rb
|
|
130
|
+
- lib/jlpt/analyzers/dokkai.rb
|
|
131
|
+
- lib/jlpt/analyzers/exam_readiness.rb
|
|
132
|
+
- lib/jlpt/analyzers/grammar.rb
|
|
133
|
+
- lib/jlpt/analyzers/jukugo.rb
|
|
134
|
+
- lib/jlpt/analyzers/loanwords.rb
|
|
135
|
+
- lib/jlpt/analyzers/onomatopeia.rb
|
|
136
|
+
- lib/jlpt/analyzers/pitch_accent.rb
|
|
137
|
+
- lib/jlpt/analyzers/pos_profiler.rb
|
|
138
|
+
- lib/jlpt/analyzers/simplifier.rb
|
|
139
|
+
- lib/jlpt/analyzers/style_profiler.rb
|
|
140
|
+
- lib/jlpt/analyzers/syntax.rb
|
|
141
|
+
- lib/jlpt/cli.rb
|
|
142
|
+
- lib/jlpt/core/analysis_result.rb
|
|
143
|
+
- lib/jlpt/core/analyzer.rb
|
|
144
|
+
- lib/jlpt/core/cache_manager.rb
|
|
145
|
+
- lib/jlpt/core/config.rb
|
|
146
|
+
- lib/jlpt/core/dictionary.rb
|
|
147
|
+
- lib/jlpt/core/engine.rb
|
|
148
|
+
- lib/jlpt/core/kanji.rb
|
|
149
|
+
- lib/jlpt/core/kanji_details.rb
|
|
150
|
+
- lib/jlpt/core/preprocessor.rb
|
|
151
|
+
- lib/jlpt/core/tokenizer.rb
|
|
152
|
+
- lib/jlpt/core/vocab_classifier.rb
|
|
153
|
+
- lib/jlpt/data/kanji.json
|
|
154
|
+
- lib/jlpt/data/vocab.json
|
|
155
|
+
- lib/jlpt/formatters/batch_processor.rb
|
|
156
|
+
- lib/jlpt/formatters/exporter.rb
|
|
157
|
+
- lib/jlpt/formatters/furigana.rb
|
|
158
|
+
- lib/jlpt/formatters/reporter.rb
|
|
159
|
+
- lib/jlpt/version.rb
|
|
160
|
+
homepage: https://github.com/kupolak/jlpt
|
|
161
|
+
licenses:
|
|
162
|
+
- MIT
|
|
163
|
+
metadata:
|
|
164
|
+
rubygems_mfa_required: 'true'
|
|
165
|
+
post_install_message:
|
|
166
|
+
rdoc_options: []
|
|
167
|
+
require_paths:
|
|
168
|
+
- lib
|
|
169
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: 2.7.0
|
|
174
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
175
|
+
requirements:
|
|
176
|
+
- - ">="
|
|
177
|
+
- !ruby/object:Gem::Version
|
|
178
|
+
version: '0'
|
|
179
|
+
requirements: []
|
|
180
|
+
rubygems_version: 3.5.22
|
|
181
|
+
signing_key:
|
|
182
|
+
specification_version: 4
|
|
183
|
+
summary: Japanese text analyzer and difficulty classifier for JLPT levels N5-N1
|
|
184
|
+
test_files: []
|