diff --git a/Makefile b/Makefile index 7ddffaae9..2dca6defb 100644 --- a/Makefile +++ b/Makefile @@ -467,6 +467,7 @@ XGETTEXT_BIN=xgettext pot: mkdir -p $(TEMPLATE_DIR) $(XGETTEXT_BIN) --from-code=utf-8 --keyword=C_:1c,2 \ + --add-comments=@translators \ reader.lua `find frontend -iname "*.lua"` \ `find plugins -iname "*.lua"` \ `find tools -iname "*.lua"` \ diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index db40db4ae..5337e28c0 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -39,6 +39,7 @@ local lfs = require("libs/libkoreader-lfs") local logger = require("logger") local util = require("ffi/util") local _ = require("gettext") +local C_ = _.pgettext local Screen = Device.screen local T = require("ffi/util").template @@ -201,14 +202,14 @@ function FileManager:init() local buttons = { { { - text = _("Copy"), + text = C_("File", "Copy"), callback = function() copyFile(file) UIManager:close(self.file_dialog) end, }, { - text = _("Paste"), + text = C_("File", "Paste"), enabled = fileManager.clipboard and true or false, callback = function() pasteHere(file) @@ -641,6 +642,7 @@ function FileManager:openRandomFile(dir) ReaderUI:showReader(random_file) end, + -- @translators Another file. This is a button on the open random file dialog. It presents a file with the choices Open/Another. choice2_text = _("Another"), choice2_callback = function() self:openRandomFile(dir) diff --git a/frontend/apps/filemanager/filemanagermenu.lua b/frontend/apps/filemanager/filemanagermenu.lua index 1ccb6c96a..ab4bac289 100644 --- a/frontend/apps/filemanager/filemanagermenu.lua +++ b/frontend/apps/filemanager/filemanagermenu.lua @@ -382,6 +382,7 @@ function FileManagerMenu:setUpdateItemTable() end } self.menu_items.find_file = { + -- @translators Search for files by name. text = _("Find a file"), callback = function() self.ui:handleEvent(Event:new("ShowFileSearch", self.ui.file_chooser.path)) diff --git a/frontend/apps/filemanager/filemanagersearch.lua b/frontend/apps/filemanager/filemanagersearch.lua index fcee1f7ee..24ed19cd1 100644 --- a/frontend/apps/filemanager/filemanagersearch.lua +++ b/frontend/apps/filemanager/filemanagersearch.lua @@ -79,7 +79,7 @@ function Search:getCalibre() logger.dbg("search Calibre database") self.metafile_1 = findcalibre("/mnt") if not self.metafile_1 then - self.error = _("SEARCH_LIBRARY_PATH should be defined in DEFAULTS.LUA.") + self.error = _("The SEARCH_LIBRARY_PATH variable must be defined in 'persistent.defaults.lua' in order to use the calibre file search functionality.") end else if string.sub(SEARCH_LIBRARY_PATH, string.len(SEARCH_LIBRARY_PATH)) ~= "/" then @@ -189,6 +189,7 @@ function Search:ShowSearch() end, }, { + -- @translators Search for books in calibre catalog. text = _("Find books"), enabled = true, callback = function() @@ -494,7 +495,7 @@ function Search:onMenuHold(item) item.info = item.info .. item.path local f = io.open(item.path, "r") if f == nil then - item.info = item.info .. "\n" .. _("File not found!") + item.info = item.info .. "\n" .. _("File not found.") else item.info = item.info .. "\n" .. _("Size:") .. " " .. string.format("%4.1fM", lfs.attributes(item.path, "size")/1024/1024) f:close() diff --git a/frontend/apps/reader/modules/readerfont.lua b/frontend/apps/reader/modules/readerfont.lua index eff2727d4..413bd9384 100644 --- a/frontend/apps/reader/modules/readerfont.lua +++ b/frontend/apps/reader/modules/readerfont.lua @@ -11,6 +11,7 @@ local Screen = require("device").screen local UIManager = require("ui/uimanager") local T = require("ffi/util").template local _ = require("gettext") +local C_ = _.pgettext local ReaderFont = InputContainer:new{ font_face = nil, @@ -294,7 +295,7 @@ function ReaderFont:makeDefault(face, touchmenu_instance) G_reader_settings:saveSetting("cre_font", face) if touchmenu_instance then touchmenu_instance:updateItems() end end, - choice2_text = _("Fallback"), + choice2_text = C_("Font", "Fallback"), choice2_callback = function() if self.ui.document:setFallbackFontFace(face) then G_reader_settings:saveSetting("fallback_font", face) diff --git a/frontend/apps/reader/modules/readerfooter.lua b/frontend/apps/reader/modules/readerfooter.lua index f82c03cf6..208a985c2 100644 --- a/frontend/apps/reader/modules/readerfooter.lua +++ b/frontend/apps/reader/modules/readerfooter.lua @@ -652,7 +652,7 @@ function ReaderFooter:addToMainMenu(menu_items) text = _("Separator"), sub_item_table = { { - text = _("Vertical line") .. " (|)", + text = _("Vertical line (|)"), checked_func = function() return self.settings.items_separator == "bar" or self.settings.items_separator == nil end, @@ -663,7 +663,7 @@ function ReaderFooter:addToMainMenu(menu_items) end, }, { - text = _("Bullet") .. " (•)", + text = _("Bullet (•)"), checked_func = function() return self.settings.items_separator == "bullet" end, diff --git a/frontend/apps/reader/modules/readerfrontlight.lua b/frontend/apps/reader/modules/readerfrontlight.lua index 902bda99d..d1cbda5c9 100644 --- a/frontend/apps/reader/modules/readerfrontlight.lua +++ b/frontend/apps/reader/modules/readerfrontlight.lua @@ -157,7 +157,7 @@ function ReaderFrontLight:onShowIntensity() if powerd:isFrontlightOff() then new_text = _("Frontlight disabled.") else - new_text = T(_("Frontlight intensity is set to %1."), powerd:frontlightIntensity()) + new_text = T(_("Frontlight intensity set to %1."), powerd:frontlightIntensity()) end UIManager:show(Notification:new{ text = new_text, diff --git a/frontend/apps/reader/modules/readerhyphenation.lua b/frontend/apps/reader/modules/readerhyphenation.lua index 56220970d..0e76f6ef9 100644 --- a/frontend/apps/reader/modules/readerhyphenation.lua +++ b/frontend/apps/reader/modules/readerhyphenation.lua @@ -7,6 +7,7 @@ local UIManager = require("ui/uimanager") local logger = require("logger") local util = require("util") local _ = require("gettext") +local C_ = _.pgettext local T = require("ffi/util").template local ReaderHyphenation = InputContainer:new{ @@ -126,7 +127,7 @@ function ReaderHyphenation:init() G_reader_settings:delSetting("hyph_alg_fallback") if touchmenu_instance then touchmenu_instance:updateItems() end end, - choice2_text = _("Fallback"), + choice2_text = C_("Hyphenation", "Fallback"), choice2_callback = function() G_reader_settings:saveSetting("hyph_alg_fallback", v.filename) G_reader_settings:delSetting("hyph_alg_default") diff --git a/frontend/apps/reader/modules/readertypeset.lua b/frontend/apps/reader/modules/readertypeset.lua index ea6cbb8c7..21fb56099 100644 --- a/frontend/apps/reader/modules/readertypeset.lua +++ b/frontend/apps/reader/modules/readertypeset.lua @@ -416,6 +416,7 @@ function ReaderTypeset:addToMainMenu(menu_items) sub_item_table = self:genStyleSheetMenu(), } menu_items.floating_punctuation = { + -- @translators See https://en.wikipedia.org/wiki/Hanging_punctuation text = _("Hanging punctuation"), checked_func = function() return self.floating_punctuation == 1 end, callback = function() diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index 612f7cc60..d4a4cc786 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -856,6 +856,7 @@ function ReaderView:getRenderModeMenuTable() } end return { + -- @translators Selects which layers of the DjVu image should be rendered. Valid rendering modes are color, black, mask, foreground, and background. See http://djvu.sourceforge.net/ and https://en.wikipedia.org/wiki/DjVu for more information about the format. text = _("DjVu render mode"), sub_item_table = { make_mode(_("COLOUR (works for both colour and b&w pages)"), 0), diff --git a/frontend/ui/data/strings.lua b/frontend/ui/data/strings.lua index 2df9ee5a5..c7721c831 100644 --- a/frontend/ui/data/strings.lua +++ b/frontend/ui/data/strings.lua @@ -14,14 +14,17 @@ S.B_PAGE_MARGIN = _("Bottom Margin") S.SYNC_T_B_PAGE_MARGINS = _("Sync T/B Margins") S.LINE_SPACING = _("Line Spacing") S.COLUMNS = _("Columns") -S.TEXT_ALIGN = _("Text Align") +-- @translators Text alignment. Options given as icons: left, right, center, justify. +S.TEXT_ALIGN = _("Alignment") S.FONTSIZE_FINE_TUNING = _("Fine Tuning") S.CONTRAST = _("Contrast") +-- @translators Reflow text. S.REFLOW = _("Reflow") S.DEWATERMARK = _("Dewatermark") S.DOC_LANG = _("Document Language") S.VERTICAL_TEXT = _("Vertical Text") S.WORD_GAP = _("Word Gap") +-- @translators The maximum size of a dust or ink speckle to be ignored instead of being considered a character. S.DEFECT_SIZE = _("Reflow Speckle Ignore Size") S.RENDER_QUALITY = _("Render Quality") S.AUTO_STRAIGHTEN = _("Auto Straighten") @@ -36,6 +39,7 @@ S.EMBEDDED_FONTS = _("Embedded Fonts") S.BLOCK_RENDERING_MODE = _("Render Mode") S.WRITING_DIR = _("Writing Direction") S.PROGRESS_BAR = _("Progress Bar") +-- @translators If OCR is unclear, please see https://en.wikipedia.org/wiki/Optical_character_recognition S.FORCED_OCR = _("Forced OCR") S.HW_DITHERING = _("Dithering") S.INVERSE_READING_ORDER = _("Inverse Order") @@ -73,9 +77,13 @@ S.REGULAR = _("regular") S.BOLD = _("bold") S.VIEW_SCROLL = _("continuous") S.VIEW_PAGE = _("page") +-- @translators LTR is left to right, which is the regular European writing direction. S.LTR = _("LTR") +-- @translators RTL is right to left, which is the regular writing direction in languages like Hebrew, Arabic, Persian and Urdu. S.RTL = _("RTL") +-- @translators TBRTL is top-to-bottom-right-to-left, which is a traditional Chinese/Japanese writing direction. S.TBRTL = _("TBRTL") +-- @translators TBLTR is top-to-bottom-left-to-right, which is a traditional Chinese/Japanese writing direction. S.TBLTR = _("TBLTR") S.FULL = _("full") S.MINI = _("mini") diff --git a/frontend/ui/network/manager.lua b/frontend/ui/network/manager.lua index 6915d75b1..c4306c640 100644 --- a/frontend/ui/network/manager.lua +++ b/frontend/ui/network/manager.lua @@ -339,7 +339,7 @@ function NetworkMgr:getMenuTable(common_settings) end function NetworkMgr:showNetworkMenu(complete_callback) - local info = InfoMessage:new{text = _("Scanning…")} + local info = InfoMessage:new{text = _("Scanning for networks…")} UIManager:show(info) UIManager:nextTick(function() local network_list, err = self:getNetworkList() @@ -366,7 +366,7 @@ function NetworkMgr:showNetworkMenu(complete_callback) end function NetworkMgr:reconnectOrShowNetworkMenu(complete_callback) - local info = InfoMessage:new{text = _("Scanning…")} + local info = InfoMessage:new{text = _("Scanning for networks…")} UIManager:show(info) UIManager:nextTick(function() local network_list, err = self:getNetworkList() diff --git a/frontend/ui/translator.lua b/frontend/ui/translator.lua index 4654b5a3a..a05cfcf36 100644 --- a/frontend/ui/translator.lua +++ b/frontend/ui/translator.lua @@ -24,6 +24,7 @@ local _ = require("gettext") -- 20181217: 104 supported languages local AUTODETECT_LANGUAGE = "auto" local SUPPORTED_LANGUAGES = { + -- @translators Many of the names for languages can be conveniently found pre-translated in the relevant language of this Wikipedia article: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes af = _("Afrikaans"), sq = _("Albanian"), am = _("Amharic"), @@ -54,6 +55,7 @@ local SUPPORTED_LANGUAGES = { ka = _("Georgian"), de = _("German"), el = _("Greek"), + -- @translators Many of the names for languages can be conveniently found pre-translated in the relevant language of this Wikipedia article: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes gu = _("Gujarati"), ht = _("Haitian Creole"), ha = _("Hausa"), @@ -69,6 +71,7 @@ local SUPPORTED_LANGUAGES = { it = _("Italian"), ja = _("Japanese"), jw = _("Javanese"), + -- @translators Many of the names for languages can be conveniently found pre-translated in the relevant language of this Wikipedia article: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes kn = _("Kannada"), kk = _("Kazakh"), km = _("Khmer"), @@ -124,6 +127,7 @@ local SUPPORTED_LANGUAGES = { uz = _("Uzbek"), vi = _("Vietnamese"), cy = _("Welsh"), + -- @translators Many of the names for languages can be conveniently found pre-translated in the relevant language of this Wikipedia article: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes xh = _("Xhosa"), yi = _("Yiddish"), yo = _("Yoruba"), diff --git a/frontend/ui/widget/dictquicklookup.lua b/frontend/ui/widget/dictquicklookup.lua index 376508a19..9ecff9734 100644 --- a/frontend/ui/widget/dictquicklookup.lua +++ b/frontend/ui/widget/dictquicklookup.lua @@ -25,6 +25,7 @@ local WidgetContainer = require("ui/widget/container/widgetcontainer") local logger = require("logger") local util = require("util") local _ = require("gettext") +local C_ = _.pgettext local Screen = Device.screen local T = require("ffi/util").template @@ -429,7 +430,14 @@ function DictQuickLookup:update() { -- if dictionary result, do the same search on wikipedia -- if already wiki, get the full page for the current result - text = self.is_wiki and _("Wikipedia full") or _("Wikipedia"), + text_func = function() + if self.is_wiki then + -- @translators Full Wikipedia article. + return C_("Button", "Wikipedia full") + else + return _("Wikipedia") + end + end, callback = function() UIManager:scheduleIn(0.1, function() self:lookupWikipedia(self.is_wiki) -- will get_fullpage if is_wiki diff --git a/frontend/ui/widget/filechooser.lua b/frontend/ui/widget/filechooser.lua index c42c5aa93..8d5aea412 100644 --- a/frontend/ui/widget/filechooser.lua +++ b/frontend/ui/widget/filechooser.lua @@ -214,6 +214,7 @@ function FileChooser:genItemTableFromPath(path) if num_items == 1 then istr = _("1 item") else + -- @translators %1 is a placeholder for a plural number. So "%1 items" will automatically show up as "2 items", "3 items", etc. istr = ffiUtil.template(_("%1 items"), num_items) end local text diff --git a/frontend/ui/widget/touchmenu.lua b/frontend/ui/widget/touchmenu.lua index e1b912ed1..84586f755 100644 --- a/frontend/ui/widget/touchmenu.lua +++ b/frontend/ui/widget/touchmenu.lua @@ -593,6 +593,7 @@ function TouchMenu:updateItems() table.insert(self.item_group, self.footer_top_margin) table.insert(self.item_group, self.footer) + -- @translators %1 is the current page. %2 is the total number of pages. In some languages a good translation might need to reverse this order, for instance: "Total %2, page %1". self.page_info_text.text = util.template(_("Page %1 of %2"), self.page, self.page_num) self.page_info_left_chev:showHide(self.page_num > 1) self.page_info_right_chev:showHide(self.page_num > 1) diff --git a/frontend/util.lua b/frontend/util.lua index 3e311b6de..fbbd1c0b7 100644 --- a/frontend/util.lua +++ b/frontend/util.lua @@ -153,12 +153,14 @@ function util.secondsToHClock(seconds, withoutSeconds, hmsFormat) mins = string.format("%.f", round(seconds / 60)) return mins .. "'" end + -- @translators This is the 'h' for hour, like in 1h30. This is a duration. return T(_("%1h%2"), hours, mins) end local secs = string.format("%02.f", math.floor(seconds - hours * 3600 - mins * 60)) if hours == "0" then mins = string.format("%.f", round(seconds / 60)) if hmsFormat then + -- @translators This is the 'm' for minute and the 's' for second, like in 1m30s. This is a duration. return T(_("%1m%2s"), mins, secs) else return mins .. "'" .. secs .. "''" @@ -166,8 +168,10 @@ function util.secondsToHClock(seconds, withoutSeconds, hmsFormat) end if hmsFormat then if secs == "00" then + -- @translators This is the 'h' for hour and the 'm' for minute, like in 1h30m. This is a duration. return T(_("%1h%2m"), hours, mins) else + -- @translators This is the 'h' for hour, the 'm' for minute and the 's' for second, like in 1h30m30s. This is a duration. return T(_("%1h%2m%3s"), hours, mins, secs) end diff --git a/plugins/coverbrowser.koplugin/bookinfomanager.lua b/plugins/coverbrowser.koplugin/bookinfomanager.lua index e562f8937..3b7d5b493 100644 --- a/plugins/coverbrowser.koplugin/bookinfomanager.lua +++ b/plugins/coverbrowser.koplugin/bookinfomanager.lua @@ -692,7 +692,11 @@ This extraction may take time and use some battery power: you may wish to keep y local recursive = Trapper:confirm(_([[ Do you want to extract book information for books in sub-directories too?]] - ), _("Here only"), _("Here and under")) + ), + -- @translators Extract book information only for books in this directory. + _("Here only"), + -- @translators Extract book information for books in this directory as well as in subdirectories. + _("Here and under")) local refresh_existing = Trapper:confirm(_([[ Do you want to refresh metadata and covers that have already been extracted?]] diff --git a/plugins/evernote.koplugin/main.lua b/plugins/evernote.koplugin/main.lua index 25478ddff..5d31f28e0 100644 --- a/plugins/evernote.koplugin/main.lua +++ b/plugins/evernote.koplugin/main.lua @@ -166,11 +166,11 @@ function EvernoteExporter:addToMainMenu(menu_items) self.config:purge() UIManager:show(ConfirmBox:new{ text = _("History records have been purged.\nAll notes will be exported again next time.\nWould you like to remove the existing KOReaderClipping.txt file to avoid duplication?\nRecords will be appended to KOReaderClipping.txt instead of being overwritten."), - ok_text = _("Yes, remove it"), + ok_text = _("Remove file"), ok_callback = function() os.remove(self.text_clipping_file) end, - cancel_text = _("No, keep it"), + cancel_text = _("Keep file"), }) end } @@ -409,20 +409,22 @@ function EvernoteExporter:exportClippings(clippings) local all_count = export_count + error_count if export_count > 0 and error_count == 0 then if all_count == 1 then - msg = _("Exported notes from book:") .. "\n" .. export_title + msg = T(_("Exported notes from the book:\n%1"), export_title) else msg = T( - _("Exported notes from book:\n%1\nand %2 others."), + -- @translators %1 is the title of a book and %2 a number of 2 or higher. To track better handling of plurals please see https://github.com/koreader/koreader/issues/5249 + _("Exported notes from the book:\n%1\nand %2 others."), export_title, all_count-1 ) end elseif error_count > 0 then if all_count == 1 then - msg = _("An error occurred while trying to export notes from book:") .. "\n" .. error_title + msg = T(_("An error occurred while trying to export notes from the book:\n%1"), error_title) else msg = T( - _("Multiple errors occurred while trying to export notes from book:\n%1\nand %2 others."), + -- @translators %1 is the title of a book and %2 a number of 2 or higher. To track better handling of plurals please see https://github.com/koreader/koreader/issues/5249 + _("Multiple errors occurred while trying to export notes from the book:\n%1\nand %2 others."), error_title, error_count-1 ) diff --git a/plugins/kosync.koplugin/main.lua b/plugins/kosync.koplugin/main.lua index af1fcb870..e0c2cb0a2 100644 --- a/plugins/kosync.koplugin/main.lua +++ b/plugins/kosync.koplugin/main.lua @@ -209,6 +209,7 @@ function KOSync:addToMainMenu(menu_items) keep_menu_open = true, tap_input_func = function() return { + -- @translators Server address defined by user for progress sync. title = _("Custom progress sync server address"), input = self.kosync_custom_server or "https://", type = "text", diff --git a/plugins/systemstat.koplugin/main.lua b/plugins/systemstat.koplugin/main.lua index 30b0dd305..e60e20c54 100644 --- a/plugins/systemstat.koplugin/main.lua +++ b/plugins/systemstat.koplugin/main.lua @@ -43,6 +43,7 @@ function SystemStat:appendCounters() string.format("%.2f", os.difftime(os.time(), self.start_sec) / 60 / 60)}) self:put({_("Counters"), ""}) self:put({_(" wake-ups"), self.wakeup_count}) + -- @translators The number of "sleeps", that is the number of times the device has entered standby. This could also be translated as a rendition of a phrase like "entered sleep". self:put({_(" sleeps"), self.sleep_count}) self:put({_(" charge cycles"), self.charge_count}) self:put({_(" discharge cycles"), self.discharge_count}) @@ -112,8 +113,10 @@ function SystemStat:appendSystemInfo() local stat = systemInfo() if stat.cpu ~= nil then self:put({_("System information"), ""}) + -- @translators Ticks is a highly technical term. See https://superuser.com/a/101202 The correct translation is likely to simply be "ticks". self:put({_(" Total ticks (million)"), string.format("%.2f", stat.cpu.total / 1000000)}) + -- @translators Ticks is a highly technical term. See https://superuser.com/a/101202 The correct translation is likely to simply be "ticks". self:put({_(" Idle ticks (million)"), string.format("%.2f", stat.cpu.idle / 1000000)}) self:put({_(" Processor usage %"),