hspell(3)

πŸ“¦
version 1.4 Β· 2 versions
, in arch rolling, epel 10, epel 9, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable

πŸ’– hspell β€” the Hebrew spellchecker, but make it C API πŸ’–

okay so bestie, this is the manual for the C API of Hspell, the Hebrew spellchecker. Yes, the lowercase hspell(3) one β€” the library, not the command. ✨

(psst: the hspell(1) page is the other one, and it's where you go for the whole story of the Hspell project, its spelling standard, and how it actually works. This page is just the API tea.)


✨ SYNOPSIS ✨

#include <hspell.h>

int hspell_init(struct dict_radix **dictp, int flags);

void hspell_uninit(struct dict_radix *dictp);

int hspell_check_word(struct dict_radix *dict, const char *word, int *preflen);

void hspell_trycorrect(struct dict_radix *dict, const char *word, struct corlist *cl);

int corlist_init(struct corlist *cl);

int corlist_free(struct corlist *cl);

int corlist_n(struct corlist *cl);

char *corlist_str(struct corlist *cl, int i);

unsigned int hspell_is_canonic_gimatria(const char *word);

typedef int hspell_word_split_callback_func(const char *word, const char *baseword, int preflen, int prefspec);

int hspell_enum_splits(struct dict_radix *dict, const char *word, hspell_word_split_callback_func *enumf);

void hspell_set_dictionary_path(const char *path);

const char *hspell_get_dictionary_path(void);

🌸 DESCRIPTION 🌸

This manual is all about the C API of the Hspell Hebrew spellchecker. If you want the lore β€” the Hspell project itself, its spelling standard, how it works under the hood β€” go read hspell(1). This page is for the girlies writing code against the library. 🫢

πŸ’« getting started: hspell_init()

The hspell_init() function must be called first to initialize the Hspell library. It sets up some global structures (peep the CAVEATS section for the drama there) and then reads the necessary dictionary files β€” and those dictionary file locations are fixed when the library is built. No take-backs.

The dictp parameter is a pointer to a struct dict_radix* object, and it gets modified to point to a newly allocated dictionary. So a typical hspell_init() call looks like:

struct dict_radix *dict;
hspell_init(&dict, flags);
heads up bestie: the (struct dict_radix*) type is an opaque pointer β€” you, the library user, get absolutely no access to the separate fields inside this structure. It's giving main character with a private life. πŸ™ˆ

The flags parameter can be a bitwise or'ing of several flags that modify Hspell's default behavior. Turning on HSPELL_OPT_HE_SHEELA lets Hspell recognize the interrogative He prefix (he ha-she'ela). And HSPELL_OPT_DEFAULT is just a synonym for turning on no special flag at all β€” i.e., it evaluates to 0. periodt.

hspell_init() returns 0 on success, or negative numbers on errors. rn the only error is -1, which means the dictionary files could not be read. πŸ’€

🧹 cleanup: hspell_uninit()

The hspell_uninit() function undoes the effects of hspell_init(), freeing any memory that was allocated during initialization. Closure, we love to see it. πŸ¦‹

βœ… checking a word: hspell_check_word()

The hspell_check_word() function checks whether a certain word is a correct Hebrew word (possibly with prefix particles attached in a syntactically-correct manner). It returns 1 if the word is correct, or 0 if it's incorrect. simple as that.

The word parameter should be a single Hebrew word, in the iso8859-8 encoding, possibly containing the ASCII quote or double-quote characters (those signify the geresh and gershayim used in Hebrew for abbreviations, acronyms, and a few foreign sounds). If your calling program works with other encodings, it must convert the word to iso8859-8 first. In particular, cp1255 (the MS-Windows Hebrew encoding) extensions to iso8859-8 β€” like niqqud characters, geresh or gershayim β€” are currently not recognized and must be removed from the word before you call hspell_check_word(). no cap.

Into the preflen parameter, the function writes back the number of characters it recognized as a prefix particle β€” the rest of the word is a stand-alone word. But because Hebrew words can typically be read in several different ways, this feature (getting just one prefix from one possible reading) is usually not very useful, and it's likely to be removed in a future version. so don't get too attached. 😭

πŸ”ͺ all the splits: hspell_enum_splits()

The hspell_enum_splits() function is your way to get all possible splittings of the given word into an optional prefix particle and a stand-alone word. For each possible (and legal β€” because some words cannot accept certain prefixes) split, a user-defined callback function gets called. That callback receives the whole word, the length of the prefix, the stand-alone word, and a bitfield describing what types of words this prefix can get.

ngl there's a lil quirk: in some cases a word beginning with the letter waw gets this waw doubled before a prefix, so sometimes strlen(word)!=strlen(baseword)+preflen. not a typo, that's just how it is. πŸ’…

🩹 corrections: hspell_trycorrect()

The hspell_trycorrect() function tries to find a list of possible corrections for an incorrect word. Because in Hebrew the word density is high (a random string of letters, especially if short, has a high probability of being a correct word), this function attempts to try corrections based on the assumption of a spelling error (replacement of letters that sound alike, missing or spurious immot qri'a) β€” not a typo (slipped finger on the keyboard, etc.). see also CAVEATS for the real talk.

hspell_trycorrect() returns the correction list into a structure of type struct corlist. That structure must be first allocated with a call to corlist_init() and subsequently freed with corlist_free(). The corlist_n() macro returns the number of words held in an allocated corlist, and corlist_str() returns the i'th word. So, accordingly, here's an example usage of hspell_trycorrect():

struct corlist cl;
printf ("Found misspelled word %s. Possible corrections:\n", w);
corlist_init (&cl);
hspell_trycorrect (dict, w, &cl);
for (i=0; i<corlist_n(&cl); i++) {
    printf ("%s\n", corlist_str(&cl, i));
}

πŸ”’ gimatria vibes: hspell_is_canonic_gimatria()

The hspell_is_canonic_gimatria() function checks whether the given word is a canonic gimatria β€” i.e., the proper way to write in gimatria the number it represents. The caller might want to accept canonic gimatria as proper Hebrew words, even if hspell_check_word() previously reported such a word to be a non-existent word.

hspell_is_canonic_gimatria() returns the number represented as gimatria in word if it is indeed proper gimatria (in canonic form), or 0 otherwise. slay.

πŸ“‚ dictionary paths: hspell_set_dictionary_path() / hspell_get_dictionary_path()

Normally hspell_init() reads the dictionary files from a path compiled into the library. That makes total sense when the library's code and the dictionaries are distributed together β€” but sometimes you, the library user, want to use Hspell dictionaries that are already present on the system in some arbitrary path. Enter hspell_set_dictionary_path(): it sets this path, and you should call it before calling hspell_init().

The given path is that of the word list, and the other input files have that path with an appended prefix. hspell_get_dictionary_path() can be used to find the current path. On many installations, this defaults to /usr/local/share/hspell/hebrew.wgz. πŸ’–


πŸ”— LINKING πŸ”—

On most systems, the Hspell library is compiled to use the Zlib library for reading the compressed dictionaries. Therefore, a program linking with the Hspell library must also be linked with the Zlib library (usually, by adding -lz to the compilation line). don't forget it, she'll be mad. 😀

Programs that use autoconf to search for the Hspell library should remember to tell AC_CHECK_LIB to also link with the -lz library when checking for -lhspell. iykyk.


⚠️ CAVEATS ⚠️

okay this is the section where we spill all the tea. buckle up. πŸ“

While the API described here has been stable for years, it may change in the future. Users are encouraged to compare the values of the integer macros HSPELL_VERSION_MAJOR and HSPELL_VERSION_MINOR to those expected by the writer of the program. A third macro, HSPELL_VERSION_EXTRA, contains a string which can describe subrelease modifications (e.g., beta versions).

The current Hspell C API is very low-level β€” in the sense that it leaves the user to implement many features that some users take for granted that a spell-checker should provide. For example, it doesn't provide any facilities for a user-defined personal dictionary. It also has separate functions for checking valid Hebrew words and valid gimatria, and no function to do both. It's assumed that the caller β€” a bigger spell-checking library or word processor, for example β€” will already have these facilities. If not, you may wish to look at the sources of hspell(1) for an example implementation. πŸ‘‘

Currently there is no concept of separate Hspell "contexts" in an application. Some of the context is now global for the entire application: currently, a single list of legal prefix-particles is kept, and the dictionary read by hspell_init() is always read from the global default place. This may be solved in a later version, e.g., by switching to an API like:

context = hspell_new_context();
hspell_set_dictionary_path(context, "/some/path/hebrew.wgz");
hspell_init(context, flags);
...
hspell_check_word(context, word, preflenp);

Note that despite the global context mentioned above, after initialization all functions described here are thread-safe, because they only read the dictionary data, not write to it. 🧚 (we love a read-only queen)

hspell_trycorrect() is not as powerful as it could have been, with typos or certain kinds of spelling mistakes not giving useful correction suggestions. Along with more types of corrections, hspell_trycorrect() needs a better way to order the likelihood of the corrections, as an unordered list of 100 corrections would be just as useful (or rather, useless) as none. πŸ’€

In some cases of errors during hspell_init(), warning messages are printed to the standard errors. This is a bad thing for a library to do. (not me exposing my own flaws on the main page 😭)

There are too many CAVEATS in this manual.


🌟 VERSION 🌟

The version of hspell described by this manual page is 1.4. ✨


Copyright (C) 2000-2017, Nadav Har'El <nyh@math.technion.ac.il> and Dan Kenigsberg <danken@cs.technion.ac.il>.

Hspell is free software, released under the GNU Affero General Public License (AGPL) version 3. Note that not only the programs in the distribution, but also the dictionary files and the generated word lists, are licensed under the AGPL. There is no warranty of any kind.

See the LICENSE file for more information and the exact license terms.

The latest version of this software can be found in http://hspell.ivrix.org.il/


πŸ‘€ SEE ALSO πŸ‘€


and that's the whole page bestie!! πŸŽ€ this was Hspell 1.4, dated 24 June 2017, straight from the Ivrix manual β€” go forth and spellcheck, you've got this πŸ’…πŸ¦‹βœ¨