Skip to content

christianrosdahl/legilo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Legilo

Legilo is a reading tool (in fact, that's the meaning of the name in Esperanto) that facilitates language practicing by allowing you to read any text in the language you are learning and making it easy to identify and look up words and expressions that you don't know yet. The UI is illustrated below:

Legilo UI example

How does it work?

The application allows you to import any text you want in your target language. The program labels all words in the text to one of the following categories: new, learning, known or ignored. The new words are marked with a blue background, the learning words are marked with a yellow background, and the known or ignored words are unmarked.

New words are words that haven't been seen previously in any text. Learning words are words that you have seen in some text before, and looked up, but that you don't consider that you know yet. Known words are words that you have skipped without looking up or that you have marked explicitly as known. Ignored words are words that you consider irrelevant, e.g. names, words in another language or numbers. This category is similar to known words, but the words will be stored in a separate list, without translations, and will not be counted into the sum of your known words (that is shown in the bottom left corner of the main window).

When reading a text, you iterate through the new and learning words using the keyboard (see below), or select words by clicking them. The current word is marked with an orange background. You can look up a marked word easily or change the label of it using the keyboard as well.

Language support: I have tested the app with Spanish, German, French, Italian, Russian, Croatian, and Swedish. However, it should also work well for many other languages. Just add the language you want to learn to the config.json file (see "Configuration" below) and try it out!

How to use it?

Disclaimer

The program has mainly been tested on macOS, and is best adapted to this operating system. However, it should be possible to run on Linux and Windows as well, but it's possible that things like font and font size might have to be adapted to look good on these platforms (which can be done by modifying the config.json file, see below). I made the program for my personal use, with the main focus on getting it to do what it should rather than optimizing the code, and there are no guarantees that it will work well. However, you are very welcome to try it out at your own risk.

Get started

MacOS / Linux

To run the program, you need a compatible version of Python. The program was tested with Python versions 3.12 and 3.11, so any of those should work, but it is possible that it works with older versions as well. It does not yet work with version 3.13, since one of the packages used is not compatible with that version. You can check your Python version by typing python3 --version in the terminal. If you think that you have a suitable Python version, you can skip to the next paragraph. You can install and use a specific Python version locally in the downloaded folder if you have installed pyenv (see the link for installation instructions). When pyenv in installed, you can type pyenv install 3.12 to install python version 3.12 and then pyenv local 3.12 when you are in the downloaded folder, before running ./run.sh as described in the next paragraph, to always use that version in the current folder.

Start by downloading the files, e.g. using git clone or clicking the green button "Code" at the top of this page, choosing "Download ZIP" and unzipping the downloaded files. Then navigate to the folder in the terminal (type cd <path to the folder with the files>). After that, you type ./run.sh and press ⏎ Enter. This will activate a Python virtual environment (it is created if it doesn't exist already), and make sure that all necessary dependencies are installed in this virtual environment. After that, the program UI will open up in a window. The first time you run the program for a new language, it can take a while to start. This is due to that it will download some natural language processing models that are used to find the dictionary form (lemma) of words, so that variants of a word can be looked up. You can skip this feature (and thus the downloading of the models) by setting "use_lemmatizer": false in config.json.

Windows

Make sure that you have Python version 3.12 installed. You can check what versions are installed by typing py -0 in the terminal. If not, you can download and install it from here.

Start by downloading the files, e.g. using git clone or clicking the green button "Code" at the top of this page, choosing "Download ZIP" and unzipping the downloaded files. After that, open the folder and double click the file run_on_windows.bat. This will activate a Python virtual environment (it is created if it doesn't exist already), and make sure that all necessary dependencies are installed in this virtual environment. After that, the program UI will open up in a window. The first time you run the program for a new language, it can take a while to start. This is due to that it will download some natural language processing models that are used to find the dictionary form (lemma) of words, so that variants of a word can be looked up. You can skip this feature (and thus the downloading of the models) by setting "use_lemmatizer": false in config.json.

Language and text selection

Choose language by pressing the indicated key (the letter or number within []) for each language name. Choose whether you want to add a new text or open a previous text by pressing N or O. Press ⏎ Enter to confirm your choices. In this start window, you can also choose to activate dark mode by pressing D and to deactivate text-to-speech pronunciation by pressing P. Deactivating pronunciation might make lookup of words faster.

New text

  • Alt. 1 (Manual text insertion): Paste a text in the text field, modify it if you want, and press ⏎ Enter to continue. If you want to add a new line in the text, this can be done by ⇧ Shift + ⏎ Enter.
  • Alt. 2 (Automatic text fetching): Paste a URL in the text field and press ⏎ Enter. If the site could be fetched, the text will appear in the text field. Edit it as you want and then press ⏎ Enter to continue.
  • Alt. 3 (Import text from an e-book or PDF): Press ⌘ Command + I to open a file selector and select an EPUB or PDF file. If the text could be fetched, the text will appear in the text field. Edit it as you want and then press ⏎ Enter to continue. Note that text extraction from PDF files in general is difficult and not always possible. Thus, EPUB files are preferable if available.

Old text

Select one of the listed recent texts by pressing the number before it, or press O to open another text file. Press ⏎ Enter to confirm your choice.

Basic navigation

Most of the keyboard commands below can also be found in the window menu of the main window. The menu items also contain the corresponding keyboard shortcuts as a reference. The keyboard shortcuts can be changed (and additional shortcuts can be added) by modifying the file keybindings.json. Note that when specifying the shortcuts in keybindings.json, "Ctrl" corresponds to ⌘ Command for macOS.

  • / Space: Mark the next new or learning word. If the currently marked word is new, and hasn't been looked up, it is marked as known when going to the next word. If it has been looked up, it is saved as a learning word (to prevent this, you can explicitly mark it as known by pressing ).
  • / ⏎ Enter:
    • If the dictionary is closed: Look up the marked word in the dictionary.
    • If the dictionary is open: Save the translation for the looked up word and mark it as a learning word.
  • : Label the marked word as known.
  • ⌫ Backspace: Label the marked word as ignored.
  • : Go back to the previous learning word.
  • Click on a word to skip to it directly. All new words before it will be automatically labeled as known.
  • ⇧ Shift + Mark the next word, regardless of whether it is a known, ignored, new or learning word.
  • ⇧ Shift + Mark the previous word, regardless of whether it is a known, ignored, new or learning word.
  • ⌘ Command + Show next page.
  • ⌘ Command + ⏎ Enter Mark all new words on current page as known and show next page.
  • ⌘ Command + Show previous page.
  • I: Insert (or edit) your own translation for a looked-up word. Press ⏎ Enter to save it. If the input text field is empty, no personal translation will be saved.
  • U: Edit lemmas (associated base forms of the word) and their translations for a looked-up word. An editable text field is enabled where one lemma is listed per line (press ⇧ Shift + ⏎ Enter to make a new line). Each lemma can be associated with a translation by writing <lemma>: <translation> in the line of the lemma. If the line doesn't contain a colon, no translation is saved for the corresponding lemma. A suggestion for autocompletion of a line will be shown if available. Press ⇥ Tab to accept the suggestion. If no suggestion is available, a suggestion can be fetched by pressing ⇥ Tab. If the line doesn't contain a colon, a suggestion of auto-completion of the word is fetched from Wiktionary. If the line does contain a colon, a machine translation is fetched and shown as suggestion (if available). When typing a colon, the lemma before it will automatically be looked up in Wiktionary and the result (if found) will be shown below the input field, so that you can use it to write your personal lemma translation. Press ⏎ Enter to save associated lemmas and possible translations.
  • O: Add (or remove) a machine translation for a looked-up word.
  • Y: Add the machine translation to the personal translation of the looked-up word or the corresponding lemma (in the latter case, the lemma is automatically associated with the looked-up word).
  • P: Pronounce the maked word.
  • H: Add a translation of a looked-up word, and its translations in English, to your third language (set in config.json) in the remark section. Press the key again to remove it.
  • R: Edit the remark for a looked-up word. Press ⏎ Enter to save. Use ⇧ Shift + ⏎ Enter if you want to make a new line.
  • A: Look up the sentence containing the marked word as a phrase (see "Phrase mode" below).
  • 1-9: Select and show different example sentences for the looked-up word. Pressing 9 will use the current sentence in the text and its Google translation as example sentence. Press 0 to not show any example sentence at all.
  • ⌘ Command + / ⌘ Command + : Scroll the text.
  • ⇧ Shift + / ⇧ Shift + : Scroll the translation.
  • ⌥ Option + / ⌥ Option + : Scroll the remark.
  • ⌘ Command + W: Save all data and close the text window. You will get back to the start window where you can select another text or close the program by repeating the command. Clicking the close button in the upper corner of the window has the same effect as this command.
  • ⌘ Command + E: Edit the opened text.

Phrase mode

Phrase mode allows you to look up and save translations for phrases or expressions consisting of several words (see example image below). A saved phrase will show up underlined in any future occurrence, and you can see the translation again by selecting it in phrase mode.

Phrase mode example

  • Press E to activate or deactivate phrase mode. When phrase mode is active, the word marker will change colors from orange to green.
  • Translate a new phrase:
    • Alt. 1 (using the keyboard): In phrase mode, use / to navigate to the first word in the phrase, and press ⏎ Enter / to select it. Repeat the same procedure to select the last word in the phrase. After this, phrase mode will be deactivated and the phrase will be looked up.
    • Alt. 2 (using the mouse): In phrase mode, click the first and last word in the phrase you want to look up. After this, phrase mode will be deactivated and the phrase will be looked up.
  • See translation for a previously saved phrase:
    • Alt. 1 (using the keyboard): In phrase mode, use / to navigate to any word in the phrase, and press ⏎ Enter / to select it. Phrase mode will be deactivated and the saved translation for the phrase will be shown.
    • Alt. 2 (using the mouse): In phrase mode, click any word in the underlined phrase. Phrase mode will be deactivated and the saved translation for the phrase will be shown.
  • / Space: Close the phrase translation and go back to the currently marked word.
  • / ⏎ Enter: Save the phrase translation.
  • : Remove the phrase from saved phrases.

External resources

In config.json, you can add external resources, such as different dictionaries, verb conjugators or search engines, that open an URL containing the marked word in a browser when pressing a key on the keyboard (or when selecting it in the "External Resources" menu). If the translation for the word is open and contains a lemma form (e.g. the infinitive for a conjugated verb or the singular nominative for a noun form), you can instead look up the lemma form in the same resource by pressing ⇧ Shift + the chosen keyboard key.

As default in the config.json file, the following resources are added with the preceding letter as keyboard shortcut:

  • W Wiktionary
  • G Google
  • F Google Images
  • Q Wikipedia
  • L Look up in some language-specific dictionary
  • V Some language-specific verb conjugator (for most languages)
  • C Context Reverso (for most languages)

See "Configuration" below for instructions about how to add new external resources.

Saving, exporting word lists or closing without saving

  • ⌘ Command + S: Save your current progress (collections of words and phrases according to their labels) and the current state (the currently marked word). This is done automatically when closing the window for the application.
  • ⌘ Command + R: Save your current progress (collections of words and phrases according to their labels) as readable text files (the normal saving yields non-readable files). Simple lists containing only one word per line for known, new and learning words are saved to the data folder.
  • ⌘ Command + X: Close the window without saving your progress.

Configuration

In the file config.json, you can set the following things:

  • "languages": What languages you want to use the program for.
    • "<language name>": Name of the language.
      • "external_resources": External resources specific to the language in question. Formatted as "common_external_resources" (see below).
  • "common_external_resources": Settings for exteral resources that are common to all languages.
    • "url": URL for the common resource, where %s is used as a place holder for the word or lemma to look up.
    • "resource_name": Name of the resource that can be used to connect a keyboard shortcut to it, by adding this name and the corresponding shortcut to keybindings.json.
    • "phrase_word_delimiter": The delimiter used instead of space in the URL of the resource when looking up phrases.
  • "machine_translator" (can have values "Google" or "GPT"): Defines the method for machine translation. The default method ("Google") uses Google Translate, and is free. Alternatively, you can use one of OpenAI's GPT models by setting this value to "GPT". This requires an OpenAI API key, that should be exported as an environment variable OPENAI_API_KEY. On macOS/Linux, this can be done by typing export OPENAI_API_KEY="<your API key>" in the terminal.
  • "machine_translator_lang": Language to translate into for machine translations.
  • "third_language": Extra language for which translations can be added to the remark.
  • "use_lemmatizer" (can have values true or false): Use natural language processing models to find the dictionary form of a word so that it can be looked up. When this is activated, the program will download the models for a language the first time it is used with that language, which might take a few minutes. It might make the program a few seconds slower to start after that as well, since the models have to be loaded.
  • "font": Font to use for all text in the program.
  • "font_size": Font size for the main text in the reader. Other text sizes are adapted relative to this.
  • "page_size": Maximum number of characters per page. This is applied when creating a new text. The text is then divided into pages with this max size.
  • "short_text_limit": Maximum number of characters for a text to be classified as short. If a new text is short, it is not divided into several pages, but imported as one page.
  • "autoscroll" (can have values true or false): When going to next or previous word, scroll the page automatically to keep the active word in the center of the upper half of the text field if possible.

Background and key features

Legilo was inspired by the web and mobile app LingQ that is based on the same principle of marking new and learning words in texts and facilitating looking up translations for them and phrases in the text. It is a commercial product that has a lot of features that this app doesn't have, such as incorporation of audio files for the text, easy import of material from many sources, built-in content suitable for different language learning levels, as well as the possibility to practice learning words with flashcards etc. However, for me personally, there were some important features that I was missing in LingQ. That's why I decided to implement my own app. These features are described below.

Key features

Simple lookup from Wiktionary

Wiktionary is a great free dictionary that has a lot of content for many languages. It's usually my favorite dictionary to use when learning languages, and I wanted to be able to incorporate the definitions from Wiktionary directly into the lookup section of the app. While it's sometimes sufficient to just get a plain translation of a word from e.g. Google Translate or some similar system, in many cases, I want to get some more information about a word. This might include e.g. several different translations with more nuanced explanations, the gender of a noun, information about what verb conjugation, grammatical number or case the word is, and what base word it is related to.

Association with lemmas (base forms of a word)

To connect different forms of a word (e.g. different verb conjugations, different gender variants, plural forms or cases) we want to be able to associate each word with its base form, or lemma. One or several lemmas can be added to a word. After the associations, the translations of the lemmas are included when looking up the variant. If the Wiktionary entry of the word variant refers to the lemma (e.g. by saying "third-person singular present tense of {lemma}"), it is fetched automatically. If that isn't the case, we use a lemmatizer from the natural language processing package Stanza to try to find a lemma. If, despite this, no lemma is found or you want to modify the suggested lemma or add another one, you can easily do that.

Showing etymology

Sometimes it's helpful or just fun to look at the etymology of a word. It might increase the understanding of the word by associating it to other words and make it easier to remember. If the Wiktionary article for a word contains an etymology, this is included in the "Notes & Remarks" section of the the lookup column.

Example sentences

Sometimes it's useful to see a word used in another example sentence than in the current text to better understand its meaning. To this end, an example sentence with translation for the looked-up word is fetched and shown at the bottom of the lookup column. It can easily be changed to another example sentence by pressing the number keys.

Customizable external resources

I want to easily, by just pressing a keyboard key, be able to look up a word in one out of several customizable external resources. These could e.g. be alternative dictionaries, verb conjugators, Google, Wikipedia, or Google Images to get a visual association of the word. Such resources can easily be defined in the config.json file. When pressing the associated key, it opens up the lookup result in a new tab in the browser. If using macOS, subsequent lookups are made in the last opened tab, so that you don't have to close the tab before switching back to the app to avoid having many tabs open. Since it in some resources isn't possible to look up specific word variants, but only lemma forms, you can choose to open an external resource for one of the associated lemmas instead, by holding down ⇧ Shift while pressing the associated key.

Fully controllable by keyboard

I want to be able to do everything in the app by just using the keyboard, not having to click with a mouse or trackpad. The option of selecting words or sentences by clicking does exist, since it can be easier if you want to select something far away from the currently marked word, but everything in the program can be done with keyboard commands only.

Alternative similar apps

As previously mentioned, I made this app mainly for myself, and the code quality and reliability is far from what you would expect for a professional product. If you want to use a reading tool that is simple and reliable, and the features listed above aren't essential to you, LingQ is probably the best option. Another commercial reading tool, that offers a free option, which seems interesting but that I don't have any experience with, is Readlang. After implementing Legilo, I also found out that there are some other people who were in a similar situation as me and decided to implement their own reading tools and sharing them for free. I haven't tried out any of these myself, but Lute (version 3) seems to be the best option out of these that I have found. A cool feature that distinguishes it from other alternatives is that you can associate a word with an image. Some other similar options include LWT (improved version), LWT (original version), and FLTR.

About

A language learning tool for reading texts and easily looking up unknown words and phrases.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages