Project

jlpt

0.0
The project is in a healthy, maintained state
Ruby library for Japanese morphological analysis, JLPT N5-N1 difficulty scoring, furigana generation, kanji extraction, and pitch accent profiling.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

>= 2.0
~> 13.0
~> 3.12
~> 1.57
~> 0.22
~> 0.9

Runtime

~> 1.2
 Project Readme

JLPT Ruby Gem Logo

JLPT

CI Gem Version License: MIT

A Ruby gem for Japanese text analysis and JLPT difficulty classification (N5–N1).

English | 日本語

It parses Japanese text, classifies vocabulary and kanji by JLPT level, generates furigana, profiles part-of-speech distributions, and provides utilities for text simplification, exam readiness evaluation, and Anki card export.

Table of Contents

  • Installation
  • Quick Start
    • 1. Basic Analysis
    • 2. Global Configuration & Options
    • 3. Furigana & Romaji Generation
    • 4. Text Profiling & Analyzers
    • 5. Anki Exporting & Batch Processing
    • 6. HTML & Markdown Visual Reports
    • 7. Rails ActiveModel Integration
    • 8. CLI Runner
  • Development
  • License

Installation

Add this line to your application's Gemfile:

gem 'jlpt'

And then run:

bundle install

Or install it directly:

gem install jlpt

Quick Start

1. Basic Analysis

require 'jlpt'

result = JLPT.analyze("日本語の勉強はとても面白いです。")

result.recommended_level #=> :n5
result.score             #=> 25.0
result.word_count        #=> 7
result.sentence_count    #=> 1
result.kanji_density     #=> 0.44

2. Global Configuration & Options

Customize global library settings using JLPT.configure:

JLPT.configure do |config|
  # Default output format for Furigana (:html, :anki, or :markdown)
  config.default_furigana_format = :anki # Default: :html

  # Capacity for the LRU cache (number of analyzed texts stored in memory)
  config.cache_capacity = 2000 # Default: 1000

  # Automatic pure-Ruby tokenizer fallback when MeCab/natto gem is absent
  config.mecab_fallback = true # Default: true
end

To reset configuration back to defaults at any point:

JLPT.reset_config!

Summary of Available Options

Option / Parameter Allowed Values / Symbols Default Description
default_furigana_format :html, :anki, :markdown :html Default format used by JLPT::Furigana.render
cache_capacity Integer (e.g. 500, 2000) 1000 Max entries stored in memory LRU cache
mecab_fallback true, false true Enable pure-Ruby tokenizer fallback if MeCab is missing
target_level :n5, :n4, :n3, :n2, :n1 :n4 Target JLPT level for exam readiness & exporter
format (CLI & Reporter) :text, :json, :html, :markdown :text Output format for CLI runner and Reporter

3. Furigana & Romaji Generation

JLPT::Furigana.render("学校に行く", format: :html)
#=> "<ruby><rb>学校</rb><rt>がっこう</rt></ruby>に<ruby><rb>行</rb><rt>い</rt></ruby>く"

JLPT::Furigana.render("学校に行く", format: :anki)
#=> "学校[がっこう]に行[い]く"

JLPT::Furigana.to_romaji("がっこう")
#=> "gakkou"

4. Text Profiling & Analyzers

# Part-of-Speech Distribution
JLPT::PosProfiler.profile("学校に行きます。")

# Grammar Pattern Extraction
JLPT::Grammar.extract("食べてはいけない")
#=> [{ name: "〜てはいけない", level: :n5, pattern: /.../ }]

# Syntactic Clause Complexity
JLPT::Syntax.analyze("雨が降ったから、学校に行かなかった。")
#=> { conjunction_count: 1, conjunctions: ["から"], avg_clauses_per_sentence: 2.0, complexity_index: 50.0 }

# Exam Readiness Evaluation
JLPT::ExamReadiness.evaluate("割合", target_level: :n3)
#=> { target_level: :n3, current_level: :n4, readiness_score: 80.86, status: :moderate }

# Style & Keigo Profiling
JLPT::StyleProfiler.profile("ご覧になる")
#=> { formality_score: 90.0, register: :polite, sonkeigo_count: 1, ... }

# Katakana Loanwords Extraction
JLPT::Loanwords.extract("デパートでパンを買う")
#=> ["デパート", "パン"]

# Kanji Details Lookup
JLPT::KanjiDetails.lookup("学")
#=> { character: "学", strokes: 8, radical: "子", onyomi: ["ガク"], kunyomi: ["まな.ぶ"], level: :n5 }

# Beginner Text Simplification
JLPT::Simplifier.simplify("著しい")
#=> [{ word: "著しい", level: :n1, reading: "いちじるしい", suggestions: ["大きい", "目立つ"] }]

# Lesson & Text Comparison
JLPT::Comparer.compare("私と学校に行く", "私と図書館に行く")
#=> { overlap_ratio: 0.71, shared_vocab: ["私", "と", "に", "行", "く"], shared_kanji: ["私", "行"] }

5. Anki Exporting & Batch Processing

# Find words above learner target level
JLPT::Exporter.find_unknown("急速な発展", target_level: :n4)

# Export TSV for Anki flashcards with pitch accent & tags
JLPT::Exporter.to_anki_tsv("急速な発展", target_level: :n4, include_pitch: true, include_tags: true)

# Export CSV format for Anki
JLPT::Exporter.to_anki_csv("急速な発展", target_level: :n4)

# Multi-chapter / Document Batch Processing
JLPT::BatchProcessor.process({ "Chapter 1" => "私と学校", "Chapter 2" => "急速な発展" })

6. HTML & Markdown Visual Reports

result = JLPT.analyze("日本語の勉強")

# Render self-contained HTML report string
html_report = JLPT::Reporter.render_html(result)

# Render Markdown summary table
md_report = JLPT::Reporter.render_markdown(result)

7. Rails ActiveModel Integration

Use the built-in ActiveModel validator to ensure user input does not exceed a given JLPT level:

class Lesson < ApplicationRecord
  validates :content, jlpt_level: { max_level: :n3 }
end

8. CLI Runner

# Analyze Japanese text
jlpt analyze "日本語の勉強"

# Generate Furigana annotations in Anki format
jlpt furigana "漢字の読み方" --format markdown

# Export unknown words exceeding N4 level to TSV
jlpt export "急速な発展" --target n4 > flashcards.tsv

# Inspect Kanji details or verb conjugations
jlpt kanji ""
jlpt conjugate "食べさせられた"
jlpt simplify "著しい"
jlpt stats "私と学校"

Development

Run tests and linter:

bundle exec rspec
bundle exec rubocop

License

The gem is available as open source under the terms of the MIT License.