← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/fh1-scenario-groundwork-emp1 into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/fh1-scenario-groundwork-emp1 into lp:widelands.

Commit message:
Started converting scenarios to new font renderer

- Story Message Box and Objectives now try to use the new font renderer before falling back to the old one.
- Added version of scenario formatting for the new renderer.
- Converted Tutorial 1 and Empire Scenario 1 to new font renderer
- Atlantean campaign now uses the campaign_message_box function.


Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/fh1-scenario-groundwork-emp1/+merge/335294

Finished the needed C++ programming for converting the scenarios to the new font renderer. Using Tutorial 1 and Empire 1 as test cases.

When testing, all story messages and objectives need to be looked at, to make sure that there's no broken markup.

https://code.launchpad.net/~widelands-dev/widelands/fh1-editorhelp should be reviewed first - those changes were merged into this branch to make it work.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/fh1-scenario-groundwork-emp1 into lp:widelands.
=== modified file 'data/campaigns/emp01.wmf/scripting/texts.lua'
--- data/campaigns/emp01.wmf/scripting/texts.lua	2016-05-17 16:40:22 +0000
+++ data/campaigns/emp01.wmf/scripting/texts.lua	2017-12-17 11:19:18 +0000
@@ -2,8 +2,7 @@
 -- Some formating functions
 -- =========================
 
-include "scripting/formatting.lua"
-include "scripting/format_scenario.lua"
+include "scripting/richtext_scenarios.lua"
 
 function lutius(title, text)
    return speech("map:Lutius.png", "2F9131", title, text)
@@ -28,7 +27,7 @@
    title=_"Build a blockhouse",
    number = 1,
    body = objective_text(_"Blockhouse",
-      listitem_bullet(_[[Build a blockhouse at the red house symbol on the east side of the forests, to the right of your provisional headquarters.]])
+      li(_[[Build a blockhouse at the red house symbol on the east side of the forests, to the right of your provisional headquarters.]])
    ),
 }
 
@@ -37,7 +36,7 @@
    title=_"Build a lumberjack’s house",
    number = 1,
    body = objective_text(_"Lumberjack’s House",
-      listitem_bullet(_[[Build a lumberjack’s house at the red house symbol, south of your provisional headquarters.]])
+      li(_[[Build a lumberjack’s house at the red house symbol, south of your provisional headquarters.]])
    ),
 }
 
@@ -46,7 +45,7 @@
    title=_"Build 2 lumberjack’s houses and a sawmill",
    number = 3,
    body = objective_text(_"Two Lumberjack’s Houses and a Sawmill",
-      listitem_bullet(_[[Build two more lumberjack’s houses and a sawmill as soon as there is enough space for them.]])
+      li(_[[Build two more lumberjack’s houses and a sawmill as soon as there is enough space for them.]])
    ),
 }
 
@@ -55,7 +54,7 @@
    title=_"Build a forester’s house",
    number = 1,
    body = objective_text(_"Forester’s House",
-      listitem_bullet(_[[Build a forester’s house to preserve the wood resources of this island.]])
+      li(_[[Build a forester’s house to preserve the wood resources of this island.]])
    ),
 }
 
@@ -64,8 +63,8 @@
    title=_"Build a quarry",
    number = 5,
    body = objective_text(_"Quarry",
-      listitem_bullet(_[[Build a quarry in the south to cut some granite and marble out of the rocks.]]) ..
-      listitem_arrow(_[[These might be used for future buildings.]])
+      li(_[[Build a quarry in the south to cut some granite and marble out of the rocks.]]) ..
+      li_arrow(_[[These might be used for future buildings.]])
    ),
 }
 

=== modified file 'data/i18n/locales.lua'
--- data/i18n/locales.lua	2017-12-17 03:57:22 +0000
+++ data/i18n/locales.lua	2017-12-17 11:19:18 +0000
@@ -2,387 +2,387 @@
 -- The locale data is managed in Transifex.
 
 return {
-   -- Locales are identified by their ISO code.
-   en = {
-      -- Used to display the locale in the Options menu.
-      name = "English",
-
-      -- Defines the language's position on the list in the Options menu.
-      sort_name = "English",
-
-      -- The font set used, including the script's direction. See i18n/fonts.lua
-      font = "default"
-   },
-
-   ar = {
-      name = "العربية",
-      sort_name = "Al-ʿArabiyyah",
-      font = "arabic"
-   },
-
-   ast = {
-      name = "Asturianu",
-      sort_name = "Asturianu",
-      font = "default"
-   },
-
-   bg = {
-      name = "Български",
-      sort_name = "Balgarski",
-      font = "default"
-   },
-
-   br = {
-      name = "Brezhoneg",
-      sort_name = "Brezhoneg",
-      font = "default"
-   },
-
-   ca = {
-      name = "Català",
-      sort_name = "Catala",
-      font = "default"
-   },
-
-   cs = {
-      name = "Čeština",
-      sort_name = "Cestina",
-      font = "default"
-   },
-
-   da = {
-      name = "Dansk",
-      sort_name = "Dansk",
-      font = "default"
-   },
-
-   de = {
-      name = "Deutsch",
-      sort_name = "Deutsch",
-      font = "default"
-   },
-
-   el = {
-      name = "Ελληνικά",
-      sort_name = "Ellinika",
-      font = "default"
-   },
-
-   en_CA = {
-      name = "Canadian English",
-      sort_name = "English (Canada)",
-      font = "default"
-   },
-
-   en_GB = {
-      name = "British English",
-      sort_name = "English (Great Britain)",
-      font = "default"
-   },
-
-   en_US = {
-      name = "US American English",
-      sort_name = "English (USA)",
-      font = "default"
-   },
-
-   eo = {
-      name = "Esperanto",
-      sort_name = "Esperanto",
-      font = "default"
-   },
-
-   es = {
-      name = "Español",
-      sort_name = "Espanol",
-      font = "default"
-   },
-
-   et = {
-      name = "Eesti keel",
-      sort_name = "Eesti keel",
-      font = "default"
-   },
-
-   eu = {
-      name = "Euskara",
-      sort_name = "Euskara",
-      font = "default"
-   },
-
-   fa = {
-      name = "فارسی",
-      sort_name = "Farsi",
-      font = "arabic"
-   },
-
-   fi = {
-      name = "Suomi",
-      sort_name = "Suomi",
-      font = "default"
-   },
-
-   fr = {
-      name = "Français",
-      sort_name = "Francais",
-      font = "default"
-   },
-
-   fy = {
-      name = "Frysk",
-      sort_name = "Frysk",
-      font = "default"
-   },
-
-   ga = {
-      name = "Gaeilge",
-      sort_name = "Gaeilge",
-      font = "default"
-   },
-
-   gd = {
-      name = "Gàidhlig",
-      sort_name = "Gaidhlig",
-      font = "default"
-   },
-
-   gl = {
-      name = "Galego",
-      sort_name = "Galego",
-      font = "default"
-   },
-
-   he = {
-      name = "עברית",
-      sort_name = "Ivrit",
-      font = "hebrew"
-   },
-
-   hi = {
-      name = "हिन्दी",
-      sort_name = "Hindi",
-      font = "devanagari"
-   },
-
-   hr = {
-      name = "Hrvatski",
-      sort_name = "Hrvatski",
-      font = "default"
-   },
-
-   hu = {
-      name = "Magyar",
-      sort_name = "Magyar",
-      font = "default"
-   },
-
-   ia = {
-      name = "Interlingua",
-      sort_name = "Interlingua",
-      font = "default"
-   },
-
-   id = {
-      name = "Bahasa Indonesia",
-      sort_name = "Indonesia",
-      font = "default"
-   },
-
-   ig = {
-      name = "Igbo",
-      sort_name = "Igbo",
-      font = "default"
-   },
-
-   it = {
-      name = "Italiano",
-      sort_name = "Italiano",
-      font = "default"
-   },
-
-   ja = {
-      name = "日本語",
-      sort_name = "Nihongo",
-      font = "cjk"
-   },
-
-   jv = {
-      name = "Basa jawa",
-      sort_name = "Jawa",
-      font = "default"
-   },
-
-   ka = {
-      name = "ქართული",
-      sort_name = "Kartuli",
-      font = "default"
-   },
-
-   ko = {
-      name = "한국어",
-      sort_name = "Hangug-eo",
-      font = "cjk"
-   },
-
-   krl = {
-      name = "Karjala",
-      sort_name = "Karjala",
-      font = "default"
-   },
-
-   la = {
-      name = "Lingua latīna",
-      sort_name = "Latina",
-      font = "default"
-   },
-
-   lt = {
-      name = "Lietuvių",
-      sort_name = "Lietuviu",
-      font = "default"
-   },
-
-   mr = {
-      name = "मराठी",
-      sort_name = "Marathi",
-      font = "devanagari"
-   },
-
-   ms = {
-      name = "بهاس ملايو",
-      sort_name = "Melayu",
-      font = "arabic"
-   },
-
-   my = {
-      name = "မြန်မာစ",
-      sort_name = "Myanma",
-      font = "myanmar"
-   },
-
-   nb = {
-      name = "Norsk (Bokmål)",
-      sort_name = "Norsk (Bokmal)",
-      font = "default"
-   },
-
-   nds = {
-      name = "Plattdütsch",
-      sort_name = "Plattdutsch",
-      font = "default"
-   },
-
-   nl = {
-      name = "Nederlands",
-      sort_name = "Nederlands",
-      font = "default"
-   },
-
-   nn = {
-      name = "Nynorsk",
-      sort_name = "Norsk (Nynorsk)",
-      font = "default"
-   },
-
-   oc = {
-      name = "Occitan",
-      sort_name = "Occitan",
-      font = "default"
-   },
-
-   pl = {
-      name = "Polski",
-      sort_name = "Polski",
-      font = "default"
-   },
-
-   pt = {
-      name = "Português",
-      sort_name = "Portugues",
-      font = "default"
-   },
-
-   pt_BR = {
-      name = "Português do Brasil",
-      sort_name = "Portugues (Brasil)",
-      font = "default"
-   },
-
-   ro = {
-      name = "Română",
-      sort_name = "Romana",
-      font = "default"
-   },
-
-   ru = {
-      name = "Русский",
-      sort_name = "Russky",
-      font = "default"
-   },
-
-   rw = {
-      name = "Kinyarwanda",
-      sort_name = "Kinyarwanda",
-      font = "default"
-   },
-
-   si = {
-      name = "සිංහල",
-      sort_name = "Simhala",
-      font = "sinhala"
-   },
-
-   sk = {
-      name = "Slovenčina",
-      sort_name = "Slovencina",
-      font = "default"
-   },
-
-   sl = {
-      name = "Slovenski jezik",
-      sort_name = "Slovenski",
-      font = "default"
-   },
-
-   sr = {
-      name = "српски",
-      sort_name = "Srpski",
-      font = "default"
-   },
-
-   sv = {
-      name = "Svenska",
-      sort_name = "Svenska",
-      font = "default"
-   },
-
-   tr = {
-      name = "Türkçe",
-      sort_name = "Turkce",
-      font = "default"
-   },
-
-   uk = {
-      name = "українська мова",
-      sort_name = "Ukrayinska",
-      font = "default"
-   },
-
-   vi = {
-      name = "Tiếng Việt",
-      sort_name = "Viet",
-      font = "default"
-   },
-
-   zh_CN = {
-      name = "简体中文",
-      sort_name = "Jianti Zhongwen",
-      font = "cjk"
-   },
-
-   zh_TW = {
-      name = "繁體中文",
-      sort_name = "Fanti Zhongwen",
-      font = "cjk"
-   },
+	-- Locales are identified by their ISO code.
+ 	en = {
+		-- Used to display the locale in the Options menu.
+		name = "English",
+
+		-- Defines the language's position on the list in the Options menu.
+		sort_name = "English",
+
+		-- The font set used, including the script's direction. See i18n/fonts.lua
+		font = "default"
+	},
+
+	ar = {
+		name = "العربية",
+		sort_name = "Al-ʿArabiyyah",
+		font = "arabic"
+	},
+
+	ast = {
+		name = "Asturianu",
+		sort_name = "Asturianu",
+		font = "default"
+	},
+
+	bg = {
+		name = "Български",
+		sort_name = "Balgarski",
+		font = "default"
+	},
+
+	br = {
+		name = "Brezhoneg",
+		sort_name = "Brezhoneg",
+		font = "default"
+	},
+
+	ca = {
+		name = "Català",
+		sort_name = "Catala",
+		font = "default"
+	},
+
+	cs = {
+		name = "Čeština",
+		sort_name = "Cestina",
+		font = "default"
+	},
+
+	da = {
+		name = "Dansk",
+		sort_name = "Dansk",
+		font = "default"
+	},
+
+	de = {
+		name = "Deutsch",
+		sort_name = "Deutsch",
+		font = "default"
+	},
+
+	el = {
+		name = "Ελληνικά",
+		sort_name = "Ellinika",
+		font = "default"
+	},
+
+	en_CA = {
+		name = "Canadian English",
+		sort_name = "English (Canada)",
+		font = "default"
+	},
+
+	en_GB = {
+		name = "British English",
+		sort_name = "English (Great Britain)",
+		font = "default"
+	},
+
+	en_US = {
+		name = "US American English",
+		sort_name = "English (USA)",
+		font = "default"
+	},
+
+	eo = {
+		name = "Esperanto",
+		sort_name = "Esperanto",
+		font = "default"
+	},
+
+	es = {
+		name = "Español",
+		sort_name = "Espanol",
+		font = "default"
+	},
+
+	et = {
+		name = "Eesti keel",
+		sort_name = "Eesti keel",
+		font = "default"
+	},
+
+	eu = {
+		name = "Euskara",
+		sort_name = "Euskara",
+		font = "default"
+	},
+
+	fa = {
+		name = "فارسی",
+		sort_name = "Farsi",
+		font = "arabic"
+	},
+
+	fi = {
+		name = "Suomi",
+		sort_name = "Suomi",
+		font = "default"
+	},
+
+	fr = {
+		name = "Français",
+		sort_name = "Francais",
+		font = "default"
+	},
+
+	fy = {
+		name = "Frysk",
+		sort_name = "Frysk",
+		font = "default"
+	},
+
+	ga = {
+		name = "Gaeilge",
+		sort_name = "Gaeilge",
+		font = "default"
+	},
+
+	gd = {
+		name = "Gàidhlig",
+		sort_name = "Gaidhlig",
+		font = "default"
+	},
+
+	gl = {
+		name = "Galego",
+		sort_name = "Galego",
+		font = "default"
+	},
+
+	he = {
+		name = "עברית",
+		sort_name = "Ivrit",
+		font = "hebrew"
+	},
+
+	hi = {
+		name = "हिन्दी",
+		sort_name = "Hindi",
+		font = "devanagari"
+	},
+
+	hr = {
+		name = "Hrvatski",
+		sort_name = "Hrvatski",
+		font = "default"
+	},
+
+	hu = {
+		name = "Magyar",
+		sort_name = "Magyar",
+		font = "default"
+	},
+
+	ia = {
+		name = "Interlingua",
+		sort_name = "Interlingua",
+		font = "default"
+	},
+
+	id = {
+		name = "Bahasa Indonesia",
+		sort_name = "Indonesia",
+		font = "default"
+	},
+
+	ig = {
+		name = "Igbo",
+		sort_name = "Igbo",
+		font = "default"
+	},
+
+	it = {
+		name = "Italiano",
+		sort_name = "Italiano",
+		font = "default"
+	},
+
+	ja = {
+		name = "日本語",
+		sort_name = "Nihongo",
+		font = "cjk"
+	},
+
+	jv = {
+		name = "Basa jawa",
+		sort_name = "Jawa",
+		font = "default"
+	},
+
+	ka = {
+		name = "ქართული",
+		sort_name = "Kartuli",
+		font = "default"
+	},
+
+	ko = {
+		name = "한국어",
+		sort_name = "Hangug-eo",
+		font = "cjk"
+	},
+
+	krl = {
+		name = "Karjala",
+		sort_name = "Karjala",
+		font = "default"
+	},
+
+	la = {
+		name = "Lingua latīna",
+		sort_name = "Latina",
+		font = "default"
+	},
+
+	lt = {
+		name = "Lietuvių",
+		sort_name = "Lietuviu",
+		font = "default"
+	},
+
+	mr = {
+		name = "मराठी",
+		sort_name = "Marathi",
+		font = "devanagari"
+	},
+
+	ms = {
+		name = "بهاس ملايو",
+		sort_name = "Melayu",
+		font = "arabic"
+	},
+
+	my = {
+		name = "မြန်မာစ",
+		sort_name = "Myanma",
+		font = "myanmar"
+	},
+
+	nb = {
+		name = "Norsk (Bokmål)",
+		sort_name = "Norsk (Bokmal)",
+		font = "default"
+	},
+
+	nds = {
+		name = "Plattdütsch",
+		sort_name = "Plattdutsch",
+		font = "default"
+	},
+
+	nl = {
+		name = "Nederlands",
+		sort_name = "Nederlands",
+		font = "default"
+	},
+
+	nn = {
+		name = "Nynorsk",
+		sort_name = "Norsk (Nynorsk)",
+		font = "default"
+	},
+
+	oc = {
+		name = "Occitan",
+		sort_name = "Occitan",
+		font = "default"
+	},
+
+	pl = {
+		name = "Polski",
+		sort_name = "Polski",
+		font = "default"
+	},
+
+	pt = {
+		name = "Português",
+		sort_name = "Portugues",
+		font = "default"
+	},
+
+	pt_BR = {
+		name = "Português do Brasil",
+		sort_name = "Portugues (Brasil)",
+		font = "default"
+	},
+
+	ro = {
+		name = "Română",
+		sort_name = "Romana",
+		font = "default"
+	},
+
+	ru = {
+		name = "Русский",
+		sort_name = "Russky",
+		font = "default"
+	},
+
+	rw = {
+		name = "Kinyarwanda",
+		sort_name = "Kinyarwanda",
+		font = "default"
+	},
+
+	si = {
+		name = "සිංහල",
+		sort_name = "Simhala",
+		font = "sinhala"
+	},
+
+	sk = {
+		name = "Slovenčina",
+		sort_name = "Slovencina",
+		font = "default"
+	},
+
+	sl = {
+		name = "Slovenski jezik",
+		sort_name = "Slovenski",
+		font = "default"
+	},
+
+	sr = {
+		name = "српски",
+		sort_name = "Srpski",
+		font = "default"
+	},
+
+	sv = {
+		name = "Svenska",
+		sort_name = "Svenska",
+		font = "default"
+	},
+
+	tr = {
+		name = "Türkçe",
+		sort_name = "Turkce",
+		font = "default"
+	},
+
+	uk = {
+		name = "українська мова",
+		sort_name = "Ukrayinska",
+		font = "default"
+	},
+
+	vi = {
+		name = "Tiếng Việt",
+		sort_name = "Viet",
+		font = "default"
+	},
+
+	zh_CN = {
+		name = "简体中文",
+		sort_name = "Jianti Zhongwen",
+		font = "cjk"
+	},
+
+	zh_TW = {
+		name = "繁體中文",
+		sort_name = "Fanti Zhongwen",
+		font = "cjk"
+	},
 }

