### Load English Tokenizer and Rules in Python Source: https://github.com/bminixhofer/nlprule/blob/main/README.md Installs via pip. Loads the English tokenizer and rules for use in Python. ```python from nlprule import Tokenizer, Rules tokenizer = Tokenizer.load("en") rules = Rules.load("en", tokenizer) ``` -------------------------------- ### Rust Project Setup for NLP Rule Source: https://github.com/bminixhofer/nlprule/blob/main/README.md Configures a Rust project to use nlprule, including Cargo.toml dependencies and build.rs for rule compilation. ```toml [dependencies] nlprule = "" [build-dependencies] lprule-build = "" # must be the same as the nlprule version! ``` ```rust fn main() -> Result<(), nlprule_build::Error> { println!("cargo:rerun-if-changed=build.rs"); nlprule_build::BinaryBuilder::new( &["en"], std::env::var("OUT_DIR").expect("OUT_DIR is set when build.rs is running"), ) .build()?; .validate() } ``` -------------------------------- ### Rust GEC API: Suggest and Correct Source: https://context7.com/bminixhofer/nlprule/llms.txt Use `Rules::suggest` to get detailed suggestions or `Rules::correct` for a one-call correction. Ensure tokenizer and rules binaries are loaded. ```rust use nlprule::{Tokenizer, Rules, types::Suggestion, rules::apply_suggestions}; fn main() -> Result<(), nlprule::Error> { let tokenizer = Tokenizer::new("path/to/en_tokenizer.bin")?; let rules = Rules::new("path/to/en_rules.bin")?; let text = "She was not been here since Monday."; // Get structured suggestions let suggestions = rules.suggest(text, &tokenizer); let s = &suggestions[0]; assert_eq!(s.span().char(), &(4usize..16)); assert_eq!(s.replacements(), &["was not", "has not been"]); assert_eq!(s.source(), "GRAMMAR/WAS_BEEN/1"); assert_eq!(s.message(), "Did you mean was not or has not been?"); // Apply suggestions (always uses first replacement) let corrected = apply_suggestions(text, &suggestions); assert_eq!(corrected, "She was not here since Monday."); // One-call correction let corrected2 = rules.correct("I can due his homework.", &tokenizer); assert_eq!(corrected2, "I can do his homework."); Ok(()) } ``` -------------------------------- ### Python Suggestion and Replacement Details Source: https://github.com/bminixhofer/nlprule/blob/main/CHANGELOG.md Get sentence suggestions and iterate through them to print start, end, text, source, and message. The 'text' attribute is now 'replacements'. ```python suggestions = rules.suggest_sentence("She was not been here since Monday.") for s in suggestions: print(s.start, s.end, s.text, s.source, s.message) # prints: # 4 16 ['was not', 'has not been'] WAS_BEEN.1 Did you mean was not or has not been? ``` -------------------------------- ### NLG Postprocessing Example Source: https://github.com/bminixhofer/nlprule/blob/main/examples/README.md This example shows the output of nlprule when used to postprocess text generated by an NLG model. It highlights corrections for grammar, spelling, and typographical errors, along with messages explaining the suggested changes. ```text Before: ...t out, as a condition of its being operated. Each lock keeper should ensure that all locks are operated and tha... After: ...t out, as a condition of its being operated. Each lockkeeper should ensure that all locks are operated and tha... Message: This noun is normally spelled as one word. Type: grammar --- Before: ...The Washington Post reported in October of 1963 that the Washington Post reported that "Mr. Saul ... After: ...The Washington Post reported in October 1963 that the Washington Post reported that "Mr. Saul Gru... Message: When specifying a month and year, 'of' is unnecessary: October 1963. Type: misspelling --- Before: ...n saying that he had written a book on Napoleon's life so he was born in 1906. The book, The Secret History... After: ...n saying that he had written a book on Napoleon's life, so he was born in 1906. The book, The Secret Histor... Message: Use a comma before 'so' if it connects two independent clauses (unless they are closely connected and short). Type: typographical --- Before: ...The title track on this record has been included in the album... After: ...The title track on this record has been included on the album... Message: The usual collocation for "album" is "on", not "in" when "album" refers to a collection of recorded music. If by "album" you mean a collection of photos, "in an album" is correct. Did you mean on the album? Type: grammar --- Before: ...he Z-machine version (in the standardised format) is comprised of 32 (in total) bytes, one per line. ... After: ...he Z-machine version (in the standardised format) comprises 32 (in total) bytes, one per line. ... Message: Did you mean comprises or consists of or is composed of? Type: misspelling --- Before: ...ith your friends and family when I went out for a weekend and it seemed like no other band coul... After: ...ith your friends and family when I went out for a weekend, and it seemed like no other band coul... Message: Use a comma before 'and' if it connects two independent clauses (unless they are closely connected and short). Type: typographical --- Before: ...esake, its unique appearance allows for increased damage and it does not require the use of an AOE spell. The ... After: ...esake, its unique appearance allows for increased damage, and it does not require the use of an AOE spell. The... Message: Use a comma before 'and' if it connects two independent clauses (unless they are closely connected and short). Type: typographical --- Before: ...er came in September at the London Olympics . The runners up were the French and the Swedish. The women's 3000... After: ...er came in September at the London Olympics . The runners-up were the French and the Swedish. The women's 3000... Message: The noun runners-up (= didn't finish first place) is spelled with a hyphen. Type: grammar ``` -------------------------------- ### Get detailed correction suggestions with Rules.suggest() Source: https://context7.com/bminixhofer/nlprule/llms.txt Use `rules.suggest(text)` to get a list of `Suggestion` objects for detected errors in a given text. Each suggestion includes the error span, possible replacements, rule source, and a message. ```python from nlprule import Tokenizer, Rules tokenizer = Tokenizer.load("en") rules = Rules.load("en", tokenizer) text = "She was not been here since Monday." for s in rules.suggest(text): print(f"Span: [{s.start}:{s.end}] → {repr(text[s.start:s.end])}") print(f"Replacements: {s.replacements}") print(f"Source: {s.source}") print(f"Message: {s.message}") print() # Span: [4:16] → 'was not been' # Replacements: ['was not', 'has not been'] # Source: GRAMMAR/WAS_BEEN/1 # Message: Did you mean was not or has not been? ``` -------------------------------- ### Rules.suggest(text) Source: https://context7.com/bminixhofer/nlprule/llms.txt Get detailed correction suggestions for a given text. Accepts a single string or a list of strings and returns a list of Suggestion objects. ```APIDOC ## Rules.suggest(text) ### Description Returns a list of `Suggestion` objects describing each detected error, including the span, replacement options, rule source ID, and a human-readable message. Accepts a single string or list of strings. ### Method `rules.suggest(text: str | list[str]) -> list[Suggestion]` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from nlprule import Tokenizer, Rules tokenizer = Tokenizer.load("en") rules = Rules.load("en", tokenizer) text = "She was not been here since Monday." for s in rules.suggest(text): print(f"Span: [{s.start}:{s.end}] \u2192 {repr(text[s.start:s.end])}") print(f"Replacements: {s.replacements}") print(f"Source: {s.source}") print(f"Message: {s.message}") print() ``` ### Response #### Success Response (200) - **suggestions** (list[Suggestion]) - A list of suggestion objects. #### Response Example ```json [ { "start": 4, "end": 16, "replacements": ["was not", "has not been"], "source": "GRAMMAR/WAS_BEEN/1", "message": "Did you mean was not or has not been?" } ] ``` ``` -------------------------------- ### Correct Grammar in Python Source: https://github.com/bminixhofer/nlprule/blob/main/README.md Applies grammatical error correction to a given text. Use `rules.correct()` for direct correction or `rules.suggest()` to get a list of suggestions. ```python rules.correct("He wants that you send him an email.") # returns: 'He wants you to send him an email.' rules.correct("I can due his homework.") # returns: 'I can do his homework.' for s in rules.suggest("She was not been here since Monday."): print(s.start, s.end, s.replacements, s.source, s.message) # prints: # 4 16 ['was not', 'has not been'] WAS_BEEN.1 Did you mean was not or has not been? ``` -------------------------------- ### Generate English build directory Source: https://github.com/bminixhofer/nlprule/blob/main/build/README.md Python command to generate the build directory for English. Ensure LT_PATH and chunker model paths are correctly set. ```bash python build/make_build_dir.py \ --lt_dir=$LT_PATH \ --lang_code=en \ --tag_dict_path=$LT_PATH/org/languagetool/resource/en/english.dict \ --tag_info_path=$LT_PATH/org/languagetool/resource/en/english.info \ --chunker_token_model=$HOME/Downloads/nlprule/en-token.bin \ --chunker_pos_model=$HOME/Downloads/nlprule/en-pos-maxent.bin \ --chunker_chunk_model=$HOME/Downloads/nlprule/en-chunker.bin \ --out_dir=data/en ``` -------------------------------- ### Rust Build Script for Binary Acquisition Source: https://context7.com/bminixhofer/nlprule/llms.txt Use `nlprule-build` in `build.rs` to automatically download language binaries for `include_bytes!` embedding. Ensure `nlprule-build` version matches `nlprule`. ```toml # Cargo.toml [dependencies] lprule = "0.6.4" [build-dependencies] nlprule-build = "0.6.4" # must match nlprule version exactly ``` -------------------------------- ### Rust Build Script for Binary Acquisition Source: https://context7.com/bminixhofer/nlprule/llms.txt Use `nlprule-build` in `build.rs` to automatically download language binaries for `include_bytes!` embedding. Ensure `nlprule-build` version matches `nlprule`. ```rust // build.rs fn main() -> Result<(), nlprule_build::Error> { println!("cargo:rerun-if-changed=build.rs"); nlprule_build::BinaryBuilder::new( &["en", "de"], // languages to download std::env::var("OUT_DIR").expect("OUT_DIR set during build"), ) .build()? // downloads binaries to OUT_DIR .validate() // runs internal rule tests to confirm binary integrity } ``` -------------------------------- ### Compile nlprule binaries Source: https://github.com/bminixhofer/nlprule/blob/main/build/README.md Command to compile nlprule binaries using the 'compile' target. Requires a build directory for the specified language and outputs for the tokenizer and rules. ```bash RUST_LOG=INFO cargo run --all-features --bin compile -- \ --build-dir data/en \ --tokenizer-out storage/en_tokenizer.bin \ --rules-out storage/en_rules.bin ``` -------------------------------- ### Generate German build directory Source: https://github.com/bminixhofer/nlprule/blob/main/build/README.md Python command to generate the build directory for German. Ensure LT_PATH and paths to the German POS dictionary are correctly set. ```bash python build/make_build_dir.py \ --lt_dir=$LT_PATH \ --lang_code=de \ --tag_dict_path=$HOME/Downloads/nlprule/german-pos-dict/src/main/resources/org/languagetool/resource/de/german.dict \ --tag_info_path=$HOME/Downloads/nlprule/german-pos-dict/src/main/resources/org/languagetool/resource/de/german.info \ --out_dir=data/de ``` -------------------------------- ### Rust API: Tokenizer::new / Tokenizer::from_reader Source: https://context7.com/bminixhofer/nlprule/llms.txt Load the tokenizer in Rust from a file path or any `Read` implementor. ```APIDOC ## Rust API: Tokenizer::new / Tokenizer::from_reader ### Description Load the tokenizer from a file path or any `Read` implementor (e.g. `&[u8]` for embedding binaries at compile time via `include_bytes!`). ### Method `Tokenizer::new(path: &str) -> Result` `Tokenizer::from_reader(reader: R) -> Result` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use nlprule::{Tokenizer, Rules, tokenizer_filename, rules_filename}; // Recommended: embed binaries at compile time (requires nlprule-build in build.rs) fn main() -> Result<(), nlprule::Error> { let mut tokenizer_bytes: &'static [u8] = include_bytes!(concat!( env!("OUT_DIR"), "/", tokenizer_filename!("en") )); let mut rules_bytes: &'static [u8] = include_bytes!(concat!( env!("OUT_DIR"), "/", rules_filename!("en") )); let tokenizer = Tokenizer::from_reader(&mut tokenizer_bytes)?; let rules = Rules::from_reader(&mut rules_bytes)?; // Correct text assert_eq!( rules.correct("She was not been here since Monday.", &tokenizer), "She was not here since Monday." ); // OR load from file path at runtime // let tokenizer = Tokenizer::new("path/to/en_tokenizer.bin")?; // let rules = Rules::new("path/to/en_rules.bin")?; Ok(()) } ``` ### Response #### Success Response (200) - **tokenizer** (Tokenizer) - An initialized Tokenizer object. #### Response Example ```rust // Successful initialization of Tokenizer let tokenizer = Tokenizer::new("path/to/en_tokenizer.bin")?; ``` ``` -------------------------------- ### Build nlprule binaries in development Source: https://github.com/bminixhofer/nlprule/blob/main/build/README.md Use this when developing nlprule itself. It allows the builder to compile binaries if they are not found. Ensure your Cargo.toml has the specified dev profile override for optimal build performance. ```rust let nlprule_builder = nlprule_build::BinaryBuilder::new( &["en"], std::env::var("OUT_DIR").expect("OUT_DIR is set when build.rs is running"), ) // this specifies that the binaries should be built if they are not found .fallback_to_build_dir(true) .build() .validate(); ``` -------------------------------- ### Test nlprule tokenizer binary Source: https://github.com/bminixhofer/nlprule/blob/main/build/README.md Command to test the tokenizer binary. Requires the path to the compiled tokenizer. ```bash RUST_LOG=WARN cargo run --all-features --bin test_disambiguation -- --tokenizer storage/en_tokenizer.bin ``` -------------------------------- ### Tokenizer.load(lang_code) Source: https://context7.com/bminixhofer/nlprule/llms.txt Loads a tokenizer for a specified language code. It automatically downloads and caches the necessary binary files. Alternatively, a tokenizer can be loaded directly from a local binary file path. ```APIDOC ## Tokenizer.load(lang_code) ### Description Loads a tokenizer for a specified language code (e.g., "en", "de", "es"). This method automatically downloads and caches the tokenizer binary. It also supports loading directly from a local `.bin` file path using `Tokenizer(path)`. ### Method ```python Tokenizer.load(lang_code: str) Tokenizer(path: str) ``` ### Parameters #### Path Parameters - **lang_code** (str) - Required - The ISO 639-1 language code (e.g., "en", "de", "es"). - **path** (str) - Required - The file path to the pre-compiled tokenizer binary. ### Request Example ```python from nlprule import Tokenizer # Load from language code (downloads + caches binary on first call) tokenizer = Tokenizer.load("en") # OR load from a local binary file # tokenizer = Tokenizer("/path/to/en_tokenizer.bin") ``` ### Response #### Success Response - **tokenizer** (Tokenizer) - An initialized Tokenizer object. ### Related - `Tokenizer.pipe(text)` - `Rules.load(lang_code, tokenizer)` ``` -------------------------------- ### Generate Spanish build directory Source: https://github.com/bminixhofer/nlprule/blob/main/build/README.md Python command to generate the build directory for Spanish. Ensure LT_PATH and paths to the Spanish POS dictionary are correctly set. Note potential manual postprocessing steps for disambiguation and grammar XML files. ```bash python build/make_build_dir.py \ --lt_dir=$LT_PATH \ --lang_code=es \ --tag_dict_path=$HOME/Downloads/nlprule/spanish-pos-dict/org/languagetool/resource/es/es-ES.dict \ --tag_info_path=$HOME/Downloads/nlprule/spanish-pos-dict/org/languagetool/resource/es/es-ES.info \ --out_dir=data/es ``` -------------------------------- ### Load Tokenizer in Python Source: https://context7.com/bminixhofer/nlprule/llms.txt Loads a tokenizer from a language code, downloading and caching the binary if necessary. Alternatively, it can load from a local file path. Accessing the underlying tagger dictionary is also shown. ```python from nlprule import Tokenizer, Rules # Load from language code (downloads + caches binary on first call) tokenizer = Tokenizer.load("en") # also supports "de", "es" # OR load from a local binary file # tokenizer = Tokenizer("/path/to/en_tokenizer.bin") # Access the underlying tagger dictionary tagGER = tokenizer.tagger print(tagger.get_data("running")) # [('run', 'VBG'), ('running', 'NN'), ('running', 'JJ')] ``` -------------------------------- ### Test nlprule grammar rule binary Source: https://github.com/bminixhofer/nlprule/blob/main/build/README.md Command to test the grammar rule binary. Requires paths to both the tokenizer and rules binaries. ```bash RUST_LOG=WARN cargo run --all-features --bin test -- --tokenizer storage/en_tokenizer.bin --rules storage/en_rules.bin ``` -------------------------------- ### Load tokenizer and rules in Rust Source: https://context7.com/bminixhofer/nlprule/llms.txt Load the tokenizer and rules in Rust using `Tokenizer::from_reader` and `Rules::from_reader`, typically with bytes embedded at compile time using `include_bytes!` and `nlprule-build`. ```rust use nlprule::{Tokenizer, Rules, tokenizer_filename, rules_filename}; // Recommended: embed binaries at compile time (requires nlprule-build in build.rs) fn main() -> Result<(), nlprule::Error> { let mut tokenizer_bytes: &'static [u8] = include_bytes!(concat!( env!("OUT_DIR"), "/", tokenizer_filename!("en") )); let mut rules_bytes: &'static [u8] = include_bytes!(concat!( env!("OUT_DIR"), "/", rules_filename!("en") )); let tokenizer = Tokenizer::from_reader(&mut tokenizer_bytes)?; let rules = Rules::from_reader(&mut rules_bytes)?; // Correct text assert_eq!( rules.correct("She was not been here since Monday.", &tokenizer), "She was not here since Monday." ); // OR load from file path at runtime // let tokenizer = Tokenizer::new("path/to/en_tokenizer.bin")?; // let rules = Rules::new("path/to/en_rules.bin")?; Ok(()) } ``` -------------------------------- ### Rules::suggest / Rules::correct / apply_suggestions Source: https://context7.com/bminixhofer/nlprule/llms.txt Core Rust GEC API for generating suggestions, correcting text, and applying suggestions manually. `suggest` returns `Vec`, `correct` returns a corrected `String`, and `apply_suggestions` allows for filtering and manual application of suggestions. ```APIDOC ## Rules::suggest / Rules::correct / apply_suggestions ### Description Core Rust GEC API. `suggest` returns `Vec`, `correct` returns a corrected `String`, and `apply_suggestions` lets you filter and apply suggestions manually. ### Method - `suggest(text: &str, tokenizer: &Tokenizer) -> Vec` - `correct(text: &str, tokenizer: &Tokenizer) -> String` - `apply_suggestions(text: &str, suggestions: &[Suggestion]) -> String` ### Example Usage ```rust use nlprule::{Tokenizer, Rules, types::Suggestion, rules::apply_suggestions}; fn main() -> Result<(), nlprule::Error> { let tokenizer = Tokenizer::new("path/to/en_tokenizer.bin")?; let rules = Rules::new("path/to/en_rules.bin")?; let text = "She was not been here since Monday."; // Get structured suggestions let suggestions = rules.suggest(text, &tokenizer); let s = &suggestions[0]; assert_eq!(s.span().char(), &(4usize..16)); assert_eq!(s.replacements(), &["was not", "has not been"]); assert_eq!(s.source(), "GRAMMAR/WAS_BEEN/1"); assert_eq!(s.message(), "Did you mean was not or has not been?"); // Apply suggestions (always uses first replacement) let corrected = apply_suggestions(text, &suggestions); assert_eq!(corrected, "She was not here since Monday."); // One-call correction let corrected2 = rules.correct("I can due his homework.", &tokenizer); assert_eq!(corrected2, "I can do his homework."); Ok(()) } ``` ``` -------------------------------- ### Rust Tokenizer Pipe for Full Analysis Source: https://context7.com/bminixhofer/nlprule/llms.txt Utilize `Tokenizer::pipe` to process text and obtain a `SentenceIter` with detailed token information including POS tags, lemmas, and spans. Requires a tokenizer binary. ```rust use nlprule::Tokenizer; fn main() -> Result<(), nlprule::Error> { let tokenizer = Tokenizer::new("path/to/en_tokenizer.bin")?; let text = "A brief example is shown."; for sentence in tokenizer.pipe(text) { println!("Sentence span: {:?}", sentence.span()); for token in sentence.tokens() { println!( "text={:?} pos={:?} lemmas={:?} chunks={:?} span={:?}", token.word().text().as_str(), token.word().tags().iter().map(|t| t.pos().as_str()).collect::>(), token.word().tags().iter().map(|t| t.lemma().as_str()).collect::>(), token.chunks(), token.span().char(), ); } } // text="A" pos=["DT"] lemmas=["A","a"] chunks=["B-NP-singular"] span=0..1 // text="brief" pos=["JJ"] lemmas=["brief"] chunks=["I-NP-singular"] span=2..7 // text="example" pos=["NN:UN"] lemmas=["example"] chunks=["E-NP-singular"] span=8..15 // text="is" pos=["VBZ"] lemmas=["be","is"] chunks=["B-VP"] span=16..18 // text="shown" pos=["VBN"] lemmas=["show","shown"] chunks=["I-VP"] span=19..24 Ok(()) } ``` -------------------------------- ### Apply filtered suggestions with Rules.apply_suggestions() Source: https://context7.com/bminixhofer/nlprule/llms.txt The static method `Rules.apply_suggestions(text, suggestions)` applies a specific list of `Suggestion` objects to a text. This is useful for filtering or selecting suggestions before applying them. ```python from nlprule import Tokenizer, Rules tokenizer = Tokenizer.load("en") rules = Rules.load("en", tokenizer) text = "She was not been here since Monday." suggestions = rules.suggest(text) # Filter: only apply grammar-category corrections grammar_suggestions = [ s for s in suggestions if "GRAMMAR" in s.source ] corrected = Rules.apply_suggestions(text, grammar_suggestions) print(corrected) # 'She was not here since Monday.' ``` -------------------------------- ### Load and Use NLP Rules in Rust Source: https://github.com/bminixhofer/nlprule/blob/main/README.md Loads tokenizer and rules from compiled binaries within a Rust application and performs grammar correction. ```rust use nlprule::{Rules, Tokenizer, tokenizer_filename, rules_filename}; fn main() { let mut tokenizer_bytes: &'static [u8] = include_bytes!(concat!( env!("OUT_DIR"), "/", tokenizer_filename!("en") )); let mut rules_bytes: &'static [u8] = include_bytes!(concat!( env!("OUT_DIR"), "/", rules_filename!("en") )); let tokenizer = Tokenizer::from_reader(&mut tokenizer_bytes).expect("tokenizer binary is valid"); let rules = Rules::from_reader(&mut rules_bytes).expect("rules binary is valid"); assert_eq!( rules.correct("She was not been here since Monday.", &tokenizer), String::from("She was not here since Monday.") ); } ``` -------------------------------- ### Rust Rule Management: Select, Disable, Enable Source: https://context7.com/bminixhofer/nlprule/llms.txt Manage rules using `Rules::select_mut` with `Category`, `Group`, or string selectors. Rules can be disabled or enabled to modify correction behavior. Requires tokenizer and rules binaries. ```rust use nlprule::{Tokenizer, Rules, rule::id::Category}; use std::convert::TryInto; fn main() -> Result<(), nlprule::Error> { let tokenizer = Tokenizer::new("path/to/en_tokenizer.bin")?; let mut rules = Rules::new("path/to/en_rules.bin")?; // Disable an entire category rules .select_mut(&Category::new("style").into()) .for_each(|rule| rule.disable()); // Disable a specific group using builder API rules .select_mut( &Category::new("confused_words") .join("confusion_due_do") .into(), ) .for_each(|rule| rule.disable()); // Re-enable using string syntax (slash-separated) rules .select_mut(&"confused_words/confusion_due_do".try_into()?) .for_each(|rule| rule.enable()); // Now run correction with modified ruleset let result = rules.correct("I can due his homework.", &tokenizer); println!("{}", result); // may remain uncorrected if rule was disabled Ok(()) } ``` -------------------------------- ### Python Tokenizer and Rules Usage Source: https://github.com/bminixhofer/nlprule/blob/main/CHANGELOG.md Load English tokenizer and rules, then correct a sentence. This replaces the old SplitOn class and *_sentence methods. ```python tokenizer = Tokenizer.load("en") rules = Rules.load("en", tokenizer) rules.correct("He wants that you send him an email.") # this takes an arbitrary text ``` -------------------------------- ### Tokenizer.pipe(text) Source: https://context7.com/bminixhofer/nlprule/llms.txt Applies the full tokenization pipeline to input text, including sentence segmentation, POS tagging, lemmatization, chunking, and disambiguation. It can process a single string or a list of strings for batch processing. ```APIDOC ## Tokenizer.pipe(text) ### Description Applies the complete NLP pipeline to the input text, performing sentence segmentation, tokenization, POS tagging, lemmatization, chunking, and rule-based disambiguation. This method can accept a single string or a list of strings for batched processing. ### Method ```python tokenizer.pipe(text: Union[str, List[str]]) ``` ### Parameters #### Path Parameters - **text** (str or List[str]) - Required - The input text or a list of texts to process. ### Request Example ```python from nlprule import Tokenizer tokenizer = Tokenizer.load("en") # Single text: returns List[List[Token]] for sentence in tokenizer.pipe("A brief example is shown. It has two sentences."): for token in sentence: print( repr(token.text).ljust(12), # str: surface form repr(token.span).ljust(12), # (int, int): char start/end repr(token.tags).ljust(26), # List[str]: POS tags repr(token.lemmas).ljust(26), # List[str]: lemmas repr(token.chunks), # List[str]: chunk tags (IOB) ) # Batched input: returns List[List[List[Token]]] batch = tokenizer.pipe(["First text.", "Second text."]) ``` ### Response #### Success Response - **sentences** (List[List[Token]]) - A list of sentences, where each sentence is a list of `Token` objects. Each `Token` object contains attributes like `text`, `span`, `tags`, `lemmas`, and `chunks`. ### Related - `Tokenizer.load(lang_code)` ``` -------------------------------- ### Load Grammar Rules in Python Source: https://context7.com/bminixhofer/nlprule/llms.txt Loads grammar rules from a language code, pairing them with a Tokenizer. It also supports loading from a local file path. The number of loaded rules and details of the first few rules can be inspected. ```python from nlprule import Tokenizer, Rules tokenizer = Tokenizer.load("en") rules = Rules.load("en", tokenizer) # OR load from local binary # rules = Rules("/path/to/en_rules.bin", tokenizer) # Inspect all loaded rules print(f"Loaded {len(rules.rules)} grammar rules") for rule in rules.rules[:3]: print(rule.id, "|", rule.name, "|", rule.category_name, "|", rule.enabled) # GRAMMAR/WAS_BEEN/1 | ... | grammar | True ``` -------------------------------- ### Perform Tokenization Pipeline in Python Source: https://context7.com/bminixhofer/nlprule/llms.txt Applies sentence segmentation, POS tagging, lemmatization, chunking, and disambiguation to input text. It accepts a single string or a list of strings for batched processing and returns a list of sentences, each containing Token objects. ```python from nlprule import Tokenizer tokenizer = Tokenizer.load("en") # Single text: returns List[List[Token]] for sentence in tokenizer.pipe("A brief example is shown. It has two sentences."): for token in sentence: print( repr(token.text).ljust(12), # str: surface form repr(token.span).ljust(12), # (int, int): char start/end repr(token.tags).ljust(26), # List[str]: POS tags repr(token.lemmas).ljust(26), # List[str]: lemmas repr(token.chunks), # List[str]: chunk tags (IOB) ) # 'A' (0, 1) ['DT'] ['A', 'a'] ['B-NP-singular'] # 'brief' (2, 7) ['JJ'] ['brief'] ['I-NP-singular'] # 'example' (8, 15) ['NN:UN'] ['example'] ['E-NP-singular'] # 'is' (16, 18) ['VBZ'] ['be', 'is'] ['B-VP'] # 'shown' (19, 24) ['VBN'] ['show', 'shown'] ['I-VP'] # '.' (24, 25) ['.', 'PCT', 'SENT_END'] ['.'] ['O'] # Batched input: returns List[List[List[Token]]] batch = tokenizer.pipe(["First text.", "Second text."]) ``` -------------------------------- ### Select and Modify Rules by Category in Rust Source: https://github.com/bminixhofer/nlprule/blob/main/CHANGELOG.md Demonstrates how to select and modify rules based on their category and name using the nlprule library. Supports disabling or enabling rules. ```rust use nlprule::{Tokenizer, Rules, rule::id::Category}; use std::convert::TryInto; let mut rules = Rules::new("path/to/en_rules.bin")?; // disable rules named "confusion_due_do" in category "confused_words" rules .select_mut( &Category::new("confused_words") .join("confusion_due_do") .into(), ) .for_each(|rule| rule.disable()); // disable all grammar rules rules .select_mut(&Category::new("grammar").into()) .for_each(|rule| rule.disable()); // a string syntax where slashes are the separator is also supported rules .select_mut(&"confused_words/confusion_due_do".try_into()?) .for_each(|rule| rule.enable()); ``` -------------------------------- ### Rules.load(lang_code, tokenizer) Source: https://context7.com/bminixhofer/nlprule/llms.txt Loads grammatical error correction rules for a specified language code, paired with a Tokenizer instance. It also supports loading rules from a local binary file. ```APIDOC ## Rules.load(lang_code, tokenizer) ### Description Loads the grammatical error correction (GEC) rules for a given language code and associates them with a provided `Tokenizer` instance. This method also allows loading rules directly from a local binary file path using `Rules(path, tokenizer)`. ### Method ```python Rules.load(lang_code: str, tokenizer: Tokenizer) Rules(path: str, tokenizer: Tokenizer) ``` ### Parameters #### Path Parameters - **lang_code** (str) - Required - The ISO 639-1 language code for the rules (e.g., "en", "de", "es"). - **tokenizer** (Tokenizer) - Required - An initialized `Tokenizer` object. - **path** (str) - Required - The file path to the pre-compiled rules binary. ### Request Example ```python from nlprule import Tokenizer, Rules tokenizer = Tokenizer.load("en") rules = Rules.load("en", tokenizer) # OR load from local binary # rules = Rules("/path/to/en_rules.bin", tokenizer) # Inspect all loaded rules print(f"Loaded {len(rules.rules)} grammar rules") for rule in rules.rules[:3]: print(rule.id, "|", rule.name, "|", rule.category_name, "|", rule.enabled) ``` ### Response #### Success Response - **rules** (Rules) - An initialized `Rules` object containing the loaded grammar rules. ### Related - `Tokenizer.load(lang_code)` - `Rules.correct(text)` ``` -------------------------------- ### Rules.apply_suggestions(text, suggestions) Source: https://context7.com/bminixhofer/nlprule/llms.txt Apply a filtered subset of suggestions to a text. This static method is useful for applying specific suggestions after filtering. ```APIDOC ## Rules.apply_suggestions(text, suggestions) ### Description Static method that applies a specific list of `Suggestion` objects to a text. Useful when you want to filter or choose among suggestions before applying them. ### Method `Rules.apply_suggestions(text: str, suggestions: list[Suggestion]) -> str` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from nlprule import Tokenizer, Rules tokenizer = Tokenizer.load("en") rules = Rules.load("en", tokenizer) text = "She was not been here since Monday." suggestions = rules.suggest(text) # Filter: only apply grammar-category corrections grammar_suggestions = [ s for s in suggestions if "GRAMMAR" in s.source ] corrected = Rules.apply_suggestions(text, grammar_suggestions) print(corrected) ``` ### Response #### Success Response (200) - **corrected_text** (str) - The text with the applied suggestions. #### Response Example ``` 'She was not here since Monday.' ``` ``` -------------------------------- ### Rules::select_mut / Rule::disable / Rule::enable Source: https://context7.com/bminixhofer/nlprule/llms.txt Rule management in Rust. Filter and mutate rules using a `Selector` built from `Category`, `Group`, or `Index`, or parsed from a slash-separated string. ```APIDOC ## Rules::select_mut / Rule::disable / Rule::enable ### Description Filter and mutate rules using a `Selector` built from `Category`, `Group`, or `Index`, or parsed from a slash-separated string. ### Methods - `select_mut(selector: &Selector) -> RuleSelectorMut` - `disable()` on `Rule` - `enable()` on `Rule` ### Example Usage ```rust use nlprule::{Tokenizer, Rules, rule::id::Category}; use std::convert::TryInto; fn main() -> Result<(), nlprule::Error> { let tokenizer = Tokenizer::new("path/to/en_tokenizer.bin")?; let mut rules = Rules::new("path/to/en_rules.bin")?; // Disable an entire category rules .select_mut(&Category::new("style").into()) .for_each(|rule| rule.disable()); // Disable a specific group using builder API rules .select_mut( &Category::new("confused_words") .join("confusion_due_do") .into(), ) .for_each(|rule| rule.disable()); // Re-enable using string syntax (slash-separated) rules .select_mut(&"confused_words/confusion_due_do".try_into()?) .for_each(|rule| rule.enable()); // Now run correction with modified ruleset let result = rules.correct("I can due his homework.", &tokenizer); println!("{}", result); // may remain uncorrected if rule was disabled Ok(()) } ``` ``` -------------------------------- ### Tokenize and Analyze Text in Python Source: https://github.com/bminixhofer/nlprule/blob/main/README.md Processes text to extract tokens, their spans, tags, lemmas, and chunks. Useful for detailed linguistic analysis. ```python for sentence in tokenizer.pipe("A brief example is shown."): for token in sentence: print( repr(token.text).ljust(10), repr(token.span).ljust(10), repr(token.tags).ljust(24), repr(token.lemmas).ljust(24), repr(token.chunks).ljust(24), ) # prints: # 'A' (0, 1) ['DT'] ['A', 'a'] ['B-NP-singular'] # 'brief' (2, 7) ['JJ'] ['brief'] ['I-NP-singular'] # 'example' (8, 15) ['NN:UN'] ['example'] ['E-NP-singular'] # 'is' (16, 18) ['VBZ'] ['be', 'is'] ['B-VP'] # 'shown' (19, 24) ['VBN'] ['show', 'shown'] ['I-VP'] # '.' (24, 25) ['.', 'PCT', 'SENT_END'] ['.'] ['O'] ``` -------------------------------- ### NLG Model Performance Metrics Source: https://github.com/bminixhofer/nlprule/blob/main/examples/README.md This section summarizes the performance of NLG models based on nlprule suggestions. It provides counts and rates for different suggestion types, indicating the frequency of potential errors or areas for improvement. ```text Generated 192300 tokens. misspelling: 35 suggestions (0.18 per 1000 tokens) style: 53 suggestions (0.28 per 1000 tokens) typographical: 112 suggestions (0.58 per 1000 tokens) grammar: 29 suggestions (0.15 per 1000 tokens) none: 3 suggestions (0.02 per 1000 tokens) inconsistency: 2 suggestions (0.01 per 1000 tokens) ``` -------------------------------- ### Tokenizer::pipe Source: https://context7.com/bminixhofer/nlprule/llms.txt Full tokenization pipeline in Rust. Returns a `SentenceIter` over `Sentence` values, each containing fully analyzed `Token`s with POS tags, lemmas, spans, and chunk labels. ```APIDOC ## Tokenizer::pipe ### Description Full tokenization pipeline in Rust. Returns a `SentenceIter` over `Sentence` values, each containing fully analyzed `Token`s with POS tags, lemmas, spans, and chunk labels. ### Method - `pipe(text: &str) -> SentenceIter` ### Example Usage ```rust use nlprule::Tokenizer; fn main() -> Result<(), nlprule::Error> { let tokenizer = Tokenizer::new("path/to/en_tokenizer.bin")?; let text = "A brief example is shown."; for sentence in tokenizer.pipe(text) { println!("Sentence span: {:?}", sentence.span()); for token in sentence.tokens() { println!( "text={{:?}} pos={{:?}} lemmas={{:?}} chunks={{:?}} span={{:?}}", token.word().text().as_str(), token.word().tags().iter().map(|t| t.pos().as_str()).collect::>(), token.word().tags().iter().map(|t| t.lemma().as_str()).collect::>(), token.chunks(), token.span().char(), ); } } // text="A" pos=["DT"] lemmas=["A","a"] chunks=["B-NP-singular"] span=0..1 // text="brief" pos=["JJ"] lemmas=["brief"] chunks=["I-NP-singular"] span=2..7 // text="example" pos=["NN:UN"] lemmas=["example"] chunks=["E-NP-singular"] span=8..15 // text="is" pos=["VBZ"] lemmas=["be","is"] chunks=["B-VP"] span=16..18 // text="shown" pos=["VBN"] lemmas=["show","shown"] chunks=["I-VP"] span=19..24 Ok(()) } ``` ``` -------------------------------- ### Tagger.get_data(word) Source: https://context7.com/bminixhofer/nlprule/llms.txt Direct dictionary lookup for a word. Accessed via `tokenizer.tagger`, this performs a raw dictionary lookup returning all possible (lemma, POS) pairs for a word, bypassing disambiguation. ```APIDOC ## Tagger.get_data(word) ### Description Direct dictionary lookup for a word. Accessed via `tokenizer.tagger`, this performs a raw dictionary lookup returning all possible `(lemma, POS)` pairs for a word, bypassing disambiguation. ### Method `tagger.get_data(word: str, add_lower: bool = False, use_compound_split_heuristic: bool = False) -> list[tuple[str, str]]` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from nlprule import Tokenizer tokenizer = Tokenizer.load("en") tagGER = tokenizer.tagger # Get all lemma/POS pairs for a word data = tagger.get_data("running") for lemma, pos in data: print(f" lemma={lemma!r:15} pos={pos!r}") # With options data_lower = tagger.get_data("Running", add_lower=True) data_compound = tagger.get_data("Hauptbahnhof", use_compound_split_heuristic=True) # German ``` ### Response #### Success Response (200) - **data** (list[tuple[str, str]]) - A list of tuples, where each tuple contains a lemma and its corresponding Part-of-Speech tag. #### Response Example ```json [ ["running", "JJ"], ["running", "NN"], ["run", "VBG"] ] ``` ``` -------------------------------- ### Select rules by ID with Rules.select() Source: https://context7.com/bminixhofer/nlprule/llms.txt Use `rules.select(id)` to retrieve `Rule` objects matching a selector string. Selectors can target categories, groups, or specific rule indices. Rules can be enabled or disabled. ```python from nlprule import Tokenizer, Rules tokenizer = Tokenizer.load("en") rules = Rules.load("en", tokenizer) # Find all rules in the "confused_words" category confused = rules.select("confused_words") print(f"Found {len(confused)} rules in 'confused_words'") # Disable a specific rule group for rule in rules.select("confused_words/confusion_due_do"): rule.disable() print(f"Disabled: {rule.id} ({rule.name})") # Re-enable it for rule in rules.select("confused_words/confusion_due_do"): rule.enable() # Disable all style rules for rule in rules.select("style"): rule.disable() # Verify rule metadata rule = rules.select("GRAMMAR/WAS_BEEN")[0] print(rule.id) # e.g. GRAMMAR/WAS_BEEN/1 print(rule.name) # human-readable name print(rule.category_name) # e.g. "grammar" print(rule.category_type) # e.g. "grammar" or "style" print(rule.url) # link to more info, if available print(rule.short) # short description, e.g. "Possible agreement error" for ex in rule.examples: print(ex.text, "→", ex.suggestion.replacements if ex.suggestion else "(no suggestion)") ``` -------------------------------- ### Direct dictionary lookup with Tagger.get_data() Source: https://context7.com/bminixhofer/nlprule/llms.txt Access `tokenizer.tagger.get_data(word)` for a raw dictionary lookup of `(lemma, POS)` pairs for a word, bypassing disambiguation. Options like `add_lower` and `use_compound_split_heuristic` are available. ```python from nlprule import Tokenizer tokenizer = Tokenizer.load("en") tagGER = tokenizer.tagger # Get all lemma/POS pairs for a word data = tagger.get_data("running") for lemma, pos in data: print(f" lemma={lemma!r:15} pos={pos!r}") # lemma='running' pos='JJ' # lemma='running' pos='NN' # lemma='run' pos='VBG' # With options data_lower = tagger.get_data("Running", add_lower=True) data_compound = tagger.get_data("Hauptbahnhof", use_compound_split_heuristic=True) # German ```