Jump to topic:
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 unnadapted, and the code was quite obfuscated. While I do not have any official responsibility to LWT (I don't know 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 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!
The current version is 2.6.0-fork (January 01 2023).
View the Changelog.
Learning with Texts (LWT) is a tool for Language Learning, inspired by:
You define languages you want to learn and import texts you want to use for learning.
While listening to the audio (optional), 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.
**MOST IMPORTANT:
To run LWT, you'll need:**
A video from FluentCzech:
Please have a look at the other great videos of FluentCzech that contain many good ideas for language learning!
Website of FluentCzech (anthonylauder.com)
A video from Benny the Irish polyglot:
Fluent In 3 Months: Introducing LWT, with Benny's own (free) version of LWT.
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.
"Learning with Texts" (LWT) 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.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to [http://unlicense.org/].
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:
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.
Whatever installation you choose, the steps will look like the following:
connect.inc.php
file with your password.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.
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.
Install XAMPP
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)
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.
Start LWT server
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.
Get Visual C++
Get EasyPHP
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)
Install everything
Start EasyPHP
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.
This section may be obsolete! Your help is welcome!
Download "MAMP & MAMP PRO" (currently version 6.6).
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.
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)
Go to /Applications/MAMP/htdocs/lwt
. Rename the file connect_mamp.inc.php
to connect.inc.php
.
Open MAMP.app
in /Applications/MAMP
. Accept the messages from the firewall. Apache and MySQL start automatically.
LWT can now be started in your web browser, go to: http://localhost:8888/lwt.
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.
The following instruction were tested on Raspbian Stretch.
Open a terminal, type and execute the following commands:
Installation of LAMP:
sudo apt-get update
sudo apt-get install apache2 libapache2-mod-php php php-mbstring php-mysql mysql-server
Enable the extensions
/etc/php/{{desired PHP version}}/{{PHP type}}/
)sudo nano php.ini
.extension=mbstring
and extension=mysqli
.Set MySQL root Password to "abcxyz"
sudo mysql
Then type
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'abcxyz';
FLUSH privileges;
QUIT;
Check MySQL access (optionnal)
mysql -u root -p
abcxyz
If you see the MySQL prompt mysql>
after the first command, everything is OK. Quit with
QUIT;
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)
Unzip it.
Rename the file connect_xampp.inc.php in /[... Path to downloaded LWT ...]/lwt to connect.inc.php.
Edit this file connect.inc.php and set the MySQL password in line
$passwd = "";
. Change it to $passwd = "abcxyz";
. Save the edited file connect.inc.php.
Open a Terminal window, 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
LWT can now be started in your web browser, go to: http://localhost/lwt.
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.
Docker is the easiest way to install LWT, but it will use more or less 1 GB on your system.
We provide on online image, you can download it using.
docker pull ghcr.io/hugofara/lwt
If you want to build the image from source, you can use the following command. You can build the image by running
docker compose up
By default the server can be accessed on port 8010 (http://localhost:8010).
To remove the created containers run
docker compose down
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.
Backup the LWT directory. Backup your database (within LWT).
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)
Unzip it.
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).
Clear the web browser cache and open LWT as usual.
Need more help? You can contact us through GitHub and Discord!
Please note that PHP below version 8.0 is not supported.
Find an interesting text (preferably with an mp3 audio file) in the Internet and load it into LWT. If you are a beginner, look for beginner courses or podcasts in the Internet.
You don't know where to find texts with audio? The LingQ Library has many (only a free registration is needed). Or look into this thread 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!
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.
Listen ⶠRead ⶠReview/Test.
Listen ⶠRead ⶠReview/Test.
......
That's it. It's that simple.
If you want to know more, watch Steve Kaufmann's videos on YouTube: "The 7 secrets of language learning", "Language learning FAQ", and many more.
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.
My Languages
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.
If you are new to the system, 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.
Explainations of the input fields - please read also this section:
The three Uniform Resource Identifiers (URIs) are URIs to three web dictionaries (the second and third is optional). Use ### as a placeholder for the searchword in the URIs. If ### is missing, the searchword will be appended. If the URI to query "travailler" in WordReference is "http://www.wordreference.com/fren/travailler", you enter: "http://www.wordreference.com/fren/###" or "http://www.wordreference.com/fren/". Another example: The URI to query "travailler" in sansagent is "http://dictionary.sensagent.com/travailler/fr-en/", so you enter in LWT "http://dictionary.sensagent.com/###/fr-en/".
As URI No. 3 ("Google Translate URI") is also used to translate whole sentences, I would recommend to enter here always the link to Google Translate, like shown in the examples. The link to Google Translate is "http://translate.google.com/?ie=UTF-8&sl=..&tl=..&text=###", where the two-character codes after "sl=" and "tl=" designate the language codes (or "subtags") for the source and the target language. But a different third web dictionary is of course possible, but sentence translations may not work.
If the searchword in the three URIs needs to be converted into a different encoding (standard is UTF-8), you can 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.
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!).
One dictionary (Glosbe) has been closely integrated into LWT via the Glosbe API. To use this dictionary, input the "special" dictionary link "glosbe_api.php?from=...&dest=...&phrase=###" (NO "http://" at the beginning!!) 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.
My 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.
My 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 (with Check)
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 (HowTo add a new newsfeed see here). 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. 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 my newsfeeds), delete all articles or delete feeds.
Actions: You can edit, update, delete a feed or follow the link to the newsfeed.
New/Edit Feeds
Explainations of the input fields:
Feed Wizard
Here you can edit or set up a new newsfeed in 4 steps.
Step 1
Insert your newsfeed url. This step is skipped, when you edit a newsfeed.
Step 2
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.
Step 3
This works like step 2. Only the selected sections from step 2 are clickable. Marked text will appear grey, filtered texts will have a red font.
Step 4
The settings are explained in 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.
Test 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 (words and expressions).
Test 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.
Test 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.
Test 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.
Test 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):
How to 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 this YouTube video.
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!
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.
My 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 (with Check)
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.
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.
Test 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 (words and expressions).
Test 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.
Test 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.
Test 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.
Test 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):
How to 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 this YouTube video.
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.
My Terms
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.
My 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.
My 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
My Statistics
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!
Backup/Restore/Empty Database
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!
Settings/Preferences
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 also 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
WARNING: The use of the "Multiple LWT table sets" feature on an external web server may cause a monstrous database size if some users import many or large texts. Without further improvements (e. g. user quotas, etc.), LWT with activated "Multiple LWT table sets" is in its current version not suitable to be run in a public environment on an external web server!
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.
I want to use LWT, and I see something like this:
Answer: Your local webserver (Apache) is not running. Please start it via EasyPHP or MAMP control program/panel.
I want to use LWT, and I see something like this:
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.
I want to use LWT, and I see this:
Answer: Either the database (MySQL) 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.
I want to use LWT, and I see this:
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.
I have 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.
This section shows some language setups ("RegExp Split Sentences", "RegExp Word Characters", "Make each character a word", "Remove spaces") for different languages. They are only recommendations, and you may change them according to your needs (and texts). See also here.
If you are unsure, try the "Language Settings Wizard" first. Later you can adjust the settings.
Please inform yourself about Unicode here (general information) and here (Table of Unicode characters) and about the characters that occur in the language you learn!
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 |
"\'" = Apostrophe, and/or "\-" = Dash, may be added to "RegExp Word Characters", then words like "aujourd'hui" or "non-government-owned" are one word, instead of two or more single words. If you omit "\'" and/or "\-" here, you can still create a multi-word expression "aujourd'hui", etc., later.
":" and ";" may be omitted in "RegExp Split Sentences", but longer example sentences may result from this.
"Make each character a word" = "Yes" should only be set in Chinese, Japanese, and similar languages. Normally words are split by any non-word character or whitespace. If you choose "Yes", then you do not need to insert spaces to specify word endings. If you choose "No", then you must prepare texts without whitespace by inserting whitespace to specify words. If you are a beginner, "Yes" may be better for you. If you are an advanced learner, and you have a possibility to prepare a text in the above described way, then "No" may be better for you.
"Remove spaces" = "Yes" should only be set in Chinese, Japanese, and similar languages to remove whitespace that has been automatically or manually inserted to specify words.
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 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 |
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 "[...]" (cloze test question) - as raw text. |
%d | The sentence, but the "{xxx}" parts are replaced by "[xxx]" (cloze test 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:< = < / > = > / & = & / " = " |
$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 "[...]" (cloze test question) - as HTML text. |
$d | The sentence, but the "{xxx}" parts are replaced by "[xxx]" (cloze test solution) - as HTML text. |
$x | The sentence in Anki2 cloze test notation: the "{xxx}" parts are replaced by "{{c1::xxx}}" - as HTML text. |
$y | The sentence in Anki2 cloze test 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 "". |
This guide is mainly aimed for developers, but it can give useful insights on how LWT is structured, which could help you for debugging. The first step you need to take is to clone LWT from the official GitHub repository (HugoFara/lwt).
Getting Composer is required if you want to edit LWT on the server side, but it will also make be useful to edit JS and CSS code, so it is highly recommended. Composer is a light-weight dependency manager that does not need a server for running.
Once Composer is ready, go the the lwt folder (most likely lwt/
), and type
composer install --dev
This will automatically dowload all the required dependencies.
Themes are stored at src/themes/
. If you want to create a new theme, simply add it in a subfolder. You can also edit existing themes.
To apply the changes you made on 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 CSS only.
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 scr/themes/
to themes/
. WARNING: it can break your relative paths!
We support a smart minifying system: relative path are automatically adapted to point to the previous location while minifying only. As a consequence:
css/images/
in your theme.
src/themes/mytheme/
, you should use the path ../../../css/theimage
../myimage
.When debugging your theme, files are simply copied to the themes/
folder, which can break the path to files in css/
.
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 does not need to have the same files as src/css/
.
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.
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();"
.
To copy code in a non-obfuscated form, run composer no-minify
, or replace the content of js/
by src/js/
.
The PHP codebase is not yet well structured, but here is a general organisation:
do_text.php
, do_test.php
, etc...)inc/
("include") folder.src/php/
.It is higly advised to test your code. Tests should be wrote under tests/
. We use PHP Unit for testing.
To run all tests:
composer test
Alternatively:
./vendor/bin/phpunit
We use Psalm to find code flaws and inconsistencies. Use ./vendor/bin/psalm
.
Your can configure the reporting level in psalm.xml
.
Nobody likes to debug unreadable code. A good way to avoid thinking about it is to include phpcs directly into your IDE. You can also download it and run it regularly on your code.
To regenerate all documentation, use composer doc
.
The documentation in split across Markdown (.md
) files in docs/
. Then, those files are requested by info.php
. The final version is info.html
, that contains all files.
To regenerate info.hml
, run composer info.html
.
Code documentation (everything under docs/html/
) 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 documentation is generated through Doxygen (run doxygen Doxyfile
to regenerate it), but this is likely to change.
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 retributions developers get from time spent on LWT is to discuss with users.
LWT is a non-profitable software, so we won't have much time, and no money, to advertise LWT. 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.
Thanks for your interest in contributiong!
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.
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,
PRIMARY KEY (StKey)
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',
PRIMARY KEY (LgID),
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',
PRIMARY KEY (TxID),
KEY TxLgID (TxLgID)
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,
PRIMARY KEY (AtID),
KEY AtLgID (AtLgID)
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 '',
PRIMARY KEY (T2ID),
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 --
PRIMARY KEY (TtTxID,TtT2ID),
KEY TtT2ID (TtT2ID)
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 --
PRIMARY KEY (AgAtID,AgT2ID),
KEY AgT2ID (AgT2ID)
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',
WoCreated timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
WoStatusChanged timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
WoTodayScore double NOT NULL DEFAULT '0',
WoTomorrowScore double NOT NULL DEFAULT '0',
WoRandom double NOT NULL DEFAULT '0',
PRIMARY KEY (WoID),
UNIQUE KEY WoLgIDTextLC (WoLgID,WoTextLC),
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 '',
PRIMARY KEY (TgID),
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 --
PRIMARY KEY (WtWoID,WtTgID),
KEY WtTgID (WtTgID)
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,
PRIMARY KEY (SeID),
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),
KEY Ti2WoID (Ti2WoID)
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,
PRIMARY KEY (WoTextLC)
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,
PRIMARY KEY (FlID),
UNIQUE KEY FlTitle (FlTitle),
KEY FlLink (FlLink),
KEY FlDate (FlDate),
KEY FlNfID (FlNfID)
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,
PRIMARY KEY (NfID),
KEY NfLgID (NfLgID),
KEY NfUpdate (NfUpdate)
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".
getWordTagList
behavior changed (inc/session_utility.php
).do_test.php
, edit_texts.php
, edit_words.php
and set_test_status.php
now explicitly require a running session. They were silently failing before this release.save_setting_redirect.php
moved to inc/save_setting_redirect.php
.escape
and unescape
were replaced by modern equivalents encodeURIcomponent
and decodeURIcomponent
. This may lead to changes in cookies, notably making them work better.words
table, replaced the default timestamp 0000-00-00 00:00:00
by 0000-00-00 00:00:01
.composer.lock
.do_test_test_css
in do_test_test.php
is deprecated since it was causing display issues. Its CSS rules were trimmed.inc/ajax_save_text_position.php
) was broken for all texts. This is fixed.get_first_value
documentation updated since it was also returning float
and int
.get_similar_terms
in simterms.php
officially returns int.inc/ajax_save_setting.php
.
edit_texts.php
was never shown.media
folder in ...
, corrected to ..
.ADD DROP INDEX TiTextLC
altering temptextitems
in update_database
of database_connect.php
.README.md
and inc/kernel_utility.php
).connect_mamp.php
to connect_mamp.inc.php
for consistency with documentation.bulk_translate_words.php
. For phone users, it now properly focuses on the main screen after use.bulk_translate
functionality (clicking in "TO DO" for editing multiple new words). Bulk translate itself is not fixed, but warnings are no longer displayed. Merged pull request #44, from @Heliozoa.all_words_wellknown.php
).tts.php
(now text_to_speech_settings.php
). Merged pull request #51, thanks @jzohrab.upload_words.php
.upload_words.php
) can now be used with @@GLOBAL.local_infile
(MySQL) set to 0.@@GLOBAL.local_infile
(MySQL) set to 0, or any configuration disabling LOAD DATA LOCAL INFILE
, was causing a fatal error on adding a new text. This is fixing by a slower method.
Term
in edit_mword.php
. This class is yet to be considered experimental, so expect important changes, but should gradually get used everywhere.insert_expression_from_mecab
in session_utility.php
. Better name and behavior for insertExpressionFromMeCab
(see deprecations).set_word_count
in database_connect.php
had a misleading name. It was changed to init_word_count
.insertExpressionFromMeCab
deprecated for insert_expression_from_mecab
in session_utility.php
.edit_texts.php
. These signatures remain untouched for backward compatibility, but the internals were changed.edit_languages.php
, creating annoying notices as illustrated at #35.long_text_import.php
for non-Japanese texts, it was broken since 2.4.0. Thanks to @rc-ops for this issue #33.pgm.js
to ask the user before exiting but also the new function ask_before_exiting
.splitCheckText
was split into smaller functions.edit_languages.php
with functional paradigm.edit_texts.php
,
edit_archivedtexts.php
, long_text_import.php
and do_feeds.php
. It solves
issue #29.edit_languages.php
.edit_languages.php
.js/
.Makefile
where transcripted in composer.json
.Dockerfile
, docker-compose.yml
, .dockerignore
and .env
files.check_update_db
in inc/database_connect.php
was moved to update_database
.tts.php
becomes text_to_speech_settings.php
. As this file was unused, it is not considered as a breaking change.all_words_wellknown.php
, edit_texts.php
. Those pages should load a bit faster.clean-doc
install of clean
in Makefile
because it was ambiguous with composer commands.all_words_wellknown.php
created errors. This file was fixed. Thanks @nghiaphamtm (issue #26).edit_texts.php
, it was not displayed in the barchart when knowing 1 word. Thanks @chaosarium for signaling it (issue #11).docs/contribute.md
.edit_texts.php
works again.info.html
works now.do_test?text=
, the language name displayed instead of "[L2]" was often wrong.$fixed_tbpref
was never declared at global scope.database_connect.php
, splitCheckText
with PHP <7.4.do_text.php
.do_text_text.php
to their snake_case counterpart. The behavior of the deprecated functions did not change.
getTextData
to get_text_data
, sentenceParser
to sentence_parser
, wordParser
to word_parser
and mainWordLoop
to main_word_loop
getLanguagesSettings
to get_language_settings
(use singular)echoTerm
to echo_term
(no return value, no $hideuntil
parameter)prepareStyle
to do_text_text_style
and do_text_javascript
to do_text_text_javascript
.README.md
.jquery.tagit.css
, it may have visual consequences.do_text.php?text=
created a database error, it does no longer.do_text_text.php
since 2.0.3-fork. Some other issues may have been fixed at the same time.do_text_header.php
, function browser_tts
.is_mobile
function now always returns false.wordProcessor
(do_text_text.php
) function was incorrect.
wordParser
, sentenceParser
and some more code instead.components/
folder was also deleted. It was bundling JS code from composer.
info_export_template.md
was imported and adapted from official documentation.index.php
)docs/info.html
, and for docs/*.md
files.composer.json
is now working! Thanks chaosarium for signaling
this issue #4!This version brings a better composer compatibility, and starts revamping mobile compatibility.
composer.phar
and composer.lock
are now git ignored.Serious maintaining is back!
This version should be the stable merge between official v2.0.2 and community maintained 1.6.31-fork.
Changes from official LWT version 1.5.20 imported:
Possibility to display similar terms while creating or editing a term. This will give you more language insight, and may ease inputting new terms that are similar. The number of displayed similar terms can be set from 0 (old behavior, default) to 9 on the "Settings" page. Clicking on the green icon in front of a similar term will copy the translation and romanization into the form fields for further editing. Important: If you want to use this new feature, you must change the setting "Similar terms to be displayed while adding/editing a term" to a value greater than 0. It will make more sense to do this if you have already many saved terms (e.g. more than 1,000). If you start with a language and have only a few terms, no or not very similar terms will be normally displayed and this feature will not make much sense.
"https://" dictionary URIs are now allowed in the language settings. Checking of dictionary URIs in the language settings has been improved.
The Glosbe dictionary page has been improved with a simple form to change the term and do a requery if you are unhappy with the query results.
The jQuery and jPlayer libraries have been updated to v1.11.1 and v2.7.0, respectively. The jQuery.ScrollTo package has been updated to v1.4.13. The Floating Menu package has been updated to v1.12.
Broken links corrected or deleted. From now on, only the installation with EasyPHP for Windows and MAMP for Mac OS X will be explained in detail and is recommended. Other local web server packages, like XAMPP, etc., are of course still possible, but it's beyond the scope of this document to explain all the details for every webserver package (it will also confuse most LWT users who are not familiar with web server packages and their setup).
"Mobile_Detect.php" updated to v2.8.3.
Documentation updated.