=== modified file 'data/scripting/editor/editor_controls.lua'
--- data/scripting/editor/editor_controls.lua	2017-08-16 05:33:50 +0000
+++ data/scripting/editor/editor_controls.lua	2017-12-17 11:19:18 +0000
@@ -1,4 +1,4 @@
-include "scripting/formatting.lua"
+include "scripting/richtext.lua"
 include "txts/help/common_helptexts.lua"
 
 local toggle_minimap_hotkey = help_toggle_minimap_hotkey()
@@ -10,50 +10,40 @@
 return {
    title = _"Controls",
    text =
-      rt(
-         h2(_"Keyboard Shortcuts") ..
-         p(
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey("F1"), _"Help") ..
-            -- TRANSLATORS: This is an access key combination.
-            dl(help_format_hotkey("H"), _"Toggle main menu") ..
-            -- TRANSLATORS: This is an access key combination. The hotkey is 't'
-            dl(help_format_hotkey("T"), _"Toggle tools menu") ..
-            toggle_minimap_hotkey ..
-            toggle_building_spaces_hotkey ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey("Ctrl + 1"), _"Toggle building spaces") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey("Ctrl + 2"), _"Toggle immovables display") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey("Ctrl + 3"), _"Toggle animals display") ..
-            -- TRANSLATORS: This is an access key combination. The hotkey is 'p'
-            dl(help_format_hotkey("Ctrl + 4"), _"Toggle resources display") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey("P"), _"Toggle player menu") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey("Ctrl + Z"), _"Undo") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey("Ctrl + Y"), _"Redo") ..
-            -- TRANSLATORS: This is an access key combination. The hotkey is 'i'
-            dl(help_format_hotkey("I"), _"Activate information tool") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey(pgettext("hotkey", "Ctrl + L")), _"Load map") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey(pgettext("hotkey", "Ctrl + S")), _"Save map") ..
+      h2(_"Keyboard Shortcuts") ..
+      p(
+         -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
+         dl(help_format_hotkey("F1"), _"Help") ..
+         -- TRANSLATORS: This is an access key combination.
+         dl(help_format_hotkey("H"), _"Toggle main menu") ..
+         -- TRANSLATORS: This is an access key combination. The hotkey is 't'
+         dl(help_format_hotkey("T"), _"Toggle tools menu") ..
+         toggle_minimap_hotkey ..
+         toggle_building_spaces_hotkey ..
+         -- TRANSLATORS: This is an access key combination. The hotkey is 'p'
+         dl(help_format_hotkey("P"), _"Toggle player menu") ..
+         -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
+         dl(help_format_hotkey("Ctrl + Z"), _"Undo") ..
+         -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
+         dl(help_format_hotkey("Ctrl + Y"), _"Redo") ..
+         -- TRANSLATORS: This is an access key combination. The hotkey is 'i'
+         dl(help_format_hotkey("I"), _"Activate information tool") ..
+         -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
+         dl(help_format_hotkey(pgettext("hotkey", "Ctrl + L")), _"Load map") ..
+         -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
+         dl(help_format_hotkey(pgettext("hotkey", "Ctrl + S")), _"Save map") ..
             toggle_fullscreen_hotkey
-         ) ..
+      ) ..
 
-         h2(_"Tools") ..
-         p(
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey(pgettext("hotkey", "0-9")), _"Change tool size") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey(pgettext("hotkey", "Click")), _"Place new elements on the map, or increase map elements by the value selected by ‘Increase/Decrease value’") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey(pgettext("hotkey", "Shift + Click")), _"Remove elements from the map, or decrease map elements by the value selected by ‘Increase/Decrease value’") ..
-            -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
-            dl(help_format_hotkey(pgettext("hotkey", "Ctrl + Click")), _"Set map elements to the value selected by ‘Set Value’")
-         )
+      h2(_"Tools") ..
+      p(
+         -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
+         dl(help_format_hotkey(pgettext("hotkey", "0-9")), _"Change tool size") ..
+         -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
+         dl(help_format_hotkey(pgettext("hotkey", "Click")), _"Place new elements on the map, or increase map elements by the value selected by ‘Increase/Decrease value’") ..
+         -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
+         dl(help_format_hotkey(pgettext("hotkey", "Shift + Click")), _"Remove elements from the map, or decrease map elements by the value selected by ‘Increase/Decrease value’") ..
+         -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
+         dl(help_format_hotkey(pgettext("hotkey", "Ctrl + Click")), _"Set map elements to the value selected by ‘Set Value’")
       )
 }

=== modified file 'data/scripting/editor/editor_introduction.lua'
--- data/scripting/editor/editor_introduction.lua	2016-05-01 09:57:58 +0000
+++ data/scripting/editor/editor_introduction.lua	2017-12-17 11:19:18 +0000
@@ -1,4 +1,4 @@
-include "scripting/formatting.lua"
+include "scripting/richtext.lua"
 include "txts/help/common_helptexts.lua"
 
 local online_help = help_online_help()
