nlp

package
v3.20.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 2, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package nlp implements POS tagging, word tokenization, and sentence segmentation.

Index

Constants

This section is empty.

Variables

View Source
var SentenceTokenizer sentenceTokenizer

SentenceTokenizer splits text into sentences.

View Source
var WordTokenizer = NewIterTokenizer()

WordTokenizer splits text into words.

Functions

func RegisterModel

func RegisterModel(name, path string) error

RegisterModel makes a tagger available to rules under the given name, reading its dictionary from path.

The dictionary is Vale's existing asset kind, so a model ships, syncs and resolves the same way a spelling dictionary does.

func StrLen

func StrLen(s string) int

StrLen returns the number of runes in a string.

func TaggerFor

func TaggerFor(name string) (tag.Interface, error)

TaggerFor returns the tagger a rule asked for.

An unknown name is an error rather than a quiet fallback: a rule written against one tagger reads differently under another, so substituting one would change what the rule means.

func TextToTokens

func TextToTokens(text string, nlp *Info) []tag.Token

TextToTokens converts a string to a slice of tagged tokens.

Tokens from the built-in tagger carry their byte offset within text, so text[tok.Start:tok.Start+len(tok.Text)] == tok.Text. Tokens from a remote NLP endpoint do not: that API returns text and tags only, so Start is zero throughout and callers needing positions must locate the tokens themselves.

Types

type Block

type Block struct {
	Context string // parent content - e.g., sentence -> paragraph
	Line    int    // line of the block
	Scope   string // section selector
	Parent  string // parent (fully-qualfied) selector
	Text    string // text content

	// Lower is Text lower-cased, for the literal prefilter that decides
	// whether a rule's pattern can match at all. Computed once per block
	// because every rule would otherwise repeat it.
	Lower string

	// Offset is where Text begins within Context, or -1 when that is not
	// known.
	//
	// Checks that can report byte offsets need this to place a match: without
	// it, a match has to be located by searching Context for its text, which
	// finds the first occurrence rather than the one that matched. A sentence
	// repeated in a document is the common case.
	Offset int

	// Runs maps pieces of Text back to the source they were read from, for a
	// block that has no Offset of its own.
	//
	// Extraction drops inline markup, so `has <b>has</b>` arrives as `has has`
	// and the block is nowhere in Context as a whole. Its pieces are, though,
	// and each was placed as it was read. See #502.
	Runs []Run
}

A Block represents a section of text.

func NewBlock

func NewBlock(ctx, txt, sel string) Block

NewBlock makes a new Block with prepared text and a Selector.

func NewLinedBlock

func NewLinedBlock(ctx, txt, sel string, line int) Block

NewLinedBlock creates a Block with an already-known location.

The block's offset is 0 when it *is* its own context, and otherwise unknown; callers that carve a block out of a larger one should set Offset themselves.

func (*Block) SourceOffset

func (b *Block) SourceOffset(i int) int

SourceOffset returns where index i of Text sits in Context, or -1 if that part of the block was never mapped.

type Info

type Info struct {
	Lang         string // Language of the file.
	Endpoint     string // API endpoint (optional); TODO: should this be per-file?
	Scope        string // The file's ext scope.
	Tagging      bool   // Does the file need POS tagging?
	Segmentation bool   // Does the file need sentence segmentation?
	Splitting    bool   // Does the file need paragraph splitting?
}

Info handles NLP-related tasks.

Assigning this on a per-file basis allows us to handle multi-language projects -- one file might be `en` while another is `ja`, for example.

func (*Info) Compute

func (n *Info) Compute(block *Block, split bool) ([]Block, error)

An NLP provider is a library to implements part-of-speech tagging, sentence segmentation, and word tokenization.

The default implementation is the pure-Go prose library, but the goal is to allow (fairly) seamless integration with non-Go libraries too (such as spaCy).

split says whether block holds paragraphs: only then does splitting apply. Headings, list items, and table cells are segmented into sentences like any other prose, but they are not paragraphs, and a rule scoped to `paragraph` must not reach them. See #1132.

type IterTokenizer

type IterTokenizer struct {
	// contains filtered or unexported fields
}

IterTokenizer extracts words from a sentence.

This is a word extractor for spell checking and location matching, not a linguistic tokenizer: it keeps contractions whole ("Don't" stays one token) and drops standalone punctuation. prose's tokenizer splits the other way, so the two are not interchangeable here.

func NewIterTokenizer

func NewIterTokenizer() *IterTokenizer

NewIterTokenizer creates a new IterTokenizer.

func (*IterTokenizer) Tokenize

func (t *IterTokenizer) Tokenize(text string) []string

Tokenize splits a sentence into a slice of words.

func (*IterTokenizer) TokenizeWithOffsets

func (t *IterTokenizer) TokenizeWithOffsets(text string) ([]string, []int)

TokenizeWithOffsets splits a sentence into words and reports where each one begins, as a byte index into `text`.

An offset is -1 when the word cannot be pointed at: the tokenizer normalizes curly quotes and entities before splitting, so a word holding one is not a substring of the text it came from. Callers must treat -1 as "unknown" rather than as a position.

This exists so that a check can report where in its block a match was. The alternative is for the match to be located afterwards by searching the context for its text, which costs a scan of the whole document per alert -- and spelling produces alerts by the thousand.

type Run

type Run struct {
	At, Src, N int
}

A Run is a piece of a block's text and where it came from: At indexes the block, Src the source, and N is how long both are.

type SegmentResult

type SegmentResult struct {
	Sents []string
}

type TagResult

type TagResult struct {
	Tokens []tag.Token
}

type TaggedWord

type TaggedWord struct {
	Token tag.Token
	Line  int
	Span  []int
}

TaggedWord is a word with an NLP context.

type TokenCache

type TokenCache struct {
	// contains filtered or unexported fields
}

TokenCache remembers the tagging of each block within one document.

Every `sequence` rule tags the sentence it is given, and a style may hold hundreds of them -- so the same sentence was tagged once per rule. The result depends only on the text, so it is computed once and shared.

Scoped to a document: a cache living longer would hold every sentence a run has ever seen, and one shared between documents would need locking on a path that is otherwise free of it.

func (*TokenCache) Tokens

func (c *TokenCache) Tokens(text string, info *Info) []tag.Token

Tokens returns the tagged tokens of text, tagging it only the first time.

func (*TokenCache) TokensWith

func (c *TokenCache) TokensWith(model, text string, info *Info) ([]tag.Token, error)

TokensWith is Tokens, read with the named tagger.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL