↑ TOP ↑
Preface Curr. Version Abstract Installation Post-Installation Features New Features Screencasts Links Restrictions License Third Party How to learn How to use Q & A
Setup Tablets Lang. Setup Term Scores Key Bindings Export Template
Contribute WordPress Integration Public API Database Changelog

Logo Learning with Texts


Jump to topic:

▶ Preface - [↑]


Preface by lang-learn-guy (original author)

Contributions by HugoFara (GitHub version maintainer)

I started using LWT in 2021, and continued its development almost instantly. I felt that the core idea was very good, but its implementation seemed unadapted, and the code was quite obfuscated. While I do not have any official responsibility to LWT (we don't have any kind of official agreement with lang-learn-guy), I am the the de facto maintainer of the community version. I dedicated myself to the following points (see the GitHub post):

If you spot any problem, please post any issue on GitHub, and we will look at it.

While work is not yet finished, I also aim to expand LWT:

But there is much more! The community version of LWT is no longer the feat of one man, it belongs to everyone. As such, it gets well easier to implement new features, discuss and exchange code and ideas. I don't know if LWT contains your killer feature, but I can say that it can be implemented with this version. Enjoy!

▶ Current Version - [↑]

The current version is 2.10.0-fork (April 01 2024).
View the Changelog.

▶ Abstract - [↑]

Learning with Texts (LWT) is a tool for Language Learning by reading texts. It is inspired by:

You define languages you want to learn and import texts you want to use for learning. While listening to the optional audio, you read the text, save, review and test "terms" (words or multi word expressions, 2 to 9 words).

In new texts all your previously saved words and expressions are displayed according to their current learn statuses, tooltips show translations and romanizations (readings), editing, changing the status, dictionary lookup, etc. is just a click away.

Import of terms in TSV/CSV format, export in TSV format, and export to Anki (prepared for cloze tests), are also possible.

To run LWT, you'll need:

  1. A modern web browser. Do not use Internet Explorer, any other browser (Chrome, Firefox, Safari or Edge) should be fine.
  2. A local web server. An easy way to install a local web server are preconfigured packages like
  3. The LWT Application. The latest version lwt_v_x_y.zip can be downloaded at https://github.com/HugoFara/lwt/archive/refs/heads/master.zip. View the install section.

▶ LWT Installation - [↑]

Let's install the LWT server. LWT uses a client-server architecture, which means it will run in your browser as a classical website. You can use any computer as the server, here are some ways to do it.

A bird's-eye view

Whatever installation you choose, the steps will look like the following:

  1. Set-up a server with a database system.
  2. Download LWT.
  3. Create connect.inc.php file with your password.
  4. Start the server and ready to go!

There are two main ways to install LWT: on your computer or using containers. We recommend the first solution as the most straightforward. The second solution has a simpler installation method, but takes a lot of storage.

Windows 10/11

Two main softwares can be used to set up a local server on your computer: XAMPP and EasyPHP. We recommand XAMPP because it supports higher PHP version, but feel free to use any softare you like.

Using XAMPP (recommended)

  1. Install XAMPP

    1. Go to https://www.apachefriends.org/download.html
    2. Download "XAMPP for Windows". PHP starting from 8.0 is supported.
    3. Open your Downloads folder and run the downloaded "xampp-windows-x64-xxx-installer.exe". Please install the components Apache, MySQL, PHP and phpMyAdmin into the folder C:\xampp.
  2. Get the latest GitHub release, unzip it.

    You can also try to download the latest stable version if you want the cutting-edge updates (that may include some bugs)

  3. Now go into "C:\xampp\htdocs\lwt". Rename the file "connect_xampp.inc.php" to "connect.inc.php". Sometimes the "php" extension is hidden, so be careful! You can display file extensions via the Windows Explorer settings and check it.

  4. Start LWT server

    1. Start the "XAMPP Control Panel" ("C:\xampp\xampp-control.exe") and start the two modules Apache and MySQL. Now the two module names should have a green background color.
    2. LWT can now be started. Open a browser, and open http://localhost/lwt (please bookmark).
  5. You may now define the first language you want to learn or install the LWT demo database.

If you start up Windows, you must repeat steps 4 and 5.

If you want to start "XAMPP Control Panel" every time you start Windows and to avoid Step 4.1, put a "XAMPP Control Panel" link to "C:\xampp\xampp-control.exe" into "C:\Users(YourUID)\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup". To autostart also the Apache and MySQL modules, please open "Config" within the XAMPP Control Panel and check the two checkboxes.

Hint: To fix a "XAMPP Control Panel" error "Xampp-control.ini Access is denied", please read and do the instructions in https://www.codermen.com/fix-xampp-server-error-xampp-control-ini-access-is-denied/

Now you must only do step 4.2 to start LWT.

Using EasyPHP

  1. Get Visual C++

    1. Download "vcredist_x86.exe" from https://www.microsoft.com/en-us/download/details.aspx?id=30679
    2. Choose the x86 version and download.
    3. Run the installer "vcredist_x86.exe" in the Downloads folder.
  2. Get EasyPHP

    1. Go to https://www.easyphp.org/easyphp-devserver.php
    2. Download "EasyPHP DevServer 17.0".
    3. Open your Downloads folder and run the downloaded "EasyPHP-Devserver-17.0-setup.exe".
    4. Install into "C:\Program Files (x86)\EasyPHP-Devserver-17".
  3. Get the latest GitHub release, unzip it.

    You can also try to download the latest stable version if you want the cutting-edge updates (that may include some bugs)

  4. Install everything

    1. Go to "C:\Program Files (x86)\EasyPHP-Devserver-17\eds-www\lwt".
    2. Rename the file "connect_easyphp.inc.php" to "connect.inc.php". Sometimes the "php" extension is hidden, so be careful! You can display file extensions via the Windows Explorer settings and check it.
  5. Start EasyPHP

    1. Start EasyPHP via Desktop Icon (Devserver 17). In the Task Bar near the clock appears the EasyPHP app icon (it may be hidden!).
    2. LWT can now be started. Right-Click on the EasyPHP icon in the taskbar, choose "Servers->Start/Restart all Servers", open a browser, and open (please bookmark).
  6. You may now define the first language you want to learn or install the LWT demo database.

If you start up EasyPHP, you must repeat step 5.1 and 5.2.

If you want to start EasyPHP every time you start Windows and avoid step 5.1, put an EasyPHP link into "C:\Users(YourUID)\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup".

Now you must only do step 5.2 to start LWT.

macOS 10.10+

This section may be obsolete! Your help is welcome!

  1. Go to https://www.mamp.info/en/downloads/

  2. Download "MAMP & MAMP PRO" (currently version 6.6).

  3. Double-click on the downloaded installation package "MAMP_MAMP_PRO_xxx.pkg", accept the license, click on "Install for all users..." and on "Continue", on the next panel titled "Standard Install on Macintosh HD" click on "Customize", deselect "MAMP PRO", and click Install. You must enter your password. After this step MAMP is installed within a folder named "MAMP" in the Applications folder.

  4. Get the latest GitHub release, unzip it.

    You can also try to download the latest stable version if you want the cutting-edge updates (that may include some bugs)

  5. Go to /Applications/MAMP/htdocs/lwt. Rename the file connect_mamp.inc.php to connect.inc.php.

  6. Open MAMP.app in /Applications/MAMP. Accept the messages from the firewall. Apache and MySQL start automatically.

  7. LWT can now be started in your web browser, go to: http://localhost:8888/lwt.

  8. You may define the first language you want to learn or install the LWT demo database.

If you want to use LWT again, just do steps 6 and 7. The local webserver (MAMP) will be automatically stopped by quitting the MAMP application.


Using the Linux Installer

We provide an installer that runs the commands described in the next section. To use the installer:

  1. Download the latest GitHub release, unzip it.
  2. Open a terminal in the downloaded folder, enable execution with chmod +x ./INSTALL.sh.
  3. Run the script with ./INSTALL.sh.
  4. You can start using LWT at http://localhost/lwt

Installing on Linux by hand

The following instruction were tested on Raspbian Stretch.

  1. Open a terminal, type and execute the following commands:

    1. Installation of LAMP:

      sudo apt-get update
      sudo apt-get install apache2 libapache2-mod-php php php-mbstring php-mysql php-xml mariadb-server

      Note: you should be able to freely switch between MySQL and MariaDB.

    2. Check if everything is okay:

      • php -v should show a PHP version equal or above to 8.0.0.
      • http://locahlhost should display a nice web page.
      • mysql -V should work.
    3. Enable the extensions

      1. Go to your PHP folder (/etc/php/{{desired PHP version}}/{{PHP type}}/)
      2. Run sudo nano php.ini.
      3. Delete the ";" symbols before extension=mbstring and extension=mysqli.
    4. Set MySQL root Password to "abcxyz"

      sudo mysql

      Then type

      ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'abcxyz';
      FLUSH privileges;
    5. (Optionnal) Check MySQL access

      mysql -u root -p

      If you see the MySQL prompt mysql> after the first command, everything is OK. Quit with

  2. Get the latest GitHub release.

    You can also try to download the latest stable version if you want the cutting-edge updates (that may include some bugs)

  3. Unzip it.

  4. Rename the file connect_xampp.inc.php (in the unzipped folder) to connect.inc.php.

  5. Edit connect.inc.php and set the MySQL password in line $passwd = "";. Change it to $passwd = "abcxyz";. Save the edited file connect.inc.php.

  6. Open a terminal, type and execute the following commands:

    sudo rm /var/www/html/index.html
    sudo mv /[... Path to downloaded LWT ...]/lwt /var/www/html
    sudo chmod -R 755 /var/www/html/lwt
    sudo service apache2 restart
    sudo service mysql restart
  7. LWT can now be started in your web browser, go to: http://localhost/lwt.

  8. You may install the LWT demo database, or define the first language you want to learn.

If you want to use LWT again, just do step 7.

Run in a Docker container

Docker is the easiest way to install LWT, but it will use more or less 1 GB on your system.

Using the installer

For an light-weight installer, you may use HugoFara/lwt-docker-installer.

Build image from source

Download the lwt, open a terminal inside it, then type

docker compose up

By default the server can be accessed on port 8010 (http://localhost:8010/lwt).

To remove the created containers run

docker compose down

Dependency management with Composer

If you have a technical knowledge of how Composer works for dependency management, you may consider using Composer. It is required for contributors only, but advanced users may want to use it as well. The official repository is at https://packagist.org/packages/hugofara/lwt.

Upgrade LWT

  1. Backup the LWT directory. Backup your database (within LWT).

  2. Get the latest GitHub release.

    You can also try to download the latest stable version if you want the cutting-edge updates (that may include some bugs)

  3. Unzip it.

  4. Copy the following (if not already at its place and OK) from your LWT backup into the LWT directory: "connect.inc.php" and the whole "media" sub-directory (if you created one; contains your MP3 audio files).

  5. Clear the web browser cache and open LWT as usual.

Something Went Wrong

Need more help? You can contact us through GitHub and Discord!

You can also consult the troubleshooting section of the documentation at https://hugofara.github.io/lwt/docs/info.html#faq.

Please note that PHP below version 8.0 is no longer supported.

▶ Optional Post-Installation Steps - [↑]

LWT is a all-in-one product, but you can extend its capabilities in various ways. Here are the additional features unavailable by default.

Parse Japanese with MeCab

MeCab is a Japanese parser. Installing it has two main advantages:


Standard Installtion

  1. Follow the instructions to download MeCab at https://taku910.github.io/mecab/#install.
  2. Add MeCab to your system PATH.
  3. In LWT, go to "Edit Languages" → "Japanese" and change from the value for "RegExp Word Characters" to mecab.

Using Docker

Original instructions provided here.

  1. Run your LWT container in interactive mode and install MeCab.

    docker exec -it lwt bash
    apt-get update && apt-get install -y mecab libmecab-dev mecab-ipadic-utf8
  2. In LWT, go to "Edit Languages" → "Japanese" and change from the value for "RegExp Word Characters" to mecab.

Automatic Translation


LibreTranslate is a great open-source tool that allows you to translate text and provides an API. With it you can achieve the following:

LibreTranslate Demo

To use it, please read the following steps:

  1. Install it on a local or remote server or using Docker.
  2. In LWT, go to "Edit Langagues", either create a new or edit an existing language
  3. In the field "Sentence Translator URI", replace it by the URL of you libre translate instance.
    • Do not forget to add the parameter lwt_translator=libretranslate for the automatic translation!
    • source= should be followed by two letters indicating the language translating from.
    • target= should be followed by two letters indicating the language to translate to.

Enhanced Text-to-Speech

The Text-to-Speech may sound robotic with some languages or operating systems. A workaround is to download a Text-To-Speech (TTS) plugin such as Read Aloud.

▶ Features - [↑]

▶ New feature not available in the official LWT - [↑]

User Interface

More than LWT


▶ Screencasts/Videos - [↑]

Learning With Texts by Anthony Lauder (FluentCzech):

Learning With Texts: iPad, computer & mobile FREE language reading interface from Benny the Irish polyglot:

Fluent In 3 Months: Introducing LWT.

LWT Online Demo - try it out:

LWT Reviews and Blog Posts

LWT Forum Threads

Additional Resources

Similar software or services:

Resources for various languages

▶ Restrictions - [↑]

Texts and vocabulary terms with Unicode characters outside the Basic Multilingual Plane (BMP; U+0000 to U+FFFF), i.e. with Unicode characters U+10000 and higher, are not supported. Therefore, characters for almost all modern languages, and a large number of symbols, are supported; but historic scripts, certain symbols and notations, and Emojis are not supported.

▶ License - [↑]

This is free and unencumbered software released into the PUBLIC DOMAIN.

Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.

In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.


For more information, please refer to [http://unlicense.org/].

▶ Third Party Licenses - [↑]

The following software packages, bundled within the LWT software, have different licenses:

The icons in the "icn" subdirectory are Copyright © Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 license. The wizard icon "wizard.png" is the "Free Wizard Icon", free for commercial use, from icojam.com (Author: IcoJam / Andrew Zhebrakov).

The following examples, supplied within the LWT download package, have the following licenses:

▶ How to Learn - [↑]

First, find a text you want to study, preferably with an audio file, and load it into LWT. The LingQ Library has many texts with audio, and only a free registration is needed. Or look into Where to find good content to import (LingQ forum) in the LingQ Forum, you will find there lots of great links to resources. Or click (within the LingQ library) on "My Imports" - you will find a list of links of "Suggested resources".

Read the text, look up the new words and expressions (=terms) and save them for review and test. The good thing with LWT: Every saved term will show up with its translation, status, etc. in all other occurrences of the same text and every other text! So you'll see immediately what you already know and how well you know it. And of course you'll see what you don't know!

Train: load the MP3 file also on your portable MP3 player and listen to it often. Review (by reading again) or test your saved words and expressions.

In short:

That's it. It's that simple. You can also watch Steve Kaufmann's videos on YouTube: "The 7 secrets of language learning", "Language learning FAQ", and many more to learn more eficiently.

▶ How to Use - [↑]

Home Screen

LWT home screen after installation:


This is home screen of LWT if the database is empty. Please install the demo database or start with the definition of a language you want to learn.

LWT home screen


This is normal home screen of LWT. You may choose a language here, but you can do this also later. If you you choose a language, the language filter is pre-set to that language in some other screens. The last text you've read or tested is shown, and you may jump directly into reading, testing or printing of this last text.


The list of languages. Here you can add a new or edit an existent language. If no texts and no saved terms in a language exist, you can delete a language. If you change a language, all texts may be automatically reparsed to refresh (and correct) the cache of sentences and text items (depends on what language settings you have changed). You can do this also manually by clicking on the yellow flash icon. You can also test all (due) terms of a language or set a language as "current" language.


New/Edit Language

This is the place to define or edit a language you want to study.

It is recommended to use the "Language Settings Wizard" first. You only select your native (L1) and study (L2) languages, and let the wizard set all language settings that are marked in yellow. You can always adjust the settings afterwards.

Explanations of the input fields - please read also this section:

The three URLs are URLs to three web dictionaries (the second and third is optional). Use lwt_term as a placeholder for the search word in the URIs. If lwt_term is missing, the search word will be appended to the end. If the URI to query "travailler" in WordReference is "http://www.wordreference.com/fren/travailler", you may enter: "http://www.wordreference.com/fren/lwt_term" or "http://www.wordreference.com/fren/". Another example: The URI to query "travailler" in sensagent is "http://dictionary.sensagent.com/travailler/fr-en/", so you enter in LWT "http://dictionary.sensagent.com/lwt_term/fr-en/".

As URI No. 3 ("Translator") is also used to translate whole sentences. It is recommended to use either Google Translate or LibreTranslate.

A different third web dictionary is of course possible, but sentence translations may not work.

IMPORTANT: Some dictionaries (including "Google Translate") don't allow to be opened within a frame set. Put an asterisk * in front of the URI (Examples: *http://mywebdict.com?q=### or *http://translate.google.com/?ie=UTF-8&sl=..&tl=..&text=###) to open such a dictionary not within the frame set but in a popup window (please don't forget to deactivate popup window blocking in your browser!).

Deprecated Features
Specify Encoding

This feature has been abandonned, do not use it!

If the searchword in the three URIs needs to be converted into a different encoding (standard is UTF-8), you could use ###encoding### as a placeholder. Normally you see this right away if terms show up wrongly in the web dictionary. Example: Linguee expects the searchword in ISO-8859-15, not in UTF-8, so you define it this way: "http://www.linguee.de/search?direction=auto&query=###ISO-8859-15###". A list of encodings can be found here.

Glosbe API

Glosbe closed there API, this feature does no longer work.

One dictionary (Glosbe) has been closely integrated into LWT via the Glosbe API. To use this dictionary, input the "special" dictionary link "http://localhost/lwt/glosbe_api.php?from=...&dest=...&phrase=lwt_term" with from: "L2 language code" (the language of your texts) and dest: "L1 language code" (e.g. mother tongue). To find the language codes, open this page to select the "from" (L2) language. On the next page, select the "L2 - L1" language pair. The URL of the next page shows the two language codes, here as an example "French - English": http://glosbe.com/fr/en/. The "from" code is "fr", the "dest" code is "en". Using this dictionary makes the transfer of translation(s) from the Glosbe to LWT very easy: just click on the icon next to the translations to copy them into the LWT edit screen. I recommend to use the LWT-integrated Glosbe dictionary as the "Dictionary 1 URI". Note: I cannot guarantee that the Glosbe API and this special integration will work in the future! glosbe_api.php is just an example how one can integrate a dictionary into LWT.

You don't know how and where to find a good web dictionary? Try these dictionary directories:

If you have found a suitable web dictionary, try to translate some words and look whether the word is part of the web address (URI/URL). If yes, replace the word with ### and put this in one of the URI fields within LWT.

The entry "Text Size" defines the relative font size of the text. This is great for Chinese, etc.

"Character Substitutions" is an optional list of "from=to" items with "|" as list separator. The "from" character is replaced by the "to" character ("to" may be also empty). So different kinds of apostrophes can unified or deleted.

"RegExp Split Sentences" is a list of characters that signify a sentence ending (ALWAYS together with a following space or newline!). The space can be omitted (and it is normally), if you set "Make each character a word" to Yes (see below). Whether you include here ":" and ";" - that's your decision. See also this table. Characters can be also defined in Unicode form: "\x{....}"; the Chinese/Japanese full stop "。" is then "\x{3002}" (always without "). Please inform yourself about Unicode here (general information) and here (Table of Unicode characters).

"Exceptions Split Sentences" are a list of exceptions that are NOT to be treated as sentence endings with "|" as list separator. [A-Z] is a character range. If you don't want to split sentences after Mr. / Dr. / A. to Z. / Vd. / Vds. / U.S.A., then you should specify these here: "Mr.|Dr.|[A-Z].|Vd.|Vds.|U.S.A." (without ").

"RegExp Word Characters" is a list of characters OR character ranges "x-y" that defines all characters in a word, e.g. English: "a-zA-Z", German: "a-zA-ZaöüÄÖÜß", Chinese: 一-龥. See also this table. Characters can be also defined in Unicode form: "\x{....}"; the Chinese/Japanese character "one" "一" is then "\x{4E00}" (always without "). So the above specification for the range of characters in Chinese "一-龥" can also be specified: "\x{4E00}-\x{9FA5}".

"Make each character a word" is a special option for Chinese, etc. This makes EVERY character a single word (normally words are split by any non-word character or a space). See also this table.

"Remove spaces" is another option for Chinese, etc. It removes all spaces from the text (and the example sentences). See also this table.

"Right-To-Left Script" must be set to "Yes" if the language/script is written from right to left, like Arabic, Hebrew, Farsi, Urdu, etc.

"Export Template". The export template controls "Flexible" Term Exports for the terms of that language. It consists of a string of characters. Some parts of this string are placeholders that are replaced by the actual term data, see this table. For each term (word or expression), that has been selected for export, the placeholders of the export template will be replaced by the term data and the string will be written to the export file. If the export template is empty, nothing will be exported.

To understand all these options, please study also this, look at the examples and play around with different settings and different texts.



The list of texts. You can filter this list according to language, title (wildcard = *) or text tag(s) (see also below). The most important links for each text are "Read" and "Test" - that's the place to read, to listen, to save terms and to review and test your terms in sentence context. To see all terms of a text that you have saved, click on the numbers in column "Saved Wo+Ex". To print, archive, edit (and reparse), or to delete a text, click on the icons in column "Actions". There are more actions available, see "Multi Actions".


Multi Actions for marked texts

You can test the terms of the marked texts, delete or archive the marked texts. "Reparse Texts" rebuilds the sentence and the text item cache for all marked texts. "Set Term Sentences" sets a valid sentence (with the term in {..}) for all those saved or imported terms that occur in the text and that do not have a sentence at all or none with {term}. This makes it easy to "create" sentence examples for imported terms.


Text Tags

The list of your text tags. You can manage your text tags here. With text tags, it will be easier to categorize and organize your texts. The tags are case sensitive, have 1 to 20 characters, and must not contain any spaces or commas.


New/Edit Text

This is the screen to input, check or edit a single text. Try to store not too long texts (the maximum length is 65,000 Bytes). If texts are very long (> 1000 words), certain operations (e.g. loading a text for reading, calculation of known/unknown words) may be quite slow. An audio URI and a link to the text source can also be defined. The best place to store your audios is the "media" subdirectory below the installation directory "lwt" (you have to create it yourself, and you have to copy the audio files into this directory; click Refresh if you don't see just copied media). But a cloud webspace service like DropBox is also possible. In the moment there is no possibility to import/upload an audio file within the LWT application. By the way, you can use MP3, WAV, or OGG media files, but be aware that not all browsers and/or operating systems support all media types!

If you click "Check", the text will be parsed and split into sentences and words according to your language settings. Nothing will be stored if you check a text. You can see whether your text needs some editing, or whether your language settings (especially the ones that influence parsing/splitting) need an adjustment. Words (not expressions) that are already in your word list are displayed in red, and the translation is displayed. The Non-Word List shows all stuff between words. The "Check a Text" function can also be started directly from the main menu. If you click on "Change" or "Save", the text will be only saved. If you click on "Change and Open" or "Save and Open", the text will be saved and opened right away.


You can also import a longer text into LWT with the possibility to split it up into several smaller texts. Click on "Long Text Import". You must specify the maximum number of sentences per text, and the handling of newlines for paragraph detection. It is not possible to specify audio files or URIs.



Newsfeed Import

Here you can download the articles of your newsfeeds (see the section New/Edit Feeds for an explanation on how To add a new newsfeed). If you've set up multiple newsfeeds for your selected language, the link "update multiple feeds" will appear. By clicking that link you can update one or more feeds at once. If you've selected a newsfeed, a blue circle-arrow will appear as well as the date of your last update. A click on the circle-arrow will update your selected newsfeed. All downloaded articles will be marked by a bookmark-icon instead of the checkbox, so you can access them immediately. If a downloaded article is archived, a red mark will appear. An error may occur, when you try to download an article and the link or the text-section of the article is not found. Then a yellow warning sign appears, which can be removed temporarily by clicking on it or permanently in "Manage Feeds" (see next section). If you hover over an article title, a description of the article will be shown. You can open the article and, if available, the audio in a new window.


Manage Feeds

Multi Actions for marked newsfeeds: You can update feeds, unset unloadable articles (see Newsfeed Import), delete all articles or delete feeds.
Actions: You can edit, update, delete a feed or follow the link to the newsfeed.


New/Edit Feeds

Explanations of the input fields

Feed Wizard

Here you can edit or set up a new newsfeed in 4 steps.

  1. Insert your newsfeed url. This step is skipped, when you edit a newsfeed.

  2. Step 2

    • Name: the name is limited to 40 characters, this can be changed later in step 4 and must not be empty.
    • Newsfeed url: URL of your RSS/Atom-Feed, this can only be changed in step 1 and must not be empty.
    • Article Source: Webpage Link means, that the article will downloaded from the link, all other values mean, that the texts are cached in the database, when you update your feed. You must set the value, before you set the article section. This can only be changed here.

    How to select the article section:

    When you click on the text, it will be marked yellow and a value in the right selectbox will appear. You can change the marked section by selecting a value. If you click on the yellow marked text, the text will be unmarked. To select a text click the "get"-button. The xpath expression of the selected text will then appear on the top and the text will be marked green. You can unselect the selected text by clicking on the red cross. If you click on the xpath expression or on the selected text, a border around the selected text will appear. This can be used to verify the connection between text and xpath exp. in the articles. In order to change an article/webpage use the selectbox on the left. All visited articles start with an arrow "▶". Articles from different hosts probably contain different article sections. Therefore a selectbox can be used to mark the hosts, that are "done", with a star. By clicking on the setting icon, you can choose between three selection modes. "Smart Selection" looks for ids and classes in the element node and parent node. "Get All Attributes" will compare all attributes of the element node/parent node with the text. This mode is not recommended. "Advanced Selection" lets you customize the xpath expression.


  3. This works like step 2. Only the selected sections from step 2 are clickable. Marked text will appear grey, excluded texts will have a red font.


  4. The settings are explained in the New/Edit Feeds.

Read a Text

This is your "working area": Reading (and listening to) a text, saving/editing words and expressions, looking up words, expressions, sentences in external dictionaries or Google Translate. To create an expression, click on the first word. You see "Exp: 2..xx 3..yy 4..zz ...". Just click on the number of words (2..9) of the desired expression you want to save. The dictionary links for multi word expressions are always in the edit frame! You can also use the Keyboard in the text frame, see Key Bindings. Double clicking on a word sets the audio position approximately to the text position, if an audio was defined. The other audio controls are self-explanatory: automatic repeat, rewind and move forward n seconds, etc.).


Reading a Right-To-Left Script (Hebrew):


With the checkbox [Show All] you can switch the display of text:

[Show All] = ON (see below): All terms are shown, and all multi-word terms are shown as superscripts before the first word. The superscript indicates the number of words in the multi-word term.


[Show All] = OFF (see below): Multi-word terms now hide single words and shorter or overlapping multi-word terms. This makes it easier to concentrate on multi-word terms while displaying them without superscripts, but creation and deletion of multi-word terms can be a bit slow in long texts.


Review terms

Tests are only possible if a term has a translation. Terms with status "Ignored" and "Well Known" are never tested, and terms with a positive or zero score are not tested today. In summary, the term score must fall below zero to trigger the test. See also Term scores. Terms that are due today are marked with a red bullet in the term table. Terms that are due tomorrow are marked with a yellow bullet in the term table.

During a test, a status display (at the bottom of the test frame) shows you the elapsed time "mm:ss", a small bar graph, and the total, not yet tested, wrong and correct terms in this test.

In the following, L1 denotes you mother tongue (= translations), and L2 the language you want to learn (= the terms, meaning words and expressions).

Review terms in a text (L2 -> L1)

This is Test #1 or #4: L2 -> L1 (recognition) - to train your ability to recognize a L2 term. You may test within sentence context (Button "..[L2].."), or just the term (Button "[L2]"). You can also use the Keyboard in the test frame, see Key Bindings.


Review terms in a text (L1 -> L2)

This is Test #2 or #5: L1 -> L2 (recall) - to train your ability to produce a term from L1. You may test within sentence context (Button "..[L1].."), or just the term (Button "[L1]"). You can also use the Keyboard in the test frame, see Key Bindings.


Review terms in a text (••• -> L2)

This is test #3: ••• -> L2 (recall) - to train your ability to produce a term only from the sentence context (Button "..[••].."). If you hover over "[•••]", a tooltip displays the translation of the term. You can also use the Keyboard in the test frame, see Key Bindings.


Review yourself in a table / word list format (Button "Table")

This is test #6: The selected terms and expressions are presented as a table. You can make invisible either the columns "Term" or "Translation", and you can hide or show the columns "Sentence", "Romanization", "Status" and "Ed" (Edit). To reveal the invisible solution ("Term" or "Translation"), you just click into the empty table cell. You can review or test yourself with or without changing the status by clicking "+" or "-" in the "Status" column. A status in red signifies that the term is due for testing. You can also edit the term by clicking the yellow "Edit" icon. Columns 2 to 6 may also my sorted by clicking on the header row. The initial sort order is according to term score.


Print a text

Here you print a text. Optional: an inline annotation (translation and/or romanization) of terms that are of specified status(es). This screen is also great to just read or study a text.

Chinese Text with annotation (Romanization/Pinyin and translation):


Chinese Text with annotation (only Romanization/Pinyin):


Create, edit, and use an Improved Annotated Text

Motivation: Annotated texts (as interlinear text) have been used for language learning for a long time. One example are the word-by-word translations in Assimil courses. The German V. F. Birkenbihl proposes the creation of interlinear word-by-word or hyperliteral translations (calling this creation "decoding") in foreign language learning. Learning Latin or Ancient Greek via interlinear texts is quite old as you can see in "014 Latin Interlinear Texts - a forgotten route to language learning.avi".

LWT's old "Print Screen" offers annotations, but it displays ALL translations of a term. The Improved Annotated Text feature enables you to select the best translation for every word in the text. As a result, you create an L1 word-by-word translation that is displayed above the L2 text. This interlinear text is better suited for language study, especially for beginners.

Method: While listening to the audio, first follow the blue annotations in your native language while listening and understanding. Later, after understanding the text fully, you read the foreign language text alone. Repeat this often. After these steps, you listen to the text passively or do shadowing.

On the Print Screen, click on "Create" an Improved Annotated Text. The system creates a default annotated text.

Edit Mode


Within the "Improved Annotated Text - Edit Mode", you can select the best term translation by clicking on one of the radio buttons. To be able to do this, multiple translations must be delimited by one of the delimiters specified in the LWT Settings (currently: /;|). You can also type in a new translation into the text box at the end (this does not change your saved term translation), or you may change your term by clicking on the yellow icon or add a translation by clicking on the green "+" icon (this does change your saved term translation), and select it afterwards. The "Star" icon indicated that you want the term itself as annotation. Important: It's not possible to create new terms here - please do this in the "Read text" screen. Changing the language settings (e.g. the word characters) may have the effect that you have to start from scratch. The best time for the creation of an improved annotated text is after you have read the text completely and created all terms and expressions in the "Read text" screen.

Warning: If you change the text, you will lose the saved improved annotated text! All changes in the Edit screen are saved automatically in the background!

To leave the Edit mode, click on "Display/Print Mode". You may then print or display (with audio) the text, and work with the text online or offline.

Print Mode


Display Mode

With audio player in a separate window. Clicking the "T" or "A" lightbulb icons hides/shows the text or the blue annotations. You may also click on a single term or a single annotation to show or to hide it. This enables you to test yourself or to concentrate on one text only. Romanizations, if available, appear while hovering over a term.



The list of your saved words or expressions (= terms). You may filter the list of terms by language, text, status, term/romanization/translation (wildcard * possible) or term tag(s). Different sort orders are possible. You can do "multi actions" only on the marked or on all terms (on all pages!). "Se?" displays a green dot if a valid sentences with {term} exists. "Stat/Days" displays the status and the number of days since the last status change. The score of a term is a rough measure (in percent) how well you know a term. Read more about term scores here. Terms with zero score are displayed red and should be tested today.


Multi Actions for marked terms

Most actions are self-explanatory. "Test Marked Terms" starts a test with all marked terms. You may delete marked terms and change the status of marked terms. "Set Status Date to Today" is some kind of "trick" for vacations, illnesses, etc.

"Export Marked Texts (Anki)" exports all terms that have been marked AND have a valid sentence with {term} for Anki. Terms that do not have a sentence with {term} will NOT be exported. Cloze testing of terms within sentence context can so be easily done in Anki. The export is tab-delimited: (1) term, (2) translation, (3) romanization, (4) Sentence without term (question of cloze test), (5) Sentence with term (answer of cloze test), (6) Language, (7) ID Number, (8) Tag list. Anki template decks (for Anki Version 1 and 2) are provided: "LWT.anki" and "LWT.apkg" in directory "anki".

"Export Marked Texts (TSV)" exports all terms that have been marked. The export is tab-delimited: (1) term, (2) translation, (3) sentence, (4) romanization, (5) status, (6) language, (7) ID Number, (8) tag list.


Multi Actions for all terms on all pages of the current query

Explanations see above.


Term Tags

The list of your term tags. You can manage your term tags here. With term tags, it will be easier to categorize and organize your terms. The tags are case sensitive, have 1 to 20 characters, and must not contain any spaces or commas.


Text Archive

The list of archived texts. To unarchive, to edit or to delete a text, click on the icon under "Actions". There are also "Multi Actions" available.

What is the difference between (active) texts and archived texts?

(Active) texts

Archived texts


Multi Actions for marked archived texts



It's self-explanatory and shows your performance. The numbers in the first table are links, by clicking on them you jump to the table of all terms in that status and language.


Import Terms

Import a list of terms for a language, and set the status for all to a specified value. You can specify a file to upload or type/paste the data directly into the textbox. Format: one term per line, fields (columns) are separated either by comma ("CSV" file, e.g. used in LingQ as export format), TAB ("TSV" file, e.g. copy and paste from a spreadsheet program, not possible if you type in data manually) or # (if you type in data manually). The field/column assignment must be specified on the left.

Important: You must import a term. The translation can be omitted if the status should be set to 98 or 99 (ignore/well known). Translation, romanization and sentence are all optional, but please understand that tests are only possible if terms have a translation. If a term already exists in the database (comparison is NOT case sensitive), it will not be overwritten; the line will be ignored. You can change this by setting "Overwrite existent terms" to "Yes". Be careful using this screen, a database backup before the import and double-checking everything is always advisable!



This screen offers a possibility to save, restore or empty the LWT database (ONLY the current table set!). This makes it easy to try out new things or just to make regular backups. "Restore" only accepts files that have been created with the "Backup" function above. "Empty Database" deletes the data of all tables (except the settings) of the current table set, and you can start from scratch afterwards. Be careful: you may lose valuable data!



In this screen you can adjust the program according to your needs. The geometric properties of the Read Text and Test screens can be changed. This is important because different browsers and font sizes may result in an unpleasant viewing experience.

The waiting time to display the next test and to hide the old message after a test assessment can be changed.

The number of sentences displayed during testing and generated during term creation can be set to 1 (default), 2 or 3; if set to 2 or 3 you are able to do "MCD" (Massive-Context Cloze Deletion) testing, proposed by Khatzumoto @ AJATT.

The number of items per page on different screens can be set, and you can decide whether you want to see the word counts on the textpage immediately (page may load slow) or later (faster initial loading).


Multiple LWT table sets


When you start using LWT, you store all your data in the "Default Table Set" within the database you have defined in the file "connect.inc.php" during the LWT installation.

Beginning with LWT Version 1.5.3, you are able to create and to use unlimited LWT table sets within one database (as space and MySQL limitations permit). This feature is especially useful for users who want to set up a multi user environment with a set of tables for each user. You can also create one table set for every language you study - this allows you to create different term/text tags for each language. If you don't need this feature, you just use LWT like in earlier versions with the "default table set". Please observe that the "Backup/Restore/Empty Database" function only works for the CURRENT table set, NOT for ALL table sets you have created!

Just click on the link at the bottom of the LWT home screen where the current table set name (or "Default") is displayed. In a new screen "Select, Create or Delete a Table Set" you may switch and manage table sets. A table set name is max. 20 characters long. Allowed characters are only: a-z, A-Z, 0-9, and the underscore "_".


If you want "switch off" this feature, and use just one table set, you may define the name in the file "connect.inc.php":

$tbpref = "";          // only the default table set  
$tbpref = "setname";   // only the table set "setname"  

After adding such a line in the file "connect.inc.php", you are not able to select, create or delete table sets anymore. Only the one you have defined in "connect.inc.php" will be used. Please observe the rules for table set names (see above)!

If more than one table set exists, and $tbpref was NOT set to a fixed value in "connect.inc.php", you can select the desired table set via "start.php" (use this as start page if several people use their own table set), or by clicking on the LWT icon or title in the LWT menu screen "index.php".

By hovering over the LWT icon in the top left corner of every screen, you can display the current table set in a yellow tooltip.

▶ Questions and Answers - [↑]

Site Unreachable

If you see "The webpage is not available", "We have trouble finding that site".


Answer: Your local webserver (Apache) is not running. Please start it via EasyPHP or MAMP control program/panel.

Blank page

You PHP version is probably too low. Try to use PHP 8 at least.

URL not found (404)


Answer: The server is running, but the application is not found. Maybe the Uniform Resource Identifier (URI) is wrong or misspelled. Please check/correct it. Or the URI is correct, and the application is installed, but not in the correct directory lwt below htdocs. Please install/copy/move it into the correct directory.

Database connection error


Answer: Either the database (MySQL/MariaDB) is not running, or the database connection parameters in ../htlwt/connect.inc.php are wrong. Please check/correct the database connection parameters and/or start MySQL via the MAMP or EasyPHP control program/panel.

Cannot find connect.inc.php


Answer: The Webserver and the database is running, but the database connection parameter file ../htlwt/connect.inc.php is not found. Please rename one of the connection files (according to your server) to ../htlwt/connect.inc.php.

Do not run on Linux after installation/update

If LWT installed or updated LWT on Linux, but the application does not run as expected.

Answer 1: The Webserver does not have full access to all LWT files (insufficient rights). Open a terminal window, go to the directory where the directory "lwt" has been created with all LWT files, e. g.
cd /var/www/html
Now execute: sudo chmod -R 755 lwt.

Answer 2: The PHP "mbstring" extension is not installed. Please install it: see this article.

MeCab not detected

LWT cannot find MeCab, you can do the following steps:

On Linux or Mac:

  1. Open a terminal.
  2. Type mecab -v to get the current MeCab version. If nothing is displayed MeCab is not installed.
  3. If MeCab is already installed, the path may be missing. If you are using MAMP type
printf 'export PATH="/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"' >> /Applications/MAMP/Library/bin/envvars

▶ Setup for Tablets - [↑]

Note: this is a deprecated feature, LWT should work with your tablet out of the box!

If you want to use LWT on a tablet: that's possible (even the audio player works!).

In "Settings/Preferences", set the "Frame Set Display Mode" to "Auto" or "Force Mobile". On other mobile devices, you may also try "Force Non-Mobile" if you are unhappy with the results, try to reduce the length of your texts to reduce scrolling.

It's also a good idea to install and run LWT at a web hoster. So you can access LWT easily if you are often on the go.

I hope you will enjoy using LWT on a tablet although creating new terms and copy & paste can be a bit tedious.

▶ Language Setup - [↑]

Language RegExp Split Sentences RegExp Word Characters Make each character a word Remove spaces
Latin derived alphabet (English, French, German, etc.) .!?:; a-zA-ZÀ-ÖØ-öø-ȳ No No
Languages with a Cyrillic-derived alphabet (Russian, Bulgarian, Ukrainian, etc.) .!?:; a-zA-ZÀ-ÖØ-öø-ȳЀ-ӹ No No
Greek .!?:; \x{0370}-\x{03FF}\x{1F00}-\x{1FFF} No No
Hebrew (Right-To-Left = Yes) .!?:; \x{0590}-\x{05FF} No No
Thai .!?:; ก-๛ No Yes
Chinese .!?:;。!?:; 一-龥 Yes or No Yes
Japanese (Without MeCab) .!?:;。!?:; 一-龥ぁ-ヾ Yes or No Yes
Japanese (With MeCab) .!?:;。!?:; mecab Yes or No Yes
Korean .!?:;。!?:; 가-힣ᄀ-ᇂ No No or Yes

▶ Term Scores - [↑]

The score of a term is a rough measure (in percent) how well you know a term. It is displayed in "My Terms", and it is used in tests to decide which terms are tested next.

The score is calculated as follows:


Terms with status 1 are tested either today (if not created today) or tomorrow (if created today, or a test failed today). Terms set to status 2 should be retested after 2 days. Terms set to status 3 should be retested after 9 days. Terms set to status 4 should be retested after 27 days. Terms set to status 5 should be retested after 72 days.

Example 1: Five terms were tested today; they are now in status 1, 2, 3, 4, and 5. The term with status 1 is still unknown (failed the test, so the score is still 0 %). The term with status 5 is well known (score: 100 %).


Example 2: Five terms were not tested for some time; they are in status 1, 2, 3, 4, and 5. All of them have a score of 0, because the number of days indicate that you may have forgotten them. Therefore all should be retested today.


▶ Key Bindings - [↑]

Important: Before using the keyboard you must set the focus within the frame by clicking once on the frame!

Key Bindings in the TEXT Frame

Key(s) Action(s)
RETURN The next UNKNOWN (blue) word in the text will be shown for creation
RIGHT or SPACE Mark next SAVED (non-blue) term (*)
LEFT Mark previous SAVED (non-blue) term (*)
HOME Mark first SAVED (non-blue) term (*)
END Mark last SAVED (non-blue) term (*)
1, 2, 3, 4, 5 Set status of marked term to 1, 2, 3, 4, or 5
I Set status of marked term to "Ignored"
W Set status of marked term to "Well Known"
E Edit marked term
G Edit marked term and open Google Translate
J Edit marked term and open Google Image Search
A Set audio position according to position of marked term.
T Translate sentence
P Pronounce term
ESC Reset marked term(s)

(*) Only saved terms with the status(es) defined/filtered in the settings are visited and marked!

Key Bindings in the TEST Frame

Key(s) Action(s)
SPACE Show solution
UP Set status of tested term to (old status plus 1)
DOWN Set status of tested term to (old status minus 1)
ESC Do not change status of tested term
1, 2, 3, 4, 5 Set status of tested term to 1, 2, 3, 4, or 5
I Set status of tested term to "Ignored"
W Set status of tested term to "Well Known"
E Edit tested term

▶ About LWT Export Templates for "Flexible Exports" - [↑]

An export template consists of a string of characters. Some parts of this string are placeholders (beginning with "%", "$" or "\") that are replaced by the actual term data, see the following table. For each term (word or expression), that has been selected for export, the placeholders of the export template will be replaced by the term data and the string will be written to the export file.

A template must end with either "\n" (UNIX, Mac) or "\r\n" (Windows). If you omit this, the whole export will be one single line!

If the export template is empty, no terms of this language will be exported.

Placeholders Placeholders replaced by ...
%... Raw Text
%w Term (Word/Expression) - as raw text.
%t Translation - as raw text.
%s Sentence, curly braces removed - as raw text.
%c The sentence, but the "{xxx}" parts are replaced by "[...]" (close review question) - as raw text.
%d The sentence, but the "{xxx}" parts are replaced by "[xxx]" (close review solution) - as raw text.
%r Romanization - as raw text.
%a Status (1..5, 98, 99) - as raw text.
%k Term in lowercase (key) - as raw text.
%z Tag List - as raw text.
%l Language - as raw text.
%n Word Number in LWT (key in table "words") - as raw text.
%% Just one percent sign "%".
$... HTML Text. HTML special characters are escaped:< = &lt; / > = &gt; / & = &amp; / " = &quot;
$w Term (Word/Expression) - as HTML text.
$t Translation - as HTML text.
$s Sentence, curly braces removed - as HTML text.
$c The sentence, but the "{xxx}" parts are replaced by "[...]" (close review question) - as HTML text.
$d The sentence, but the "{xxx}" parts are replaced by "[xxx]" (close review solution) - as HTML text.
$x The sentence in Anki2 close review notation: the "{xxx}" parts are replaced by "{{c1::xxx}}" - as HTML text.
$y The sentence in Anki2 close review notation, with translation: the "{xxx}" parts are replaced by "{{c1::xxx::translation}}" - as HTML text.
$r Romanization - as HTML text.
$k Term in lowercase (key) - as HTML text.
$z Tag List - as HTML text.
$l Language - as HTML text.
$$ Just one dollar sign "$".
\... Special Characters
\t TAB character (HEX 9).
\n NEWLINE character (HEX 10).
\r CARRIAGE RETURN character (HEX 13).
\\ Just one backslash "".

▶ Contributing to LWT - [↑]

This guide is mainly aimed at developers, but it can give useful insights on how LWT is structured, which could help with debugging. The first step you need to take is to clone LWT from the official GitHub repository (HugoFara/lwt).

Get Composer

Getting Composer is required if you want to edit LWT on the server side, but it will also be useful to edit JS and CSS code, so it is highly recommended. Composer is a lightweight dependency manager that does not need a server to run.

Once Composer is ready, go to the lwt folder (most likely lwt/), and type

composer install --dev

This will automatically download all the required dependencies.

Create and Edit Themes

Themes are stored at src/themes/. If you want to create a new theme, simply add it to a subfolder. You can also edit existing themes.

To apply the changes you made to a theme, run

composer minify

This command will minify all CSS and JS.

Alternatively, you can run

php -r "require 'src/php/minifier.php'; minifyAllCSS();"

It minifies only CSS.

Debug your theme

You may not want to see your code minified, so you can use

composer no-minify

It has the same effect as copying the folder src/themes/ to themes/. WARNING: It can break your relative paths!

Add Images to your Themes

We support a smart minifying system: relative paths are automatically adapted to point to the previous location while minifying only. As a consequence:

When debugging your theme, files are simply copied to the themes/ folder, which can break the path to files in css/.

My theme does not contain all the Skinning Files

That's not a problem at all. When LWT looks for a file that should be contained in src/themes/{{The Theme}}/, it checks if the file exists. If not, it goes to css/ and tries to get the same file. With this system, your themes do not need to have the same files as src/css/.

Change JS behavior

As with themes, LWT minifies JS code for a better user experience. Please refer to the previous section for detailed explanations; this section will only go through import points.

Edit JS code

Clear code is stored at src/js/. Once again, the actual code used by LWT should be at js/. After you have done any modification, either run composer minify or php -r "require 'src/php/minifier.php'; minifyAllJS();".

Debug JS code

To copy code in a non-obfuscated form, run composer no-minify or replace the content of js/ with src/js/.

Edit PHP code

The PHP codebase is not yet well structured, but here is a general organization:

Testing your Code

It is highly advised to test your code. Tests should be wrote under tests/. We use PHP Unit for testing.

To run all tests:

composer test



Security Check

We use Psalm to find code flaws and inconsistencies. Use ./vendor/bin/psalm.

You can configure the reporting level in psalm.xml.

Advice: Follow the Code Style Standards

Nobody likes to debug unreadable code. A good way to avoid thinking about it is to include phpcs directly in your IDE. You can also download it and run it regularly on your code.

You can run it through composer. Use php ./vendor/bin/squizlabs/phpcs.phar [filename] to see style violations on a file. You can fix them using

php ./vendor/bin/squizlabs/phpcbf.phar [filename]

Interact with and modify the REST API

Starting from 2.9.0-fork, LWT provides a RESTful API. The main handler for the API is api.php. You can find a more exhaustive API documentation at api.md.

If you plan to develop the API, please follow the RESTful standards. To debug:

  1. Install Node and NPM.
  2. Run npm install in the main LWT folder.
  3. Run npm test to test the API.

Improving Documentation

To regenerate all PHP and Markdown documentation, use composer doc. For the JS documentation, you need NPM. Use ./node_modules/.bin/jsdoc -c jsdoc.json.

General Documentation

The documentation is split across Markdown (.md) files in docs/. Then, those files are requested by info.php. The final version is info.html, which contains all files.

To regenerate info.hml, run composer info.html.

PHP Code Documentation

Code documentation (everything under docs/html/ and docs/php/) is automatically generated. If you see an error, the PHP code is most likely at fault. However, don't hesitate to signal the issue.

Currently, the PHP documentation is generated two times:

JS Code Documentation

Code documentation for JavaScript is available at docs/js/ is is generated thourgh JSDoc. The JSDoc configuration file is jsdoc.json.

New version

LWT-fork follows a strict procedure for new versions. This section is mainly intended for the maintainers, but feel free to take a peak at it.

The steps to publish a new version are:

  1. In the CHANGELOG, add the latest release number and date.
  2. In inc/kernel_utility.php, update LWT_APP_VERSION and LWT_RELEASE_DATE.
  3. Update PROJECT_NUMBER in Doxyfile to the latest release number.
  4. Regenerate documentation with composer doc.
  5. Commit your changes, git commit -m "Regenerates documentation for release []."
  6. Add a version tag with annotation git tag -a [release number] and push the changes.
  7. If all the GitHub actions are successfull, write a new release on GitHub linking to the previously created tag.
  8. The new version is live!

Other Ways of Contribution

Drop a star on GitHub

This is an open-source project. It means that anyone can contribute, but nobody gets paid for improving it. Dropping a star, leaving a comment, or posting an issue is essential because the only reward developers get from time spent on LWT is the opportunity to discuss with users.

Spread the Word

LWT is a non-profitable piece of software, so we won't have much time or money to advertise it. If you enjoy LWT and want to see it grow, share it!


Either go to the forum of the official LWT version, or come and discuss on the community version.

Support on OpenCollective

LWT is hosted on OpenCollective, you can support the development of the app at https://opencollective.com/lwt-community.

Thanks for your interest in contributing!

▶ Wordpress Integration - [↑]


I CANNOT give any support for this feature, NOR can I help you with any WordPress problems! USE AT YOUR OWN RISK!


The WordPress feature is a legacy function no longer maintained. It should be considered experimental as it may break with a new release of LWT.

The following instructions are for users who have installed WordPress, and want to install LWT for multiple WordPress users in conjunction with WordPress authentication. Every WordPress user will have his/her own LWT table set.

  1. Download and install WordPress.
  2. Download and install LWT into a new subdirectory "lwt", located in the main directory of your WordPress installation.
  3. In subdirectory "lwt", rename the file connect_wordpress.inc.php into connect.inc.php, and enter the database parameters $server (database server), $userid (database user id), $passwd (database password), and $dbname (database name, can be the same like your wordpress database, or a different one) by editing the file with a text editor.
  4. In the WordPress General Settings, decide whether anyone can register and use LWT (Membership = "Anyone can register"), or not (an administrator must create new users). The "New User Default Role" should be "Subscriber".
  5. The link to start LWT with complete WordPress authentication is:
  6. The link to start LWT (without WordPress authentication, only by checking the session cookie that is valid until the browser is closed) is:
    If the session cookie does not exist, both above start methods are the same.
  7. To properly log out from both WordPress and LWT, use the link:
    The LWT home page has such a link. If you only log out via the links on the WordPress pages, you will still be able to use LWT until the browser is closed. If you want to log out from both WordPress and LWT, use the above link, or click on the link on the LWT home page!
  8. If you delete a user, you must find out its user number (table "wp_users"). After deleting the user in WordPress, you can delete all LWT tables with table names beginning with the user number plus an underscore "_". You can do this in phpMyAdmin.

▶ LWT REST API Documentation - [↑]

This documentation provides an overview of the REST API endpoints available for LWT-community. The LWT API allows developers to interact with various features of the application, such as retrieving media paths, getting sentences containing a specific term, managing settings, and more.

Base URL

The base URL for all API endpoints is: http://[base_url]/api/v1, where base_url is your instance URL (e. g. localhost:8080).


Currently, the LWT API does not require authentication. However, authentication might be implemented in the future. Ensure that appropriate security measures are implemented on the client-side to protect user data.


The REST API should follow semantic versioning. In the API URL, v1 indicates "MAJOR version 1", and so on for the future versions. A track of all changes is kept in the CHANGELOG.md.

GET API Endpoints

Get Media Files Paths

Retrieves the files paths to the audio and video files in the media folder.

Get Reading Configuration

Retrieves how word should be read for a specific language.

Get Phonetic Reading

Retrieves the phonetic reading for any specified term.

Get Next Word to Review

Retrieves the next word to be reviewed.

Get Tomorrow's Reviews Number

Retrieves the number of reviews scheduled for tomorrow.

Get Sentences Containing New Term

Retrieves sentences that contain the specified term.

Get Sentences Containing Registred Term

Retrieves sentences that contain the specified term.

Get Terms Similar to Another

Retrieves terms similar to the specified term.

Get Theme Path

Retrieves the path for a file using the user theme.

Get Imported Terms

Retrieves the terms that were imported.

Get Term Translations

Retrieves the translations for a specific term.

Get Texts Statistics

Retrieves statistics for multiple texts.

Get API Version

Retrieves the version of the LWT API.

POST API Endpoints

Save Setting

Saves user settings.

Set Text Annotation

Sets the annotation for a specific text.

Update Audio Position

Updates the audio position for a specific text.

Update Reading Position

Updates the reading position for a specific text.

Decrement Term Status

Decrements the status of a term.

Increment Term Status

Increments the status of a term.

Set Term Status

Sets the status of a term to a new value.

Update Existing Term Translation

Add a translation for an existing term.

Add New Term Translation

Adds a new translation for a term.

Response Format

All API endpoints return responses in JSON format.

▶ Database Information - [↑]

The following seventeen tables are one "LWT table set". The default table set has no table name prefix, so the tables are named just as written below: "settings", "languages", etc.

Additional table sets have its "table set name" plus an underscore "_" as a table name prefix: "setname_settings", "setname_languages", etc. The "table set name" is max. 20 characters long. Allowed characters are only: a-z, A-Z, 0-9, and the underscore "_".

Only if the table set is not set in "connect.inc.php", the currently used table set is saved in a global table "_lwtgeneral", in column LWTValue of row with LWTKey = "current_table_prefix". If such a row does not exist, the default table set will be used, or will be automatically created and used.

Table "settings"

Settings as Key-Value Pairs

StKey varchar(40) NOT NULL,  
StValue varchar(40) DEFAULT NULL,  

Table "languages"

Defined languages

LgID tinyint(3) unsigned NOT NULL AUTO\_INCREMENT,  
LgName varchar(40) NOT NULL,  
LgDict1URI varchar(200) NOT NULL,  
LgDict2URI varchar(200) DEFAULT NULL,  
LgGoogleTranslateURI varchar(200) DEFAULT NULL,  
LgExportTemplate varchar(1000) DEFAULT NULL,  
LgTextSize smallint(5) unsigned NOT NULL DEFAULT '100',  
LgCharacterSubstitutions varchar(500) NOT NULL,  
LgRegexpSplitSentences varchar(500) NOT NULL,  
LgExceptionsSplitSentences varchar(500) NOT NULL,  
LgRegexpWordCharacters varchar(500) NOT NULL,  
LgRemoveSpaces tinyint(1) unsigned NOT NULL DEFAULT '0',  
LgSplitEachChar tinyint(1) unsigned NOT NULL DEFAULT '0',  
LgRightToLeft tinyint(1) UNSIGNED NOT NULL DEFAULT '0',  
UNIQUE KEY LgName (LgName)

Table "texts"

(Active texts, parsed and cached in sentences and textitems)

TxID smallint(5) unsigned NOT NULL AUTO\_INCREMENT,  
TxLgID tinyint(3) unsigned NOT NULL, -- LANGUAGE FOREIGN KEY --  
TxTitle varchar(200) NOT NULL,  
TxText text NOT NULL,  
TxAnnotatedText longtext NOT NULL,  
TxAudioURI varchar(200) DEFAULT NULL,  
TxSourceURI varchar(1000) DEFAULT NULL,  
TxPosition smallint(5) NOT NULL DEFAULT '0',  
TxAudioPosition float NOT NULL DEFAULT '0',  


Table "archivedtexts"

Text Archive, not parsed and cached

AtID smallint(5) unsigned NOT NULL AUTO\_INCREMENT,  
AtLgID tinyint(3) unsigned NOT NULL, -- LANGUAGE FOREIGN KEY --  
AtTitle varchar(200) NOT NULL,  
AtText text NOT NULL,  
AtAnnotatedText longtext NOT NULL,  
AtAudioURI varchar(200) DEFAULT NULL,  
AtSourceURI varchar(1000) DEFAULT NULL,  

Table "tags2"

Text tags and comments

T2ID smallint(5) unsigned NOT NULL AUTO\_INCREMENT,  
T2Text varchar(20) CHARACTER SET utf8 COLLATE utf8\_bin NOT NULL,  
T2Comment varchar(200) NOT NULL DEFAULT '',  
UNIQUE KEY T2Text (T2Text)

Table "texttags"

Text tags relations

TtTxID smallint(5) unsigned NOT NULL, -- TEXT FOREIGN KEY --  
TtT2ID smallint(5) unsigned NOT NULL, -- TEXT TAG FOREIGN KEY --  

Table "archtexttags"

Archived text tags relations

AgAtID smallint(5) unsigned NOT NULL, -- ARCHIVED TEXT FOREIGN KEY --  
AgT2ID smallint(5) unsigned NOT NULL, -- TEXT TAG FOREIGN KEY --  

Table "words"

the words and expressions you have saved

WoID mediumint(8) unsigned NOT NULL AUTO\_INCREMENT,  
WoLgID tinyint(3) unsigned NOT NULL, -- LANGUAGE FOREIGN KEY --  
WoText varchar(250) NOT NULL,  
WoTextLC varchar(250) CHARACTER SET utf8 COLLATE utf8\_bin NOT NULL,  
WoStatus tinyint(4) NOT NULL,  
WoTranslation varchar(500) NOT NULL DEFAULT '\*',  
WoRomanization varchar(100) DEFAULT NULL,  
WoSentence varchar(1000) DEFAULT NULL,  
WoWordCount tinyint(3) unsigned NOT NULL DEFAULT '0',  
WoStatusChanged timestamp NOT NULL DEFAULT '1970-01-01 12:00:00',  
WoTodayScore double NOT NULL DEFAULT '0',  
WoTomorrowScore double NOT NULL DEFAULT '0',  
WoRandom double NOT NULL DEFAULT '0',  
KEY WoLgID (WoLgID),  
KEY WoStatus (WoStatus),  
KEY WoTextLC (WoTextLC),  
KEY WoTranslation (WoTranslation),  
KEY WoCreated (WoCreated),  
KEY WoStatusChanged (WoStatusChanged),  
KEY WoWordCount (WoWordCount),  
KEY WoTodayScore (WoTodayScore),  
KEY WoTomorrowScore (WoTomorrowScore),  
KEY WoRandom (WoRandom)

Table "tags"

Term tags and comments

TgID smallint(5) unsigned NOT NULL AUTO\_INCREMENT,  
TgText varchar(20) CHARACTER SET utf8 COLLATE utf8\_bin NOT NULL,  
TgComment varchar(200) NOT NULL DEFAULT '',  
UNIQUE KEY TgText (TgText)

Table "wordtags"

Term tags relations

WtWoID int(11) unsigned NOT NULL, -- TERM FOREIGN KEY --  
WtTgID smallint(5) unsigned NOT NULL, -- TERM TAG FOREIGN KEY --  

Table "sentences"

Sentences cache, no backup needed

SeID mediumint(8) unsigned NOT NULL AUTO\_INCREMENT,  
SeLgID tinyint(3) unsigned NOT NULL, -- LANGUAGE FOREIGN KEY --  
SeTxID smallint(5) unsigned NOT NULL, -- TEXT FOREIGN KEY --  
SeOrder smallint(5) unsigned NOT NULL,  
SeText text,  
SeFirstPos smallint(5) unsigned NOT NULL,  
KEY SeLgID (SeLgID),  
KEY SeTxID (SeTxID),  
KEY SeOrder (SeOrder)

Table "textitems2"

Text items cache, no backup needed

Ti2WoID mediumint(8) unsigned NOT NULL,  
Ti2LgID tinyint(3) unsigned NOT NULL, -- LANGUAGE FOREIGN KEY --  
Ti2TxID smallint(5) unsigned NOT NULL, -- TEXT FOREIGN KEY --  
Ti2SeID mediumint(8) unsigned NOT NULL, -- SENTENCE FOREIGN KEY --  
Ti2Order smallint(5) unsigned NOT NULL,  
Ti2WordCount tinyint(3) unsigned NOT NULL,  
Ti2Text varchar(250) CHARACTER SET utf8 COLLATE utf8\_bin NOT NULL,  
PRIMARY KEY (Ti2TxID,Ti2Order,Ti2WordCount),  

Table "temptextitems"

memory table only used when creating texts, otherwise empty

TiCount smallint(5) unsigned NOT NULL,  
TiSeID mediumint(8) unsigned NOT NULL,  
TiOrder smallint(5) unsigned NOT NULL,  
TiWordCount tinyint(3) unsigned NOT NULL,  
TiText varchar(250) CHARACTER SET utf8 COLLATE utf8\_bin NOT NULL

Table "tempwords"

memory table only used when importing words, otherwise empty

WoText varchar(250) DEFAULT NULL,  
WoTextLC varchar(250) CHARACTER SET utf8 COLLATE utf8\_bin NOT NULL,  
WoTranslation varchar(500) NOT NULL DEFAULT '\*',  
WoRomanization varchar(100) DEFAULT NULL,  
WoSentence varchar(1000) DEFAULT NULL,  
WoTaglist varchar(255) DEFAULT NULL,  

Table "feedlinks"

Newsfeed articles

FlID smallint(5) unsigned NOT NULL AUTO\_INCREMENT,  
FlTitle varchar(200) NOT NULL,  
FlLink varchar(400) NOT NULL,  
FlDescription text NOT NULL,  
FlDate datetime NOT NULL,  
FlAudio varchar(200) NOT NULL,  
FlText longtext NOT NULL,  
FlNfID tinyint(3) unsigned NOT NULL,  
UNIQUE KEY FlTitle (FlTitle),  
KEY FlLink (FlLink),  
KEY FlDate (FlDate),  

Table "newsfeeds"

Newsfeed settings

NfID tinyint(3) unsigned NOT NULL AUTO\_INCREMENT,  
NfLgID tinyint(3) unsigned NOT NULL,  
NfName varchar(40) NOT NULL,  
NfSourceURI varchar(200) NOT NULL,  
NfArticleSectionTags text NOT NULL,  
NfFilterTags text NOT NULL,  
NfUpdate int(12) unsigned NOT NULL,  
NfOptions varchar(200) NOT NULL,  
KEY NfLgID (NfLgID),  
KEY NfUpdate (NfUpdate)

▶ Changelog - [↑]

This project's changelog. Versions marked with "-fork" come from the community, other versions come from the canonical LWT ("official" branch on Git). For git tags, official releases are marked like "v1.0.0", while unofficial ones are marked like "v1.0.0-fork".

[2.10.0-fork] (April 1 2024)





Full Changelog for 2.10.0-fork

2.9.1-fork (December 29 2023)

Added in 2.9.1-fork

Changed in 2.9.1-fork

Fixed in 2.9.1-fork

Deprecated in 2.9.1-fork

Full Changelog for 2.9.1-fork

2.9.0-fork (December 24 2023)

Added in 2.9.0-fork

Changed in 2.9.0-fork

Fixed in 2.9.0-fork

Deprecated in 2.9.0-fork

Security in 2.9.0-fork

Full Changelog for 2.9.0-fork

2.8.1-fork (April 14 2023)

Changed in 2.8.1-fork

Fixed in 2.8.1-fork

Full Changelog for 2.8.1-fork

2.8.0-fork (April 08 2023)

Added in 2.8.0-fork

Changed in 2.8.0-fork

Fixed in 2.8.0-fork

Full Changelog for 2.8.0-fork

2.7.0-fork (March 14 2023)

Added in 2.7.0-fork

Changed in 2.7.0-fork

Fixed in 2.7.0-fork

Deprecated in 2.7.0-fork

Full Changelog for 2.7.0-fork

2.6.0-fork (January 01 2023)

Added in 2.6.0-fork

Changed in 2.6.0-fork

Deprecated in 2.6.0-fork

Removed in 2.6.0-fork

Fixed in 2.6.0-fork

Full Changelog for 2.6.0-fork

2.5.3-fork (November 06 2022)

Added in 2.5.3-fork

Changed in 2.5.3-fork

Fixed in 2.5.3-fork

Full Changelog for 2.5.3-fork

2.5.2-fork (September 27 2022)

Changed in 2.5.2-fork

Fixed in 2.5.2-fork

Full Changelog for 2.5.2-fork

2.5.1-fork (September 16 2022)

Fixed in 2.5.1-fork

Full Changelog for 2.5.1-fork

2.5.0-fork (July 08 2022)

Added in 2.5.0-fork

Changed in 2.5.0-fork

Fixed in 2.5.0-fork

Full Changelog for 2.5.0-fork

Deprecated in 2.5.0-fork

2.0.3 (February 15 2022)

Fixed in 2.0.3

2.4.1-fork (June 09 2022)

Changed in 2.4.1-fork

Fixed in 2.4.1-fork

Full Changelog for 2.4.1-fork

2.4.0-fork (May 23 2022)

Added in 2.4.0-fork

Changed in 2.4.0-fork

Fixed in 2.4.0-fork

Removed in 2.4.0-fork

Full Changelog for 2.4.0-fork

2.3.0-fork (April 25 2022)

Added in 2.3.0-fork

Changed in 2.3.0-fork

Deprecated in 2.3.0-fork

Fixed in 2.3.0-fork

Full Changelog for 2.3.0-fork

2.2.2-fork (February 13 2022)

Added in 2.2.2-fork

Changed in 2.2.2-fork

Fixed in 2.2.2-fork

Deprecated in 2.2.2-fork

Full Changelog for 2.2.2-fork

2.2.1-fork (February 07 2022)

Changed in 2.2.1-fork

Fixed in 2.2.1-fork

Deprecated in 2.2.1-fork

Removed in 2.2.1-fork

Full Changelog for 2.2.1-fork

2.2.0-fork (February 04 2022)

Added in 2.2.0-fork

Changed in 2.2.0-fork

Fixed in 2.2.0-fork

Removed in 2.2.0-fork

Full Changelog for 2.2.0-fork

2.1.0-fork (January 09 2022)

Added in 2.1.0-fork

Changed in 2.1.0-fork

Fixed in 2.1.0-fork

Removed in 2.1.0-fork

Full Changelog for 2.1.0-fork

2.0.4-fork (December 03 2021)

This version brings a better composer compatibility, and starts revamping mobile compatibility.

Changed in 2.0.4-fork

Removed in 2.0.4-fork

Full Changelog for 2.0.4-fork

2.0.3-fork (November 26 2021)

Serious maintaining is back!

This version should be the stable merge between official v2.0.2 and community maintained 1.6.31-fork.

Added in 2.0.3-fork

Changed in 2.0.3-fork

Full Changelog for 2.0.3-fork

2.0.2 (September 07 2021)

Fixed in 2.0.2

2.0.1 (October 07 2020)

Fixed in 2.0.1

2.0.0 (October 04 2020)

Fixed in 2.0.0

1.6.3 (April 06 2020)

Added in 1.6.3

1.6.2 (March 10 2018, this page "info.php" last updated August 12 2019)

Added in 1.6.2

Changed in 1.6.2

Fixed in 1.6.2

Removed in 1.6.2

1.6.1 (February 01 2016, this page "info.php" last updated January 13 2018)

Added in 1.6.1

Changed in 1.6.1

1.6.31-fork (October 03 2016)

Fixed in 1.6.31-fork

1.6.30-fork (July 28 2016)

Added in 1.6.30-fork

Fixed in 1.6.30-fork

1.6.29-fork (April 21 2016)

Changed in 1.6.29-fork

Fixed in 1.6.29-fork

1.6.28-fork (April 07 2016)

Added in 1.6.28-fork

Changed in 1.6.28-fork

Fixed in 1.6.28-fork

1.6.27-fork (February 21 2016)

Fixed in 1.6.27-fork

Removed in 1.6.27-fork

1.6.26-fork (February 11 2016)

Changed in 1.6.26-fork

Fixed in 1.6.26-fork

1.6.25-fork (January 31 2016)

Added in 1.6.25-fork

Changed in 1.6.25-fork

Fixed in 1.6.25-fork

1.6.0 (January 28 2016)

Changed in 1.6.0

1.5.21 (January 14 2016)

Changed in 1.5.21

1.6.24-fork (January 11 2016)

Added in 1.6.24-fork

Changed in 1.6.24-fork

Removed in 1.6.24-fork

1.6.23-fork (December 13 2015)

Added in 1.6.23-fork

Changed in 1.6.23-fork

1.6.22-fork (November 11 2015)

Added in 1.6.22-fork

1.6.21-fork (October 16 2015)

Added in 1.6.21-fork

1.6.20-fork (September 26 2015)

Changed in 1.6.20-fork

Fixed in 1.6.20-fork

1.6.19-fork (August 29 2015)

Added in 1.6.19-fork

Changed in 1.6.19-fork

1.6.18-fork (June 11 2015)

Added in 1.6.18-fork

Fixed in 1.6.18-fork

1.6.17-fork (May 09 2015)

Fixed in 1.6.17-fork

1.6.16-fork (May 01 2015)

Changed in 1.6.16-fork

1.6.15-fork (April 10 2015)

Changed in 1.6.15-fork

Fixed in 1.6.15-fork

1.6.14-fork (March 28 2015)

Changed in 1.6.14-fork

1.6.13-fork (March 23 2015)

Added in 1.6.13-fork

Fixed in 1.6.13-fork

1.6.12-fork (March 01 2015)

Changed in 1.6.12-fork

Fixed in 1.6.12-fork

1.6.11-fork (February 09 2015)

Fixed in 1.6.11-fork

1.6.10-fork (January 25 2015)

Changed in 1.6.10-fork

Fixed in 1.6.10-fork

1.6.9-fork (December 21 2014)

Fixed in 1.6.9-fork

1.6.8-fork (December 19 2014)

Changed in 1.6.8-fork

1.6.7-fork (December 18 2014)

Fixed in 1.6.7-fork

1.6.6-fork (December 16 2014)

Added in 1.6.6-fork

1.6.5-fork (December 01 2014)

Fixed in 1.6.5-fork

1.6.4-fork (November 29 2014)

Fixed in 1.6.4-fork

1.6.3-fork (October 12 2014)

Added in 1.6.3-fork

Changed in 1.6.3-fork

1.6.2-fork (October 06 2014)

Added in 1.6.2-fork

Changed in 1.6.2-fork

1.6.1-fork (September 28 2014)

Added in 1.6.1-fork

Changes from official LWT version 1.5.20 imported:

Changed in 1.6.1-fork

1.5.20 (September 22 2014)

Changed in 1.5.20

Fixed in 1.5.20

1.5.19 (September 15 2014)

1.5.18 (September 14 2014)

Added in 1.5.18

Changed in 1.5.18

Fixed in 1.5.18

Removed in 1.5.18

1.6.0-fork (September 12 2014)

Added in 1.6.0-fork

Changed in 1.6.0-fork

1.5.17-fork (June 08 2014)

Added in 1.5.17-fork

Changed in 1.5.17-fork

Fixed in 1.5.17-fork

1.5.17 (August 15 2014, this document updated Aug 17 2014 and Aug 24 2014)

Changed in 1.5.17

Fixed in 1.5.17

1.5.16 (February 19 2014)

Changed in 1.5.16

Fixed in 1.5.16

1.5.15 (December 17 2013)

Changed in 1.5.15

Fixed in 1.5.15

1.5.14 (August 05 2013, this document updated Oct 30 2013)

Changed in 1.5.14

Fixed in 1.5.14

1.5.13 (July 22 2013)

Changed in 1.5.13

Fixed in 1.5.13

1.5.12 (July 16 2013)

Added in 1.5.12

Changed in 1.5.12

Fixed in 1.5.12

1.5.11 (July 12 2013)

Added in 1.5.11

Changed in 1.5.11

Fixed in 1.5.11

1.5.10 (July 07 2013)

Added in 1.5.10

Changed in 1.5.10

Fixed in 1.5.10

1.5.9 (July 03 2013)

Added in 1.5.9

Changed in 1.5.9

Fixed in 1.5.9

1.5.8 (June 27 2013)

Changed in 1.5.8

1.5.7 (June 25 2013)

Added in 1.5.7

Changed in 1.5.7

Fixed in 1.5.7

1.5.6 (June 22 2013)

Fixed in 1.5.6

1.5.5 (June 21 2013)

Added in 1.5.5

Changed in 1.5.5

1.5.4 (June 19 2013)

Added in 1.5.4

Changed in 1.5.4

1.5.3 (June 14 2013)

Added in 1.5.3

Changed in 1.5.3

1.5.2 (June 09 2013)

Added in 1.5.2

Changed in 1.5.2

1.5.1 (June 07 2013)

Added in 1.5.1

Changed in 1.5.1

1.5.0 (April 22 2013)

Added in 1.5.0

Changed in 1.5.0

1.4.10 (February 22 2013)

Added in 1.4.10

Changed in 1.4.10

1.4.9 (August 29 2012)

Fixed in 1.4.9

1.4.8 (May 11 2012, some external links updated June 19 2012)

Added in 1.4.8

Changed in 1.4.8

Fixed in 1.4.8

1.4.7 (April 6 2012)

Fixed in 1.4.7

1.4.6 (March 14 2012)

Fixed in 1.4.6

1.4.5 (October 01 2011, documentation updated Oct 13 2011, external links updated Dec 8 2011)

Added in 1.4.5

1.4.4 (September 23 2011)

Changed in 1.4.4

1.4.3 (September 21 2011)

Changed in 1.4.3

1.4.2 (September 19 2011)

Removed in 1.4.2

1.4.1 (September 15 2011)

Changed in 1.4.1

1.4.0 (September 09 2011)

Added in 1.4.0

1.3.1 (September 05 2011)

Added in 1.3.1

Changed in 1.3.1

1.3.0 (September 03 2011)

Added in 1.3.0

Changed in 1.3.0

1.2.2 (August 26 2011)

Added in 1.2.2

Changed in 1.2.2

Fixed in 1.2.2

1.2.1 (August 25 2011)

Added in 1.2.1

Changed in 1.2.1

1.2.0 (August 24 2011)

1.1.1 (August 17 2011)

Added in 1.1.1

Changed in 1.1.1

Fixed in 1.1.1

1.1.0 (August 16 2011)

Added in 1.1.0

Changed in 1.1.0

Fixed in 1.1.0

1.0.4 (August 11 2011)

Added in 1.0.4

Changed in 1.0.4

1.0.3 (August 09 2011)

Added in 1.0.3

Changed in 1.0.3

1.0.2 (August 05 2011)

Added in 1.0.2

Changed in 1.0.2

1.0.1 (August 04 2011)

Added in 1.0.1

Changed in 1.0.1

1.0.0 (August 01 2011)

0.9.8 (July 31 2011)

Added in 0.9.8

Changed in 0.9.8

0.9.7 (July 28 2011)

Changed in 0.9.7

0.9.6 (July 26 2011)

Changed in 0.9.6

0.9.5 (July 23 2011)

Changed in 0.9.5

0.9.4 (July 22 2011)

Added in 0.9.4

Changed in 0.9.4

0.9.3 (July 21 2011)

Fixed in 0.9.3

0.9.2 (July 19 2011)

Fixed in 0.9.2

0.9.1 (July 18 2011)

Changed in 0.9.1

Fixed in 0.9.1

0.9.0 (July 14 2011)

Added in 0.9.0

Changed in 0.9.0

0.8.2 (July 13 2011)

Changed in 0.8.2

Fixed in 0.8.2

0.8.1 (July 12 2011)

Changed in 0.8.1

0.8.0 (July 11 2011)

Added in 0.8.0

Changed in 0.8.0

0.7.0 (July 09 2011)

Changed in 0.7.0

0.6.0 (July 08 2011)

Changed in 0.6.0

Fixed in 0.6.0

0.5.0 (June 30 2011)

Added in 0.5.0

Changed in 0.5.0

Fixed in 0.5.0

0.4.0 (June 29 2011)

Added in 0.4.0

Changed in 0.4.0

Fixed in 0.4.0

0.3.0 (June 27 2011)

Added in 0.3.0

Changed in 0.3.0

Fixed in 0.3.0

0.2.0 (June 25 2011)

Added in 0.2.0

Changed in 0.2.0

Fixed in 0.2.0

0.1.0 (June 24 2011)