@@ -8,13 +8,11 @@
 return {
    title = _"The Widelands Editor",
    text =
-      rt(
-         h1(_"Introduction") ..
-
-         p(_"This editor is intended for players who would like to design their own maps to use with Widelands.") ..
-         p(_"As you can see, this editor is heavy work in progress and as the editor becomes better and better, this text will also get longer and more complete.") ..
-
-         online_help ..
-         p(_"The wiki also includes a short tutorial on how to build a map.")
-      )
+      h1(_"Introduction") ..
+
+      p(_"This editor is intended for players who would like to design their own maps to use with Widelands.") ..
+      p(_"As you can see, this editor is heavy work in progress and as the editor becomes better and better, this text will also get longer and more complete.") ..
+
+      online_help ..
+      p(_"The wiki also includes a short tutorial on how to build a map.")
 }

=== removed file 'data/scripting/editor/format_editor.lua'
--- data/scripting/editor/format_editor.lua	2016-09-01 15:43:01 +0000
+++ data/scripting/editor/format_editor.lua	1970-01-01 00:00:00 +0000
@@ -1,31 +0,0 @@
--- RST
--- format_editor.lua
--- -----------------
---
--- Functions used in the ingame editor help windows for formatting the text and pictures.
-
-include "scripting/formatting.lua"
-
--- RST
--- .. function:: picture_li(imagepath, text)
---
---    Places a paragraph of text to the right of an image
-
---    :arg imagepath: the full path to the image file
---    :arg text: the text to be placed next to the image
---
---    :returns: the text wrapped in a paragraph and placed next to the image
-function picture_li(imagepath, text)
-   return "<rt image=" .. imagepath .. " image-align=left>"
-      .. p(text) .. "</rt>"
-end
-
--- RST
--- .. function:: spacer()
---
---    Adds a little space between two paragraphs
---
---    :returns: a small empty paragraph
-function spacer()
-   return rt(p("font-size=3", ""))
-end

=== modified file 'data/scripting/editor/terrain_help.lua'
--- data/scripting/editor/terrain_help.lua	2016-09-01 15:23:25 +0000
+++ data/scripting/editor/terrain_help.lua	2017-12-17 11:19:18 +0000
@@ -5,7 +5,7 @@
 -- This script returns a formatted entry for the terrain help in the editor.
 -- Pass the internal terrain name to the coroutine to select the terrain type.
 
-include "scripting/editor/format_editor.lua"
+include "scripting/richtext.lua"
 
 return {
    func = function(terrain_name)
@@ -13,25 +13,25 @@
       local world = wl.World();
       local terrain = wl.Editor():get_terrain_description(terrain_name)
 
-      local result = picture_li(terrain.representative_image, "")
+      local result = li_image(terrain.representative_image, "")
 
       -- Resources
       local valid_resources = terrain.valid_resources
       if (#valid_resources > 0) then
-         result = result .. spacer() .. rt(h2(_"Resources"))
+         result = result .. h2(_"Resources")
          if (#valid_resources > 0) then
             -- TRANSLATORS: A header in the editor help
-            result = result .. rt(h3(ngettext(
-               "Valid Resource:", "Valid Resources:", #valid_resources)))
+            result = result .. h3(ngettext(
+               "Valid Resource:", "Valid Resources:", #valid_resources))
             for count, resource in pairs(valid_resources) do
-               result = result .. picture_li(
+               result = result .. li_image(
                   resource.representative_image, resource.descname)
             end
          end
 
          local default_resource = terrain.default_resource
          if (default_resource ~= nil) then
-            result = result .. text_line(_"Default:",
+            result = result .. inline_header(_"Default:",
                -- TRANSLATORS: e.g. "5x Water"
                _"%1%x %2%":bformat(terrain.default_resource_amount, default_resource.descname))
          end
@@ -59,21 +59,22 @@
 
       local tree_string = ""
       for k,v in ipairs(tree_list) do
-         tree_string = tree_string .. picture_li(v.tree.representative_image,
-            v.tree.species .. ("<br>%2.1f%%"):bformat(100 * v.probability)) .. spacer()
+         tree_string = tree_string .. li_image(v.tree.representative_image,
+            v.tree.species .. ("<br>%2.1f%%"):bformat(100 * v.probability)) .. vspace(3)
       end
 
       -- TRANSLATORS: A header in the editor help
-      result = result .. spacer() .. rt(h2(_"Probability of trees growing")) .. spacer()
+      result = result .. vspace(3) .. h2(vspace(12) .. _"Probability of trees growing") .. vspace(3)
 
       if (tree_string ~="") then
          result = result .. tree_string
       else
-         result = result .. rt(p(_"No trees will grow here."))
+         result = result .. p(_"No trees will grow here.")
       end
+
       return {
          title = terrain.descname,
-         text = result
+         text = div("width=100%", result)
       }
    end
 }

=== modified file 'data/scripting/editor/tips.lua'
--- data/scripting/editor/tips.lua	2016-10-19 09:00:29 +0000
+++ data/scripting/editor/tips.lua	2017-12-17 11:19:18 +0000
@@ -1,18 +1,17 @@
-include "scripting/formatting.lua"
+include "scripting/richtext.lua"
 
 function get_editor_tips()
    include "txts/tips/editor.lua"
    return tips
 end
 
-local text = paragraphdivider()
+local text = ""
 for index, contents in pairs(get_editor_tips()) do
-   text = text .. listitem_bullet(contents["text"])
+   text = text .. li(contents["text"])
 end
-text = text .. "</p>"
 
 set_textdomain("widelands_editor")
 return {
   title = _"Tips",
-  text = rt(text)
+  text = text
 }

=== modified file 'data/scripting/editor/tree_help.lua'
--- data/scripting/editor/tree_help.lua	2016-09-01 15:23:25 +0000
+++ data/scripting/editor/tree_help.lua	2017-12-17 11:19:18 +0000
@@ -5,17 +5,17 @@
 -- This script returns a formatted entry for the tree help in the editor.
 -- Pass the internal tree name to the coroutine to select the tree type.
 
-include "scripting/editor/format_editor.lua"
+include "scripting/richtext.lua"
 
 return {
    func = function(tree_name)
       set_textdomain("widelands_editor")
       local world = wl.World();
       local tree = wl.Editor():get_immovable_description(tree_name)
-      local result = picture_li(tree.representative_image, "")
+      local result = li_image(tree.representative_image, "")
 
       -- TRANSLATORS: A header in the editor help. Terrains preferred by a type of tree.
-      result = result .. rt(p("font-size=3", "")) .. rt(h2(_"Preferred terrains")) .. spacer()
+      result = result .. h2(_"Preferred terrains")
       terrain_list = {}
       for i, terrain in ipairs(world.terrain_descriptions) do
          local probability = tree:probability_to_grow(terrain)
@@ -34,11 +34,11 @@
       end
 
       for k,v in ipairs(terrain_list) do
-         result = result .. picture_li(v.terrain.representative_image,
+         result = result .. li_image(v.terrain.representative_image,
                -- TRANSLATORS: Terrain name (Climate)
                (_"%1% (%2%)"):bformat(v.terrain.descname, v.terrain.editor_category.descname) ..
                "<br>" .. ("%2.1f%%"):bformat(100 * v.probability)
-            ) .. spacer()
+            ) .. vspace(3)
       end
       return {
          title = tree.species,

=== added file 'data/scripting/format_scenario.lua'
--- data/scripting/format_scenario.lua	1970-01-01 00:00:00 +0000
+++ data/scripting/format_scenario.lua	2017-12-17 11:19:18 +0000
@@ -0,0 +1,85 @@
+-- RST
+-- format_scenario.lua
+-- -------------------
+--
+-- Function to simplify and unique text formatting in scenarios.  Most of these
+-- functions are simple wrapper functions that make working with widelands rich
+-- text formatting system more bearable.
+
+
+-- RST
+-- .. function:: speech(img, clr, title, text)
+--
+--    Formats a text as spoken by one person in a scenario. Use it as follows:
+--
+--    .. code-block:: lua
+--
+--        function jundlina(title, text)
+--           return speech("map:princess.png", "2F9131", title, text)
+--        end
+--
+--    :arg img: name of the image to use for this speaker
+--    :arg clr: a valid 6 char hex color to use for the name of this speaker
+--    :arg title: Title of this text.
+--    :arg text: The text itself. If this is nil, :const:`title` is used as text
+--       instead and there will not be any title.
+--    :returns: the formatted text.
+--
+function speech(img, clr, g_title, g_text)
+   local title, text = g_title, g_text
+   if not text then
+      title = nil
+      text = g_title
+   end
+
+   -- Surround the text with translatable ","
+   text = (_'“%s”'):format(text)
+
+   local s = ""
+   if title then
+      s = rt("<p font-size=20 font-weight=bold font-face=serif " ..
+         ("font-color=%s>"):format(clr) .. title ..
+         "</p><p font-size=8> <br></p>"
+      )
+   end
+
+   return s .. rt(("image=%s"):format(img), p(text))
+end
+
+
+-- RST
+-- .. function:: objective_text(heading, body)
+--
+--    Provides nice formatting for objective texts.
+--
+--    :returns: a rich text object that contains the formatted
+--       objective text.
+--
+function objective_text(heading, body)
+   return rt(h2(heading) .. p(body))
+end
+
+
+-- RST
+-- Append an objective text with a header to a dialog box in a nice fashion.
+-- For displaying objectives with an extra title when an advisor is talking
+--
+--    Provides nice formatting for objective texts.
+--    the following arguments will be parsed:
+--    number: the number of objectives described in the body
+--    body: the objective text, e.g. created with function objective_text(heading, body)
+--
+--    :returns: a rich text object that contains the formatted
+--       objective text & title.
+--
+function new_objectives(...)
+   local sum = 0
+   local s = ""
+   for idx,obj in ipairs{...} do
+      s = s .. obj.body
+      sum = sum + obj.number
+   end
+   return rt("<p font-size=10> <br></p>" ..
+      "<p font=serif font-size=18 font-weight=bold font-color=D1D1D1>"
+      .. ngettext("New Objective", "New Objectives", sum) .. "</p>") .. s
+end

=== modified file 'data/scripting/messages.lua'
--- data/scripting/messages.lua	2017-05-12 09:43:57 +0000
+++ data/scripting/messages.lua	2017-12-17 11:19:18 +0000
@@ -5,6 +5,7 @@
 -- Functions to send messages to the player and to add objectives to campaigns.
 
 include "scripting/coroutine.lua"
+include "scripting/richtext.lua"
 include "scripting/table.lua"
 include "scripting/ui.lua"
 
@@ -51,7 +52,7 @@
    -- While the message box is shown, the user cannot do anything else anyway.
    local user_input = wl.ui.get_user_input_allowed()
    wl.ui.set_user_input_allowed(true)
-   player:message_box(title, body, parameters)
+   player:message_box(title, rt(body), parameters)
    wl.ui.set_user_input_allowed(user_input)
 end
 
@@ -83,9 +84,9 @@
 --
 function add_campaign_objective(objective)
    if objective.obj_name then
-      return wl.Game().players[1]:add_objective(objective.obj_name, objective.obj_title, objective.obj_body)
+      return wl.Game().players[1]:add_objective(objective.obj_name, objective.obj_title, rt(objective.obj_body))
    else
-      return wl.Game().players[1]:add_objective(objective.name, objective.title, objective.body)
+      return wl.Game().players[1]:add_objective(objective.name, objective.title, rt(objective.body))
    end
 end
 
@@ -160,7 +161,7 @@
       -- message_box takes care of this, but player:message_box does not
       local user_input = wl.ui.get_user_input_allowed()
       wl.ui.set_user_input_allowed(true)
-      player:message_box(message.title, message.body, message)
+      player:message_box(message.title, rt(message.body), message)
       wl.ui.set_user_input_allowed(user_input)
    else
       message_box(plr, message.title, message.body, message)

=== modified file 'data/scripting/richtext.lua'
--- data/scripting/richtext.lua	2017-07-03 10:16:59 +0000
+++ data/scripting/richtext.lua	2017-12-17 11:19:18 +0000
@@ -124,9 +124,9 @@
 --    :returns: A paragraph with text formatted as heading.
 function h1(text_or_color, text)
    if text then
-      return p_font("", "size=18 bold=1 color=".. text_or_color, vspace(6) .. text .. vspace(1))
+      return p_font("", "size=18 bold=1 color=".. text_or_color, vspace(12) .. text .. vspace(1))
    else
-      return p_font("", "size=18 bold=1 color=D1D1D1", vspace(6) .. text_or_color .. vspace(1))
+      return p_font("", "size=18 bold=1 color=D1D1D1", vspace(12) .. text_or_color .. vspace(1))
    end
 end
 
@@ -138,7 +138,7 @@
 --
 --    :returns: A paragraph with text formatted as heading.
 function h2(text)
-   return p_font("", "size=14 bold=1 color=D1D1D1", vspace(6) .. text .. vspace(1))
+   return p_font("", "size=14 bold=1 color=D1D1D1", vspace(12) .. text .. vspace(1))
 end
 
 -- RST
@@ -150,7 +150,7 @@
 --    :returns: A paragraph with text formatted as heading.
 --
 function h3(text)
-   return p_font("", "size=13 color=D1D1D1", vspace(4) .. text .. vspace(1))
+   return p_font("", "size=13 color=D1D1D1", vspace(6) .. text .. vspace(1))
 end
 
 -- RST
@@ -233,7 +233,7 @@
 --
 --    :returns: The closing tags for a paragraph
 function close_p(t)
-   return vspace(6) .. "</font></p>"
+   return vspace(6) .. "</font>" .. vspace(6)  .. "</p>"
 end
 
 -- RST
@@ -307,9 +307,9 @@
 --    :returns: a p tag containint the formatted text
 function li(text_or_symbol, text)
    if text then
-      return p(text_or_symbol .. " " .. text .. vspace(6))
+      return div(p(text_or_symbol)) .. div(p(space(6))) .. div("width=*", p(text))
    else
-      return p("• " .. text_or_symbol .. vspace(6))
+      return div(p("•")) .. div(p(space(6))) .. div("width=*", p(text_or_symbol))
    end
 end
 
@@ -336,12 +336,13 @@
 --    :arg text: the text to be placed next to the image
 --
 --    :returns: the text wrapped in a paragraph and placed next to the image, The outer tag is a div.
-function li_image(imagepath, text_width_percent, text)
-   return p("<br>") .. div("width=100%", "") ..
-         div(p(img(imagepath))) ..
+function li_image(imagepath, text)
+   return
+      div("width=100%",
+         div(p(vspace(6) .. img(imagepath) .. space(6))) ..
          div(p(space(6))) ..
-         div("width="..text_width_percent.."%", p(text)) ..
-         div("width=100%", "")
+         div("width=*", p(vspace(6) .. text .. vspace(12)))
+      )
 end
 
 -- RST
@@ -423,3 +424,18 @@
       return ("<div>") .. text_or_attributes .. "</div>"
    end
 end
+
+-- RST
+-- .. function:: inline_header(t1, t2)
+--
+--    Creates a line of h3 formatted text followed by normal paragraph text.
+--
+--    :arg t1: text in h3 format.
+--    :arg t2: text in p format.
+--    :returns: header text followed by normal text.
+--
+function inline_header(header, text)
+   return
+      div("width=100%",  font("size=13 color=D1D1D1", header .. " ") ..
+      font("size=12", text))
+end

=== renamed file 'data/scripting/format_scenario.lua' => 'data/scripting/richtext_scenarios.lua'
--- data/scripting/format_scenario.lua	2016-10-19 09:00:29 +0000
+++ data/scripting/richtext_scenarios.lua	2017-12-17 11:19:18 +0000
@@ -1,6 +1,8 @@
+include "scripting/richtext.lua"
+
 -- RST
--- format_scenario.lua
--- -------------------
+-- richtext_scenarios.lua
+-- ----------------------
 --
 -- Function to simplify and unique text formatting in scenarios.  Most of these
 -- functions are simple wrapper functions that make working with widelands rich
@@ -20,31 +22,32 @@
 --
 --    :arg img: name of the image to use for this speaker
 --    :arg clr: a valid 6 char hex color to use for the name of this speaker
---    :arg title: Title of this text.
---    :arg text: The text itself. If this is nil, :const:`title` is used as text
---       instead and there will not be any title.
+--    :arg title: Title of this text. Use empty string if you don't want any.
+--    :arg text: The text itself.
 --    :returns: the formatted text.
 --
-function speech(img, clr, g_title, g_text)
-   local title, text = g_title, g_text
-   if not text then
-      title = nil
-      text = g_title
+function speech(img, clr, title, text)
+   if title ~= "" then
+      title = h1(clr, title)
    end
 
    -- Surround the text with translatable ","
    text = (_'“%s”'):format(text)
 
-   local s = ""
-   if title then
-      s = rt("<p font-size=20 font-weight=bold font-face=serif " ..
-         ("font-color=%s>"):format(clr) .. title ..
-         "</p><p font-size=8> <br></p>"
-      )
-   end
-
-   return s .. rt(("image=%s"):format(img), p(text))
-end
+   return title .. li_image(img, p(text))
+end
+
+-- RST
+-- .. function:: paragraphdivider()
+--
+--    Closes a paragraph and opens a new paragraph. Use this when you format a string with the speech function
+--    and need to divide the speech into multiple paragraphs.
+--
+--    :returns: close_p() .. open_p()
+function paragraphdivider()
+   return close_p() .. open_p()
+end
+
 
 
 -- RST
@@ -56,7 +59,7 @@
 --       objective text.
 --
 function objective_text(heading, body)
-   return rt(h2(heading) .. p(body))
+   return h2(heading) .. p(body)
 end
 
 
@@ -74,12 +77,10 @@
 --
 function new_objectives(...)
    local sum = 0
-   local s = ""
+   local text = ""
    for idx,obj in ipairs{...} do
-      s = s .. obj.body
+      text = text .. obj.body
       sum = sum + obj.number
    end
-   return rt("<p font-size=10> <br></p>" ..
-      "<p font=serif font-size=18 font-weight=bold font-color=D1D1D1>"
-      .. ngettext("New Objective", "New Objectives", sum) .. "</p>") .. s
+   return h1(ngettext("New Objective", "New Objectives", sum)) .. text
 end

=== modified file 'data/tribes/scripting/help/controls.lua'
--- data/tribes/scripting/help/controls.lua	2017-02-24 10:29:59 +0000
+++ data/tribes/scripting/help/controls.lua	2017-12-17 11:19:18 +0000
@@ -1,6 +1,6 @@
 set_textdomain("tribes_encyclopedia")
 
-include "scripting/formatting.lua"
+include "scripting/richtext.lua"
 include "txts/help/common_helptexts.lua"
 
 local toggle_minimap_hotkey = help_toggle_minimap_hotkey()
@@ -12,7 +12,6 @@
 return {
    title = _"Controls",
    text =
-      rt(
          h2(_"Window Control") ..
          p(
                -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
@@ -103,5 +102,4 @@
                -- TRANSLATORS: This is an access key combination. Localize, but do not change the key.
                dl(help_format_hotkey(pgettext("hotkey", "Delete")), _"Archive/Restore the current message")
           )
-      )
 }

=== modified file 'data/tribes/scripting/help/introduction.lua'
--- data/tribes/scripting/help/introduction.lua	2016-04-02 08:21:25 +0000
+++ data/tribes/scripting/help/introduction.lua	2017-12-17 11:19:18 +0000
@@ -1,13 +1,11 @@
 set_textdomain("tribes_encyclopedia")
 
-include "scripting/formatting.lua"
+include "scripting/richtext.lua"
 include "txts/help/common_helptexts.lua"
 
 return {
    title = _"About Widelands",
    text =
-      rt(
          help_introduction() ..
          help_online_help()
-      )
 }

=== modified file 'data/tribes/scripting/help/tips.lua'
--- data/tribes/scripting/help/tips.lua	2017-01-23 08:38:07 +0000
+++ data/tribes/scripting/help/tips.lua	2017-12-17 11:19:18 +0000
@@ -1,4 +1,4 @@
-include "scripting/formatting.lua"
+include "scripting/richtext.lua"
 
 function get_general_tips()
    include "txts/tips/general_game.lua"
@@ -31,11 +31,10 @@
 end
 
 function format_tips(tips)
-   local text = paragraphdivider()
+   local text = ""
    for index, contents in pairs(tips) do
-      text = text .. listitem_bullet(contents["text"])
+      text = text .. li(contents["text"])
    end
-   text = text .. "</p>"
    return text
 end
 
@@ -69,7 +68,7 @@
       set_textdomain("tribes_encyclopedia")
       return {
         title = _"Tips",
-        text = rt(text)
+        text = text
       }
    end
 }

=== modified file 'data/txts/help/common_helptexts.lua'
--- data/txts/help/common_helptexts.lua	2016-03-27 07:32:33 +0000
+++ data/txts/help/common_helptexts.lua	2017-12-17 11:19:18 +0000
@@ -2,7 +2,7 @@
 -- e.g. for the readme and general in-game help
 -- This cuts down on string maintenance.
 
-include "scripting/formatting.lua"
+include "scripting/richtext.lua"
 
 function help_online_help()
    set_textdomain("texts")

=== modified file 'data/txts/translators_data.lua'
--- data/txts/translators_data.lua	2017-12-17 03:57:22 +0000
+++ data/txts/translators_data.lua	2017-12-17 11:19:18 +0000
@@ -1,1 +1,1 @@
-function translators() return {{heading = "العربية (Arabic)",entries = {{members = {"abdXelrhman","m-abudrais"," Omar Anwar","someone",},},},},{heading = "Asturianu (Asturian)",entries = {{members = {"Xuacu Saturio",},},},},{heading = "Български (Bulgarian)",entries = {{members = {"А. Ташев","Любомир Василев",},},},},{heading = "Brezhoneg (Breton)",entries = {{members = {"Pierre Morvan (Iriep)",},},},},{heading = "Català (Catalan)",entries = {{members = {"Francesc Famadas (kiski97)","Guybrush88","Joan Josep","Juanjo (juanjo_n)","Marc Dabad Castellà (marc.dabad)","Oriol",},},},},{heading = "Čeština (Czech)",entries = {{members = {"Adam Matoušek","David Spanel","Jakub Šebek (Jack_Honeypuffs)","Jens Beyer","Jezevec","Jiří Locker","Konki","Marek (d3rklord)","Marek Donar (Markus7cz)","Martin Volf","Martin Vecera (Marvec)","MaSo_CZ","Matej Svrcek (prom)","Milan Fašina (Matrix17)","Vit Hrachovy","Zbyněk Schwarz",},},},},{heading = "Dansk (Danish)",entries = {{members = {"Ask Hjorth Larsen","beer","Daniel Ejsing-Duun","David Lamhauge","Erik Soe Sorensen","Esben Aaberg","hulagutten","Joe Hansen (joedalton)","larsch","Nikolaj Sejergaard","Ole Laursen (olau)","silentStatic","Simon Stubben","Ville Witt",},},},},{heading = "Deutsch (German)",entries = {{members = {"Andreas Breitschopp","Astuur","Bamstam","Benedikt Tröster","Bob Johns","Borim","Clemens Dinkel","Daniel Kutrowatz","Daniel Winzen","Das MC","David Allwicher","DelphiMarkus","Dirk Stöcker","Elisabeth Jäger","Felix Gruber","Fenris Wolf","Ferdinand T.","FetteNase","Flames_in_Paradise","fraang","Frank Kubitschek","Gabriel Margiani","gamag","Hagen","Hanna Podewski (kristin)","herbert","HybridDog","hurz","Johannes (nuefke)","Johannes Haupt","Jonas Jonas","Jürgen Eberlein (Cherub)","Kaste","Klappstuhl","Klaus Halfmann (Hasi50)","Koneu","kraileth","LAZA","LennStar","Macedon","Marc Rodrigues (ExUndHop)","Marc Wischnowsky","Markus Pfitzner (janus)","Martin","Martin Schaerer","Matthias Krüger","Max","Max_Bento","meru","millimarg","Mirian Margiani","MirkoWodtke","Mister Pi","Mr. Anderson","Ole","Peter Schwanemann (Nasenbaer)","Philipp Niemann (Azagtoth)","Provetin","Ralf-J. Block","Raymond Vetter","ronny","SevyRide","Shevonar","SirVer","Sonnrain","Thomas","Tim O.","Timowi","Tino Miegel (TinoM)","Tobias Margiani","Venatrix","wl-zocker","Wolfgang Kurz","Wolfs","Wuzzy","Xaver (xtother90)",},},},},{heading = "Ελληνικά (Greek)",entries = {{members = {"Elias Delakovias","Lifeboy","Marinus Savoritias","ptr","Γιάννης Ανθυμίδης",},},},},{heading = "Canadian English",entries = {{members = {"Ne-1",},},},},{heading = "British English",entries = {{members = {"_aD","Alex Denvir","Andi Chandler (AndiBing)","Anthony Harrington","Biffaboy","Heber","Jackson Doak","James Thorrold","Jon Senior","LiSrt","Luis Miguel D.P.","M Crosby (classicsnoot)","mrx5682","Terry Jones","Tinker","UndiFineD","Vladimir Oka",},},},},{heading = "US American English",entries = {{members = {"DragonAtma",},},},},{heading = "Esperanto",entries = {{members = {"alms21","Fenris Wolf","Ivan Camilo Quintero Santacruz","Jens Beyer","Kristjan SCHMIDT","LaPingvino","Manuel Berkemeier","Michael Moroni (Airon90)",},},},},{heading = "Español (Spanish)",entries = {{members = {"Adolfo Jayme","Adrián Magro (senhorroar)","Agustín Vela","Alberto D.V.","Alejandro Pérez","Antonio Trueba (Fasser)","David Mitos","David Pérez","Diego Alberto Pereyra (Dishitooo)","DiegoJ","Eduardo Alberto Calvo","G BR (gastbr)","Gerardb","ironfisher","Ivan","Ivan Radzik (Sugsaggu)","Ivan Camilo Quintero Santacruz","Javi Sol","Javier Mora (morehash)","Jonay","Joseph Molina","JoseRoberto","Juan Eduardo Riva","Kiba Gasteiz (Kiibakun)","Lucía Pradillos","Luis Miguel D.P.","Madkat Here (madkat)","Martín V.","Miguel adre","Miguel de Dios Matias (tres.14159)","Monkey","Pablo Frigerio","Paco Molinero","Paulomorales","pescamillam","Rafael Augusto Maguiña Yrivarren","Rafael Medina","Raul Ferriz","Roberto López","schimmm","simon","Siz","Thadah D. Denyse","WalterCool","zer berros",},},},},{heading = "Eesti keel (Estonian)",entries = {{members = {"gert7","rm87",},},},},{heading = "Euskara (Basque)",entries = {{members = {"Mikel Alzibar",},},},},{heading = "فارسی (Persian)",entries = {{members = {"katy Zahedi","Hossien H (hossien2020)",},},},},{heading = "Suomi (Finnish)",entries = {{members = {"C C (ciucoi)","Jari Hautio","Joonas Tamminen (owava44)","Juhani Numminen","Jukka Pakarinen (flegmaatikko)","Markus Hällfors (Mad_Mac)","Max Ihalempia (xdvii7)","Pekka Järvinen (raspi)","Ropertto4","Sampo Harjula (Sahtor)","Sini Ruohomaa (Byakushin)","Teppo Mäenpää (teppq)","Tommi Nirha","Vazde",},},},},{heading = "Français",entries = {{members = {"Remerçiements aux traducteurs:","","Adrien Vigneron (VRad)","AGuechoum","AnubiS","Audiger Jeremy","Aurelien Pavel","Benjamin Subtil","Bertram","Bruno Veilleux","clark17","crep4ever","David .","Denis Chenu (Shnoulle)","Didier M (didli)","El Pensador","Eliovir","Emmanuel Andry (Eandry)","fk","François Rousselet","Gilles Aubert (Hellsprings)","Guillaume Brant","Guybrush88","Gwendal D","hu bu (finkiki)","Immunoman","Jaypad","Jean-Pierre Gemble","Hanna Podewski (kristin)","londumas","Michael Colignon","Michael DOUBEZ","Mohamed SEDKI","Nicolas Auvray (Itms)","NonoSan","Pierre Rudloff","Renaud Bouchard (neurofr)","Sébastien Duthil","Sevy Ride","Tarou","Thomas Jungers","tomtom","Tubuntu","Ubuntu1988","verdy_p","wl-zocker","YS1","Yves MATHIEU","zezinho",},},},},{heading = "Frysk (Western Frisian)",entries = {{members = {"Luitzen Hietkamp",},},},},{heading = "Gàidhlig (Scottish Gaelic)",entries = {{members = {"GunChleoc",},},},},{heading = "Galego (Galician)",entries = {{members = {"Adrián Chaves Fernández","Adrián Magro (senhorroar)","Antonio Trueba (Fasser)","Xosé",},},},},{heading = "עברית (Hebrew)",entries = {{members = {"Danny Albocher","Liel Fridman","Maor Reuben (maor309)","Michael DOUBEZ","Solomon Gruber (Piql7)","Yaron",},},},},{heading = "हिन्दी (Hindi)",entries = {{members = {"girdhari rao",},},},},{heading = "Hrvatski (Croatian)",entries = {{members = {"Ivan Bižaca (biza)","Mario Dautović",},},},},{heading = "Magyar (Hungarian)",entries = {{members = {"Agnes Dabi","Balázs Meskó (meskobalazs)","Bangó Máté","cn4ij","Dániel Varga (vargad88)","Ferenc Nagy","Gyönki Bendegúz","Herczeg Attila (hNczy)","HUNStree","István Kiss","jzombi","Kiscsirke","litoll","Major Gabesz","Muszela Balázs","Papp Bence","Peter Garami (garpe)","Richard Somlói","Robert Roth","SanskritFritz","Szűcs Kornél Géza (thewanderer)","zone",},},},},{heading = "Interlingua",entries = {{members = {"alms21",},},},},{heading = "Bahasa Indonesia (Indonesian)",entries = {{members = {"dadanhrn",},},},},{heading = "Igbo",entries = {{members = {"AhaNkem Obi",},},},},{heading = "Italiano (Italian)",entries = {{members = {"Angelo Locritani","Bananasoft (Betacentury)","Cristiano Magro (xno)","Colin Gibson","DarkSaivor","Davide Nicolini (Davidus)","Dom De Felice","Doukas7","Eulogy","Gabriel Rota","Guybrush88","ido","Luigi Lain (king_of_nowhere)","Loris Turchetti","MarcoTrevisiol","Matteo Viarengo (enthusedquill6)","Oibaf","Pierpaolo Pierozzi","pierusch","Pietro Battiston","Roberto Sciascia","Riccardo Di Maio (yogotosleepnow)","SecondCloud500","Sergio Spinatelli","sgargel","simone.sandri","Tommaso Amici",},},},},{heading = "日本語 (Japanese)",entries = {{members = {"alms21","Dios","Gonta Ultra (Ulgon)","guess880","Midori","SevyRide","Scorpio","tubame",},},},},{heading = "Basa jawa (Javanese)",entries = {{members = {"zaenal arifin",},},},},{heading = "ქართული (Georgian)",entries = {{members = {"Gabriel Margiani","gamag","Meyer Konrad",},},},},{heading = "한국어 (Korean)",entries = {{members = {"ddfddf2k",},},},},{heading = "Karjala (Karelian)",entries = {{members = {"C C (ciucoi)",},},},},{heading = "Lingua latīna (Latin)",entries = {{members = {"alms21","Leonard Noack (Aleno)","lopho","Sonnrain","Stephan Lenk","Thorsten",},},},},{heading = "Lietuvių (Lithuanian)",entries = {{members = {"Mantas Kriaučiūnas",},},},},{heading = "मराठी (Marathi)",entries = {{members = {"Amod Ajit Karmarkar",},},},},{heading = "بهاس ملايو (Malay)",entries = {{members = {"abuyop",},},},},{heading = "မြန်မာစ (Burmese)",entries = {{members = {"pyaehtetaung",},},},},{heading = "Norsk (Bokmål) (Norwegian Bokmål)",entries = {{members = {"Alexander Jansen (Bornxlo)","Bjørnar Moen Marthinsen (Bramlorn)","Fredrik Sudmann","Hans Joachim Desserud","Harald H. (haarek)","Magnus Meyer Hustveit","Martin Dahl Moe","mr.x","Thorbjørn Bruarøy (2rB)",},},},},{heading = "Plattdütsch (Low German)",entries = {{members = {"Mister Pi ","Nasenbaer ","Ole ","tando",},},},},{heading = "Nederlands (Dutch)",entries = {{members = {"ben2s","BenW","Christian Groenendijk","Dirk Schut","fireprog","fk","Foppe Benedictus","Johan Jonkman (Dikjuh)","Maasieboy","Marcel","megabyte","Patrick van der Leer","Pieter Ouwerkerk (Pietertje)","Pietertje","PliniusNeo","REAL NAME","Rick van der Zwet","Rob Snelders (Ertai)","Steven De Herdt (stdh)","Teun Spaans","Victor Pelt","Wim Champagne",},},},},{heading = "Nynorsk (Norwegian Nynorsk)",entries = {{members = {"Alexander Mackinnon Jansen","Hans Joachim Desserud","Odin Hørthe Omdal","Thorbjørn Bruarøy (2rB)",},},},},{heading = "Occitan",entries = {{members = {"Cédric VALMARY (Tot en òc)",},},},},{heading = "Polski (Polish)",entries = {{members = {"Andrzej Krentosz (Endrju)","Asahi Koishi","BartekChom","Bartosz Wiśniewski","Gabriel Fortin","Hubert Pluta","Jakub Rak (einstein13)","Januzi (januzi)","Jacek Wolszczak (Shutdownrunner)","Jens Beyer","Karol Sobolewski","Łukasz Chełmicki","Mateusz Micał","Michal Maslanko","Michał Rzepiński","MikeNow","miragae","orzeh","Patryk Sawicki","Pawel PErz","Sebastian Janus (kreys)","Stanisław Gackowski (Soeb)","Szymon Fornal","Szymon Gackowski","Szymon Nieznański","tim","Tomasz Pudło (tombox)","Tomasz Sterna","Wesmania","Wojtek","XeonBloomfield",},},},},{heading = "Português (Portuguese)",entries = {{members = {"Almufadado","daniel reis","David Rodrigues","Flávio J. Saraiva","Gnu Rreia","GunChleoc","Luis Neves (ljay79)","Marcelo do Pagode","Miguel de Freitas Fonseca","Patrick de Castro (Rayback)","Tiago Silva","trewe","zecas (zezinho)",},},},},{heading = "Português do Brasil (Brazilian Portuguese)",entries = {{members = {"Alexandre","alms21","Almufadado","Cleverton","daniel reis","Fabio Garz","Flaviano Angeli","Henrique Terto de Souza","HicHic","Hriostat","Israel","JoãoPedro BrasãoToledo","Juarez S.","Júlio Cezar Santos Pires","Juno","Luiz N","Maraschin","Marcelo do Pagode","Monstro Socialista","Murilo Poso (MetrO)","Nicolas Abril","Patrick de Castro (Rayback)","Pedro Pisandelli","Proezas","Rafael Dotti","Rafael Neri","Renata Campos","Rubens Bueno","Salatiel Ewerton","Samer Ghosnlas.2932","Tomas Abril","Vitor",},},},},{heading = "Română (Romanian)",entries = {{members = {"Tarta Vasile-Florin (phlo)","Ursachi Alexandru",},},},},{heading = "Русский (Russian)",entries = {{members = {"Александр (Kvark)","Александр Бикмеев (Romiresz)","Александр Глухов","Алексей Кабанов","Андрей Кулаков ","Андрей Олыкайнен ","Антон Хабаров (a.khabarov)","Виктор Биркманис","Владимир Коваленко","Владимир Куряев (Istercul)","Глеб Синковский","Глория Хрусталёва","Денис Дерябин","Егор Панфилов","Константин Щукин","Никита Шехов","Руслан Ковтун","Сергей Фуканчик ","Федор (Lunar_energy)","Юрий Соколов (Urra)","Arex","dr&mx","Georgiy","gerich","Gregory Lominoga (gromodar)","Iaroslav Boiarshinov (foxmulder32)","Ivan (CupIvan)","Izon","KroArtem","Lex","Massol","Papazu","SashaQR","Simple88","telema","TroubleMakerDV","Vampire Hunter D","Vlad",},},},},{heading = "Kinyarwanda",entries = {{members = {"Nasenbaer",},},},},{heading = "සිංහල (Sinhala)",entries = {{members = {"Samith Sandanayake",},},},},{heading = "Slovenčina (Slovak)",entries = {{members = {"Kefir111","Marek Hám","Miroslav Remák","Vladimir","Vladímir Tóth (Ike)",},},},},{heading = "Slovenski jezik (Slovenian)",entries = {{members = {"Andrej Znidarsic","Boštjan Miklavčič","Jure Repinc","kleb","Klemen Košir","Matevž Jekovec","Matic Gradišer","mrt",},},},},{heading = "српски (Serbian)",entries = {{members = {"Никола Павловић","Zlatko Savić (zlajonja)",},},},},{heading = "Svenska (Swedish)",entries = {{members = {"avdpos","Arve Eriksson","Christian Widell","Daniel Nylander (yeager)","Frederik Pettersson (luno)","Hilding Kåstad (HildingWK)","ivh","Joakim Lundborg","karlrune","Marcus E","Michael Rydén","Patrick H.","Phoenix","Rasmus Olstedt","RasmusBackman","Sigra","Treecko","Tumaini","Ulite",},},},},{heading = "Türkçe (Turkish)",entries = {{members = {"Aathonaeax","Asiye","Ekrem Kocadere","Ercin Senturk","Erdy","Recep Hasanbaş (swarf)","ScriptMonster","Volkan Gezer","yakup","Yusuf boy",},},},},{heading = "українська мова (Ukranian)",entries = {{members = {"Вячеслав Фияло (Slaventius)","Сергій Дубик","Fedik","Shemet Yevhene","Vladislav Trotsky (flyboooy17)",},},},},{heading = "Tiếng Việt (Vietnamese)",entries = {{members = {"Nguyen Quang Chien",},},},},{heading = "简体中文 (Simplified Chinese)",entries = {{members = {"Frank Tang (roadt)","luojie-dune","Susie Shi","XIA",},},},},{heading = "繁體中文 (Traditional Chinese)",entries = {{members = {"AJ","Arm Coon","poormusic","sonny",},},},},} end
+function translators() return {{heading = "العربية (Arabic)",entries = {{members = {"abdXelrhman","m-abudrais"," Omar Anwar","someone",},},},},{heading = "Asturianu (Asturian)",entries = {{members = {"Xuacu Saturio",},},},},{heading = "Български (Bulgarian)",entries = {{members = {"А. Ташев","Любомир Василев",},},},},{heading = "Brezhoneg (Breton)",entries = {{members = {"Pierre Morvan (Iriep)",},},},},{heading = "Català (Catalan)",entries = {{members = {"Francesc Famadas (kiski97)","Guybrush88","Joan Josep","Juanjo (juanjo_n)","Marc Dabad Castellà (marc.dabad)","Oriol",},},},},{heading = "Čeština (Czech)",entries = {{members = {"Adam Matoušek","David Spanel","Jakub Šebek (Jack_Honeypuffs)","Jens Beyer","Jezevec","Jiří Locker","Konki","Marek (d3rklord)","Marek Donar (Markus7cz)","Martin Volf","Martin Vecera (Marvec)","MaSo_CZ","Matej Svrcek (prom)","Milan Fašina (Matrix17)","Vit Hrachovy","Zbyněk Schwarz",},},},},{heading = "Dansk (Danish)",entries = {{members = {"Ask Hjorth Larsen","beer","Daniel Ejsing-Duun","David Lamhauge","Erik Soe Sorensen","Esben Aaberg","hulagutten","Joe Hansen (joedalton)","larsch","Nikolaj Sejergaard","Ole Laursen (olau)","silentStatic","Simon Stubben","Ville Witt",},},},},{heading = "Deutsch (German)",entries = {{members = {"Andreas Breitschopp","Astuur","Bamstam","Benedikt Tröster","Bob Johns","Borim","Clemens Dinkel","Daniel Kutrowatz","Daniel Winzen","Das MC","David Allwicher","DelphiMarkus","Dirk Stöcker","Elisabeth Jäger","Felix Gruber","Fenris Wolf","Ferdinand T.","FetteNase","Flames_in_Paradise","fraang","Frank Kubitschek","Gabriel Margiani","gamag","Hagen","Hanna Podewski (kristin)","herbert","HybridDog","hurz","Johannes (nuefke)","Johannes Haupt","Jonas Jonas","Jürgen Eberlein (Cherub)","Kaste","Klappstuhl","Klaus Halfmann (Hasi50)","Koneu","kraileth","LAZA","LennStar","Macedon","Marc Rodrigues (ExUndHop)","Marc Wischnowsky","Markus Pfitzner (janus)","Martin","Martin Schaerer","Matthias Krüger","Max","Max_Bento","meru","millimarg","Mirian Margiani","MirkoWodtke","Mister Pi","Mr. Anderson","Ole","Peter Schwanemann (Nasenbaer)","Philipp Niemann (Azagtoth)","Provetin","Ralf-J. Block","Raymond Vetter","ronny","SevyRide","Shevonar","SirVer","Sonnrain","Thomas","Tim O.","Timowi","Tino Miegel (TinoM)","Tobias Margiani","Venatrix","wl-zocker","Wolfgang Kurz","Wolfs","Wuzzy","Xaver (xtother90)",},},},},{heading = "Ελληνικά (Greek)",entries = {{members = {"Elias Delakovias","Lifeboy","Marinus Savoritias","ptr","Γιάννης Ανθυμίδης",},},},},{heading = "Canadian English",entries = {{members = {"Ne-1",},},},},{heading = "British English",entries = {{members = {"_aD","Alex Denvir","Andi Chandler (AndiBing)","Anthony Harrington","Biffaboy","Heber","Jackson Doak","James Thorrold","Jon Senior","LiSrt","Luis Miguel D.P.","M Crosby (classicsnoot)","mrx5682","Terry Jones","Tinker","UndiFineD","Vladimir Oka",},},},},{heading = "US American English",entries = {{members = {"DragonAtma",},},},},{heading = "Esperanto",entries = {{members = {"alms21","Fenris Wolf","Ivan Camilo Quintero Santacruz","Jens Beyer","Kristjan SCHMIDT","LaPingvino","Manuel Berkemeier","Michael Moroni (Airon90)",},},},},{heading = "Español (Spanish)",entries = {{members = {"Adolfo Jayme","Adrián Magro (senhorroar)","Agustín Vela","Alberto D.V.","Alejandro Pérez","Antonio Trueba (Fasser)","David Mitos","David Pérez","Diego Alberto Pereyra (Dishitooo)","DiegoJ","Eduardo Alberto Calvo","G BR (gastbr)","Gerardb","ironfisher","Ivan","Ivan Radzik (Sugsaggu)","Ivan Camilo Quintero Santacruz","Javi Sol","Javier Mora (morehash)","Jonay","Joseph Molina","JoseRoberto","Juan Eduardo Riva","Kiba Gasteiz (Kiibakun)","Lucía Pradillos","Luis Miguel D.P.","Madkat Here (madkat)","Martín V.","Miguel adre","Miguel de Dios Matias (tres.14159)","Monkey","Pablo Frigerio","Paco Molinero","Paulomorales","pescamillam","Rafael Augusto Maguiña Yrivarren","Rafael Medina","Raul Ferriz","Roberto López","schimmm","simon","Siz","Thadah D. Denyse","WalterCool","zer berros",},},},},{heading = "Eesti keel (Estonian)",entries = {{members = {"gert7","rm87",},},},},{heading = "Euskara (Basque)",entries = {{members = {"Mikel Alzibar",},},},},{heading = "فارسی (Persian)",entries = {{members = {"katy Zahedi","Hossien H (hossien2020)",},},},},{heading = "Suomi (Finnish)",entries = {{members = {"C C (ciucoi)","Jari Hautio","Joonas Tamminen (owava44)","Juhani Numminen","Jukka Pakarinen (flegmaatikko)","Markus Hällfors (Mad_Mac)","Max Ihalempia (xdvii7)","Pekka Järvinen (raspi)","Ropertto4","Sampo Harjula (Sahtor)","Sini Ruohomaa (Byakushin)","Teppo Mäenpää (teppq)","Tommi Nirha","Vazde",},},},},{heading = "Français",entries = {{members = {"Remerçiements aux traducteurs:","","Adrien Vigneron (VRad)","AGuechoum","AnubiS","Audiger Jeremy","Aurelien Pavel","Benjamin Subtil","Bertram","Bruno Veilleux","clark17","crep4ever","David .","Denis Chenu (Shnoulle)","Didier M (didli)","El Pensador","Eliovir","Emmanuel Andry (Eandry)","fk","François Rousselet","Gilles Aubert (Hellsprings)","Guillaume Brant","Guybrush88","Gwendal D","hu bu (finkiki)","Immunoman","Jaypad","Jean-Pierre Gemble","Hanna Podewski (kristin)","londumas","Michael Colignon","Michael DOUBEZ","Mohamed SEDKI","Nicolas Auvray (Itms)","NonoSan","Pierre Rudloff","Renaud Bouchard (neurofr)","Sébastien Duthil","Sevy Ride","Tarou","Thomas Jungers","tomtom","Tubuntu","Ubuntu1988","verdy_p","wl-zocker","YS1","Yves MATHIEU","zezinho",},},},},{heading = "Frysk (Western Frisian)",entries = {{members = {"Luitzen Hietkamp",},},},},{heading = "Gàidhlig (Scottish Gaelic)",entries = {{members = {"GunChleoc",},},},},{heading = "Galego (Galician)",entries = {{members = {"Adrián Chaves Fernández","Adrián Magro (senhorroar)","Antonio Trueba (Fasser)","Xosé",},},},},{heading = "עברית (Hebrew)",entries = {{members = {"Danny Albocher","Liel Fridman","Maor Reuben (maor309)","Michael DOUBEZ","Solomon Gruber (Piql7)","Yaron",},},},},{heading = "हिन्दी (Hindi)",entries = {{members = {"girdhari rao",},},},},{heading = "Hrvatski (Croatian)",entries = {{members = {"Ivan Bižaca (biza)","Mario Dautović",},},},},{heading = "Magyar (Hungarian)",entries = {{members = {"Agnes Dabi","Balázs Meskó (meskobalazs)","Bangó Máté","cn4ij","Dániel Varga (vargad88)","Ferenc Nagy","Gyönki Bendegúz","Herczeg Attila (hNczy)","HUNStree","István Kiss","jzombi","Kiscsirke","litoll","Major Gabesz","Muszela Balázs","Papp Bence","Peter Garami (garpe)","Richard Somlói","Robert Roth","SanskritFritz","Szűcs Kornél Géza (thewanderer)","zone",},},},},{heading = "Interlingua",entries = {{members = {"alms21",},},},},{heading = "Bahasa Indonesia (Indonesian)",entries = {{members = {"dadanhrn",},},},},{heading = "Igbo",entries = {{members = {"AhaNkem Obi",},},},},{heading = "Italiano (Italian)",entries = {{members = {"Angelo Locritani","Bananasoft (Betacentury)","Cristiano Magro (xno)","Colin Gibson","DarkSaivor","Davide Nicolini (Davidus)","Dom De Felice","Doukas7","Eulogy","Gabriel Rota","Guybrush88","ido","Luigi Lain (king_of_nowhere)","Loris Turchetti","MarcoTrevisiol","Matteo Viarengo (enthusedquill6)","Oibaf","Pierpaolo Pierozzi","pierusch","Pietro Battiston","Roberto Sciascia","Riccardo Di Maio (yogotosleepnow)","SecondCloud500","Sergio Spinatelli","sgargel","simone.sandri","Tommaso Amici",},},},},{heading = "日本語 (Japanese)",entries = {{members = {"alms21","Dios","Gonta Ultra (Ulgon)","guess880","Midori","SevyRide","Scorpio","tubame",},},},},{heading = "Basa jawa (Javanese)",entries = {{members = {"zaenal arifin",},},},},{heading = "ქართული (Georgian)",entries = {{members = {"Gabriel Margiani","gamag","Meyer Konrad",},},},},{heading = "한국어 (Korean)",entries = {{members = {"ddfddf2k",},},},},{heading = "Karjala (Karelian)",entries = {{members = {"C C (ciucoi)",},},},},{heading = "Lingua latīna (Latin)",entries = {{members = {"alms21","Leonard Noack (Aleno)","lopho","Sonnrain","Stephan Lenk","Thorsten",},},},},{heading = "Lietuvių (Lithuanian)",entries = {{members = {"Mantas Kriaučiūnas",},},},},{heading = "मराठी (Marathi)",entries = {{members = {"Amod Ajit Karmarkar",},},},},{heading = "بهاس ملايو (Malay)",entries = {{members = {"abuyop",},},},},{heading = "မြန်မာစ (Burmese)",entries = {{members = {"pyaehtetaung",},},},},{heading = "Norsk (Bokmål) (Norwegian Bokmål)",entries = {{members = {"Alexander Jansen (Bornxlo)","Bjørnar Moen Marthinsen (Bramlorn)","Fredrik Sudmann","Hans Joachim Desserud","Harald H. (haarek)","Magnus Meyer Hustveit","Martin Dahl Moe","mr.x","Thorbjørn Bruarøy (2rB)",},},},},{heading = "Plattdütsch (Low German)",entries = {{members = {"Mister Pi ","Nasenbaer ","Ole ","tando",},},},},{heading = "Nederlands (Dutch)",entries = {{members = {"ben2s","BenW","Christian Groenendijk","Dirk Schut","fireprog","fk","Foppe Benedictus","Johan Jonkman (Dikjuh)","Maasieboy","Marcel","megabyte","Patrick van der Leer","Pieter Ouwerkerk (Pietertje)","Pietertje","PliniusNeo","REAL NAME","Rick van der Zwet","Rob Snelders (Ertai)","Steven De Herdt (stdh)","Teun Spaans","Victor Pelt","Wim Champagne",},},},},{heading = "Nynorsk (Norwegian Nynorsk)",entries = {{members = {"Alexander Mackinnon Jansen","Hans Joachim Desserud","Odin Hørthe Omdal","Thorbjørn Bruarøy (2rB)",},},},},{heading = "Occitan",entries = {{members = {"Cédric VALMARY (Tot en òc)",},},},},{heading = "Polski (Polish)",entries = {{members = {"Andrzej Krentosz (Endrju)","Asahi Koishi","BartekChom","Bartosz Wiśniewski","Gabriel Fortin","Hubert Pluta","Jakub Rak (einstein13)","Januzi (januzi)","Jacek Wolszczak (Shutdownrunner)","Jens Beyer","Karol Sobolewski","Łukasz Chełmicki","Mateusz Micał","Michal Maslanko","Michał Rzepiński","MikeNow","miragae","orzeh","Patryk Sawicki","Pawel PErz","Sebastian Janus (kreys)","Stanisław Gackowski (Soeb)","Szymon Fornal","Szymon Gackowski","Szymon Nieznański","tim","Tomasz Pudło (tombox)","Tomasz Sterna","Wesmania","Wojtek","XeonBloomfield",},},},},{heading = "Português (Portuguese)",entries = {{members = {"Almufadado","daniel reis","David Rodrigues","Flávio J. Saraiva","Gnu Rreia","GunChleoc","Luis Neves (ljay79)","Marcelo do Pagode","Miguel de Freitas Fonseca","Patrick de Castro (Rayback)","Tiago Silva","trewe","zecas (zezinho)",},},},},{heading = "Português do Brasil (Brazilian Portuguese)",entries = {{members = {"Alexandre","alms21","Almufadado","Cleverton","daniel reis","Fabio Garz","Flaviano Angeli","Henrique Terto de Souza","HicHic","Hriostat","Israel","JoãoPedro BrasãoToledo","Juarez S.","Júlio Cezar Santos Pires","Juno","Luiz N","Maraschin","Marcelo do Pagode","Monstro Socialista","Murilo Poso (MetrO)","Nicolas Abril","Patrick de Castro (Rayback)","Pedro Pisandelli","Proezas","Rafael Dotti","Rafael Neri","Renata Campos","Rubens Bueno","Salatiel Ewerton","Samer Ghosnlas.2932","Tomas Abril","Vitor",},},},},{heading = "Română (Romanian)",entries = {{members = {"Tarta Vasile-Florin (phlo)","Ursachi Alexandru",},},},},{heading = "Русский (Russian)",entries = {{members = {"Александр (Kvark)","Александр Бикмеев (Romiresz)","Александр Глухов","Алексей Кабанов","Андрей Кулаков ","Андрей Олыкайнен ","Антон Хабаров (a.khabarov)","Виктор Биркманис","Владимир Коваленко","Владимир Куряев (Istercul)","Глеб Синковский","Глория Хрусталёва","Денис Дерябин","Егор Панфилов","Константин Щукин","Никита Шехов","Руслан Ковтун","Сергей Фуканчик ","Федор (Lunar_energy)","Юрий Соколов (Urra)","Arex","dr&mx","Georgiy","gerich","Gregory Lominoga (gromodar)","Iaroslav Boiarshinov (foxmulder32)","Ivan (CupIvan)","Izon","KroArtem","Lex","Massol","Papazu","SashaQR","Simple88","telema","TroubleMakerDV","Vampire Hunter D","Vlad",},},},},{heading = "Kinyarwanda",entries = {{members = {"Nasenbaer",},},},},{heading = "සිංහල (Sinhala)",entries = {{members = {"Samith Sandanayake",},},},},{heading = "Slovenčina (Slovak)",entries = {{members = {"Kefir111","Marek Hám","Miroslav Remák","Vladimir","Vladímir Tóth (Ike)",},},},},{heading = "Slovenski jezik (Slovenian)",entries = {{members = {"Andrej Znidarsic","Boštjan Miklavčič","Jure Repinc","kleb","Klemen Košir","Matevž Jekovec","Matic Gradišer","mrt",},},},},{heading = "српски (Serbian)",entries = {{members = {"Никола Павловић","Zlatko Savić (zlajonja)",},},},},{heading = "Svenska (Swedish)",entries = {{members = {"avdpos","Arve Eriksson","Christian Widell","Daniel Nylander (yeager)","Frederik Pettersson (luno)","Hilding Kåstad (HildingWK)","ivh","Joakim Lundborg","karlrune","Marcus E","Michael Rydén","Patrick H.","Phoenix","Rasmus Olstedt","RasmusBackman","Sigra","Treecko","Tumaini","Ulite",},},},},{heading = "Türkçe (Turkish)",entries = {{members = {"Aathonaeax","Asiye","Ekrem Kocadere","Ercin Senturk","Erdy","Recep Hasanbaş (swarf)","ScriptMonster","Volkan Gezer","yakup","Yusuf boy",},},},},{heading = "українська мова (Ukranian)",entries = {{members = {"Вячеслав Фияло (Slaventius)","Сергій Дубик","Fedik","Shemet Yevhene","Vladislav Trotsky (flyboooy17)",},},},},{heading = "Tiếng Việt (Vietnamese)",entries = {{members = {"Nguyen Quang Chien",},},},},{heading = "简体中文 (Simplified Chinese)",entries = {{members = {"Frank Tang (roadt)","luojie-dune","Susie Shi","XIA",},},},},{heading = "繁體中文 (Traditional Chinese)",entries = {{members = {"AJ","Arm Coon","poormusic","sonny",},},},},} end
\ No newline at end of file

=== modified file 'src/graphic/text/rt_parse.cc'
--- src/graphic/text/rt_parse.cc	2017-05-13 08:36:05 +0000
+++ src/graphic/text/rt_parse.cc	2017-12-17 11:19:18 +0000
@@ -256,6 +256,7 @@
 
 		tc.allowed_children.insert("font");
 		tc.allowed_children.insert("space");
+		tc.allowed_children.insert("vspace");
 		tc.allowed_children.insert("br");
 		tc.allowed_children.insert("img");
 		tc.allowed_children.insert("div");
@@ -280,6 +281,7 @@
 		tc.allowed_children.insert("p");
 		tc.allowed_children.insert("font");
 		tc.allowed_children.insert("div");
+		tc.allowed_children.insert("img");
 		tc.text_allowed = true;
 		tc.has_closing_tag = true;
 		tag_constraints_["font"] = tc;

=== modified file 'src/graphic/text/rt_render.cc'
--- src/graphic/text/rt_render.cc	2017-12-10 03:03:53 +0000
+++ src/graphic/text/rt_render.cc	2017-12-17 11:19:18 +0000
@@ -678,7 +678,11 @@
 		return 0;
 	}
 	std::shared_ptr<UI::RenderedText> render(TextureCache* /* texture_cache */) override {
-		NEVER_HERE();
+		// TODO(GunChleoc): When using div width=*, some newline nodes are not being consumed.
+		// Since it is working as expected otherwise and I can't find the problem, let's fix this some other time.
+		// Testing can be done with the editor terrains/trees help
+		// NEVER_HERE();
+		return std::shared_ptr<UI::RenderedText>(new UI::RenderedText());
 	}
 	bool is_non_mandatory_space() const override {
 		return true;
@@ -818,7 +822,12 @@
 			rendered_text->rects.push_back(std::unique_ptr<UI::RenderedRect>(std::move(bg_rect)));
 		}
 
-		for (std::shared_ptr<RenderNode> n : nodes_to_render_) {
+<<<<<<< TREE
+		for (std::shared_ptr<RenderNode> n : nodes_to_render_) {
+=======
+		for (std::shared_ptr<RenderNode> n : nodes_to_render_) {
+			// TODO(GunChleoc): With div width=*, we are getting newline nodes here, which should have been consumed
+>>>>>>> MERGE-SOURCE
 			const auto& renderme = n->render(texture_cache);
 			for (auto& rendered_rect : renderme->rects) {
 				if (rendered_rect->was_visited()) {

=== modified file 'src/scripting/lua_game.cc'
--- src/scripting/lua_game.cc	2017-12-17 03:57:22 +0000
+++ src/scripting/lua_game.cc	2017-12-17 11:19:18 +0000
@@ -429,7 +429,11 @@
 	int32_t posy = -1;
 	Coords coords = Coords::null();
 
+<<<<<<< TREE
 #define CHECK_UINT(var)                                                                            \
+=======
+#define CHECK_UINT(var)                                                                       \
+>>>>>>> MERGE-SOURCE
 	lua_getfield(L, -1, #var);                                                                      \
 	if (!lua_isnil(L, -1))                                                                          \
 		var = luaL_checkuint32(L, -1);                                                               \
@@ -441,19 +445,39 @@
 		CHECK_UINT(w);
 		CHECK_UINT(h);
 
+<<<<<<< TREE
 		// If a field has been defined, read the coordinates to jump to.
+=======
+		// If a field has been defined, read the coordinated to jump to.
+>>>>>>> MERGE-SOURCE
 		lua_getfield(L, 4, "field");
 		if (!lua_isnil(L, -1)) {
-			coords = (*get_user_class<LuaField>(L, -1))->coords();
+<<<<<<< TREE
+			coords = (*get_user_class<LuaField>(L, -1))->coords();
+=======
+			coords = (*get_user_class<LuaField>(L, -1))->coords();
+			game.get_ipl()->map_view()->scroll_to_field(coords, MapView::Transition::Jump);
+>>>>>>> MERGE-SOURCE
 		}
 		lua_pop(L, 1);
 	}
+<<<<<<< TREE
 #undef CHECK_UINT
 	std::unique_ptr<StoryMessageBox> mb(new StoryMessageBox(
 	   &game, coords, luaL_checkstring(L, 2), luaL_checkstring(L, 3), posx, posy, w, h));
+=======
+#undef CHECK_UINT
+	StoryMessageBox* mb = new StoryMessageBox(&game, coords, luaL_checkstring(L, 2),
+	                                          luaL_checkstring(L, 3), posx, posy, w, h);
+>>>>>>> MERGE-SOURCE
 
 	mb->run<UI::Panel::Returncodes>();
-
+<<<<<<< TREE
+
+=======
+	delete mb;
+
+>>>>>>> MERGE-SOURCE
 	return 1;
 }
 

=== modified file 'src/ui_basic/box.cc'
--- src/ui_basic/box.cc	2017-12-17 03:57:22 +0000
+++ src/ui_basic/box.cc	2017-12-17 11:19:18 +0000
@@ -135,21 +135,41 @@
 	layout();
 }
 
-bool Box::handle_mousewheel(uint32_t which, int32_t x, int32_t y) {
-	if (scrollbar_) {
-		assert(scrolling_);
-		return scrollbar_->handle_mousewheel(which, x, y);
-	}
-	return Panel::handle_mousewheel(which, x, y);
-}
-bool Box::handle_key(bool down, SDL_Keysym code) {
-	if (scrollbar_) {
-		assert(scrolling_);
-		return scrollbar_->handle_key(down, code);
-	}
-	return Panel::handle_key(down, code);
-}
-
+<<<<<<< TREE
+bool Box::handle_mousewheel(uint32_t which, int32_t x, int32_t y) {
+	if (scrollbar_) {
+		assert(scrolling_);
+		return scrollbar_->handle_mousewheel(which, x, y);
+	}
+	return Panel::handle_mousewheel(which, x, y);
+}
+bool Box::handle_key(bool down, SDL_Keysym code) {
+	if (scrollbar_) {
+		assert(scrolling_);
+		return scrollbar_->handle_key(down, code);
+	}
+	return Panel::handle_key(down, code);
+}
+
+=======
+bool Box::handle_mousewheel(uint32_t which, int32_t x, int32_t y) {
+	if (scrollbar_) {
+		assert(scrolling_);
+		return scrollbar_->handle_mousewheel(which, x, y);
+	}
+	return Panel::handle_mousewheel(which, x, y);
+
+}
+bool Box::handle_key(bool down, SDL_Keysym code) {
+	if (scrollbar_) {
+		assert(scrolling_);
+		return scrollbar_->handle_key(down, code);
+	}
+	return Panel::handle_key(down, code);
+}
+
+
+>>>>>>> MERGE-SOURCE
 /**
  * Adjust all the children and the box's size.
  */

=== modified file 'src/ui_basic/panel.cc'
=== modified file 'src/ui_basic/scrollbar.cc'
--- src/ui_basic/scrollbar.cc	2017-12-17 03:57:22 +0000
+++ src/ui_basic/scrollbar.cc	2017-12-17 11:19:18 +0000
@@ -439,6 +439,7 @@
 	return true;
 }
 
+<<<<<<< TREE
 bool Scrollbar::handle_key(bool down, SDL_Keysym code) {
 	if (down) {
 		if (horizontal_) {
@@ -508,6 +509,77 @@
 	return Panel::handle_key(down, code);
 }
 
+=======
+bool Scrollbar::handle_key(bool down, SDL_Keysym code) {
+	if (down) {
+		if (horizontal_) {
+			switch (code.sym) {
+			case SDLK_KP_6:
+				if (code.mod & KMOD_NUM) {
+					break;
+				}
+				FALLS_THROUGH;
+			case SDLK_RIGHT:
+				action(Plus);
+				return true;
+
+			case SDLK_KP_4:
+				if (code.mod & KMOD_NUM) {
+					break;
+				}
+				FALLS_THROUGH;
+			case SDLK_LEFT:
+				action(Minus);
+				return true;
+			default:
+				break;  // not handled
+			}
+		} else {
+			switch (code.sym) {
+			case SDLK_KP_2:
+				if (code.mod & KMOD_NUM) {
+					break;
+				}
+				FALLS_THROUGH;
+			case SDLK_DOWN:
+				action(Plus);
+				return true;
+
+			case SDLK_KP_8:
+				if (code.mod & KMOD_NUM) {
+					break;
+				}
+				FALLS_THROUGH;
+			case SDLK_UP:
+				action(Minus);
+				return true;
+
+			case SDLK_KP_3:
+				if (code.mod & KMOD_NUM) {
+					break;
+				}
+				FALLS_THROUGH;
+			case SDLK_PAGEDOWN:
+				action(PlusPage);
+				return true;
+
+			case SDLK_KP_9:
+				if (code.mod & KMOD_NUM) {
+					break;
+				}
+				FALLS_THROUGH;
+			case SDLK_PAGEUP:
+				action(MinusPage);
+				return true;
+			default:
+				break;  // not handled
+			}
+		}
+	}
+	return Panel::handle_key(down, code);
+}
+
+>>>>>>> MERGE-SOURCE
 void Scrollbar::layout() {
 	if ((2 * kSize + get_knob_size()) > static_cast<uint32_t>((horizontal_ ? get_w() : get_h()))) {
 		buttonsize_ = kSize / 2;

=== modified file 'src/ui_basic/scrollbar.h'
=== modified file 'src/wui/encyclopedia_window.cc'
--- src/wui/encyclopedia_window.cc	2017-06-11 20:09:05 +0000
+++ src/wui/encyclopedia_window.cc	2017-12-17 11:19:18 +0000
@@ -40,7 +40,7 @@
 
 constexpr int kPadding = 5;
 constexpr int kTabHeight = 35;
-
+// TODO(GunChleoc): Remove when all help is converted to new font renderer
 const std::string heading(const std::string& text) {
 	return ((boost::format("<rt><p font-size=18 font-weight=bold font-color=D1D1D1>"
 	                       "%s<br></p><p font-size=8> <br></p></rt>") %
@@ -173,9 +173,19 @@
 			cr->resume();
 			table = cr->pop_table();
 		}
-		contents_.at(tab_name)->set_text(
-		   (boost::format("%s%s") % heading(table->get_string("title")) % table->get_string("text"))
-		      .str());
+
+		// TODO(GunChleoc): Remove this when all in-game help has been converted.
+		try {
+			contents_.at(tab_name)->force_new_renderer();
+			contents_.at(tab_name)->set_text(as_message(table->get_string("title"), table->get_string("text")));
+		} catch (const std::exception& e) {
+			log("Encyclopedia: falling back to OLD font renderer: %s\n", e.what());
+			contents_.at(tab_name)->force_new_renderer(false);
+			contents_.at(tab_name)->set_text(
+			   (boost::format("%s%s") % heading(table->get_string("title")) % table->get_string("text"))
+			      .str());
+		}
+
 	} catch (LuaError& err) {
 		contents_.at(tab_name)->set_text(err.what());
 	}

=== modified file 'src/wui/game_objectives_menu.cc'
--- src/wui/game_objectives_menu.cc	2017-02-23 17:58:25 +0000
+++ src/wui/game_objectives_menu.cc	2017-12-17 11:19:18 +0000
@@ -86,5 +86,15 @@
  * An entry in the objectives menu has been selected
  */
 void GameObjectivesMenu::selected(uint32_t const t) {
-	objectivetext.set_text(t == ListType::no_selection_index() ? std::string() : list[t].descr());
+	const std::string text = t == ListType::no_selection_index() ? "" : list[t].descr();
+	// TODO(GunChleoc): When all campaigns, scenarios and win conditions have been converted, simply add the text above.
+	try {
+		objectivetext.force_new_renderer();
+		objectivetext.set_text(text);
+		log("Objectives: using NEW font renderer.\n");
+	} catch (const std::exception& e) {
+		log("Objectives: falling back to OLD font renderer:\n%s\n%s\n", text.c_str(), e.what());
+		objectivetext.force_new_renderer(false);
+		objectivetext.set_text(text);
+	}
 }

=== modified file 'src/wui/story_message_box.cc'
--- src/wui/story_message_box.cc	2017-12-17 03:57:22 +0000
+++ src/wui/story_message_box.cc	2017-12-17 11:19:18 +0000
@@ -26,6 +26,7 @@
 #include "ui_basic/button.h"
 #include "ui_basic/multilinetextarea.h"
 #include "ui_basic/textarea.h"
+<<<<<<< TREE
 #include "wui/interactive_player.h"
 
 namespace {
@@ -34,12 +35,23 @@
 
 StoryMessageBox::StoryMessageBox(Widelands::Game* game,
                                  const Widelands::Coords coords,
+=======
+#include "wui/interactive_player.h"
+
+namespace {
+constexpr int kPadding = 4;
+}
+
+StoryMessageBox::StoryMessageBox(Widelands::Game* game,
+											const Widelands::Coords coords,
+>>>>>>> MERGE-SOURCE
                                  const std::string& title,
                                  const std::string& body,
                                  int32_t const x,
                                  int32_t const y,
                                  uint32_t const w,
                                  uint32_t const h)
+<<<<<<< TREE
    : UI::Window(game->get_ipl(), "story_message_box", x, y, w, h, title.c_str()),
      main_box_(this, kPadding, kPadding, UI::Box::Vertical, 0, 0, kPadding),
      button_box_(&main_box_, kPadding, kPadding, UI::Box::Horizontal, 0, 0, kPadding),
@@ -84,6 +96,51 @@
 	if (x == -1 && y == -1) {
 		center_to_parent();
 	}
+=======
+   : UI::Window(game->get_ipl(), "story_message_box", x, y, w, h, title.c_str()),
+	  main_box_(this, kPadding, kPadding, UI::Box::Vertical, 0, 0, kPadding),
+	  button_box_(&main_box_, kPadding, kPadding, UI::Box::Horizontal, 0, 0, kPadding),
+	  textarea_(&main_box_, 0, 0, 100, 100, ""),
+	  ok_(&button_box_, "ok", 0, 0, 120, 0, g_gr->images().get("images/ui_basic/but5.png"), _("OK")),
+	  desired_speed_(game->game_controller()->desired_speed()),
+	  game_(game) {
+
+	// Pause the game
+	game_->game_controller()->set_desired_speed(0);
+	game_->save_handler().set_allow_saving(false);
+
+	// Adjust map view
+	if (coords != Widelands::Coords::null()) {
+		game_->get_ipl()->map_view()->scroll_to_field(coords, MapView::Transition::Jump);
+	}
+
+	// TODO(GunChleoc): When all campaigns and scenarios have been converted, simply add the body text above.
+	try {
+		textarea_.force_new_renderer();
+		textarea_.set_text(body);
+		log("Story Message Box: using NEW font renderer.\n");
+	} catch (const std::exception& e) {
+		log("Story Message Box: falling back to OLD font renderer:\n%s\n%s\n", body.c_str(), e.what());
+		textarea_.force_new_renderer(false);
+		textarea_.set_text(body);
+	}
+
+
+	// Add and configure the panels
+	main_box_.set_size(get_inner_w() - 3 * kPadding, get_inner_h() - 2 * kPadding);
+
+	main_box_.add(&textarea_, UI::Box::Resizing::kExpandBoth);
+	main_box_.add(&button_box_, UI::Box::Resizing::kFullSize);
+	button_box_.add_inf_space();
+	button_box_.add(&ok_);
+	button_box_.add_inf_space();
+
+	ok_.sigclicked.connect(boost::bind(&StoryMessageBox::clicked_ok, boost::ref(*this)));
+
+	if (x == -1 && y == -1) {
+		center_to_parent();
+	}
+>>>>>>> MERGE-SOURCE
 	move_inside_parent();
 	textarea_.focus();
 }

=== modified file 'src/wui/story_message_box.h'
--- src/wui/story_message_box.h	2017-12-17 03:57:22 +0000
+++ src/wui/story_message_box.h	2017-12-17 11:19:18 +0000
@@ -36,12 +36,21 @@
  * If 'x' == 'y' == -1, the message box will be centered on screen.
  */
 struct StoryMessageBox : public UI::Window {
+<<<<<<< TREE
 	StoryMessageBox(Widelands::Game* game,
 	                const Widelands::Coords coords,
 	                const std::string& title,
 	                const std::string& body,
 	                int32_t x,
 	                int32_t y,
+=======
+	StoryMessageBox(Widelands::Game* game,
+						 const Widelands::Coords coords,
+	                const std::string& title,
+	                const std::string& body,
+	                int32_t x,
+	                int32_t y,
+>>>>>>> MERGE-SOURCE
 	                uint32_t w,
 	                uint32_t h);
 
@@ -55,6 +64,7 @@
 private:
 	/// Get the game running again and close the window.
 	void clicked_ok();
+<<<<<<< TREE
 
 	// UI elements
 	UI::Box main_box_;
@@ -64,6 +74,17 @@
 
 	const uint32_t desired_speed_;  // Remember the previous game speed
 	Widelands::Game* game_;         // For controlling the game speed
+=======
+
+	// UI elements
+	UI::Box main_box_;
+	UI::Box button_box_;
+	UI::MultilineTextarea textarea_;
+	UI::Button ok_;
+
+	const uint32_t desired_speed_; // Remember the previous game speed
+	Widelands::Game* game_; // For controlling the game speed
+>>>>>>> MERGE-SOURCE
 };
 
 #endif  // end of include guard: WL_WUI_STORY_MESSAGE_BOX_H


References