patch 9.0.2127: translation Makefiles can be improved

Problem:  translation Makefiles can be improved
Solution: Modified and extended po-related Makefiles and
          related files

closes: #13518

Signed-off-by: RestorerZ <restorer@mail2k.ru>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/Filelist b/Filelist
index 29d9f5a..000e5ed 100644
--- a/Filelist
+++ b/Filelist
@@ -990,6 +990,7 @@
 		runtime/doc/*-tr.UTF-8.1 \
 		runtime/lang/README.txt \
 		runtime/lang/Makefile \
+		runtime/lang/Make_all.mak \
 		runtime/lang/menu_*.vim \
 		runtime/keymap/README.txt \
 		runtime/keymap/*.vim \
@@ -1049,10 +1050,12 @@
 		src/po/vim.desktop.in \
 		src/po/gvim.desktop.in \
 		src/po/sjiscorr.c \
+		src/po/big5corr.c \
 		src/po/*.po \
 
 # the language files for the Win32 lang archive
 LANG_DOS = \
 		src/po/*.mo \
+		runtime/lang/Make_mvc.mak \
 
 # vim: set ft=make:
diff --git a/src/po/Make_mvc.mak b/src/po/Make_mvc.mak
index 9cfa408..b168af7 100644
--- a/src/po/Make_mvc.mak
+++ b/src/po/Make_mvc.mak
@@ -6,26 +6,55 @@
 # Please read README_mvc.txt before using this file.
 #
 
-!ifndef VIMRUNTIME
-VIMRUNTIME = ..\..\runtime
-!endif
+!IF [powershell -nologo -noprofile "exit $$psversiontable.psversion.major"] == 2
+!ERROR The program "PowerShell" version 3.0 or higher is required to work
+!ENDIF
+
+!IFNDEF LANGUAGE
+!ERROR Set the environment variable %LANGUAGE%. See README_mvc.txt
+!ENDIF
 
 # get LANGUAGES, MOFILES, MOCONVERTED and others
-!include Make_all.mak
+!INCLUDE Make_all.mak
+
+!IFNDEF VIMRUNTIME
+VIMRUNTIME = ..\..\runtime
+!ENDIF
 
 PACKAGE = vim
+# Correct the following line for the where executeable file vim is installed
 VIM = ..\vim
 
 # Correct the following line for the directory where gettext et al is installed
-GETTEXT_PATH = H:\gettext.0.14.4\bin
+GETTEXT_PATH = D:\Programs\GetText\bin
 
 MSGFMT = $(GETTEXT_PATH)\msgfmt -v
 XGETTEXT = $(GETTEXT_PATH)\xgettext
 MSGMERGE = $(GETTEXT_PATH)\msgmerge
 
-MV = move
-CP = copy
-RM = del
+# In case some package like GnuWin32, UnixUtils, gettext
+# or something similar is installed on the system.
+# If the "iconv" program is installed on the system, but it is not registered
+# in the %PATH% environment variable, then specify the full path to this file.
+!IF EXIST ("iconv.exe")
+ICONV = "iconv.exe"
+!ELSEIF EXIST ("$(GETTEXT_PATH)\iconv.exe")
+ICONV="$(GETTEXT_PATH)\iconv.exe"
+!ENDIF
+
+# In case some package like GnuWin32, UnixUtils
+# or something similar is installed on the system.
+# If the "touch" program is installed on the system, but it is not registered
+# in the %PATH% environment variable, then specify the full path to this file.
+!IF EXIST ("touch.exe")
+TOUCH = touch.exe $@
+!ELSE
+TOUCH = @if exist $@ ( copy /b $@+,, ) else ( type nul >$@ )
+!ENDIF
+
+MV = move /y
+CP = copy /y
+RM = del /q
 MKD = mkdir
 LS = dir
 
@@ -34,14 +63,426 @@
 INSTALLDIR = $(VIMRUNTIME)\lang\$(LANGUAGE)\LC_MESSAGES
 
 .SUFFIXES:
-.SUFFIXES: .po .mo .pot
+.SUFFIXES: .po .mo .pot .ck
+
+all: $(MOFILES) $(MOCONVERTED)
+
+.po.ck:
+	$(VIM) -u NONE -e -X -S check.vim -c "if error == 0 | q | endif" -c cq $<
+	$(TOUCH)
+
+check: $(CHECKFILES)
+
+checkclean:
+	$(RM) *.ck
+
+converted: $(MOCONVERTED)
+
+nl.po:
+	@( echo \# > nl.po )
+
+# Norwegian/Bokmal: "nb" is an alias for "no".
+nb.po: no.po
+	$(CP) no.po nb.po
+
+# Convert ja.po to create ja.sjis.po.
+ja.sjis.po: ja.po
+	@$(MAKE) -nologo -f Make_mvc.mak sjiscorr
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t CP932 $? | .\sjiscorr.exe > $@
+!ELSEIF DEFINED (ICONV)
+	$(ICONV) -f UTF-8 -t CP932 $? | .\sjiscorr.exe > $@
+!ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(65001)), \
+		[System.Text.Encoding]::GetEncoding(932))
+	type $@ | .\sjiscorr.exe > tmp.$@
+	@$(MV) tmp.$@ $@
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(932)) \
+		-replace \"`r`n\", \"`n\"; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(932))
+
+sjiscorr: sjiscorr.c
+	$(CC) sjiscorr.c
+
+# Convert ja.po to create ja.euc-jp.po
+ja.euc-jp.po: ja.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t EUC-JP -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f UTF-8 -t EUC-JP $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(65001)), \
+		[System.Text.Encoding]::GetEncoding(20932))
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(20932)) -replace \
+		'charset=utf-8', 'charset=EUC-JP'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(20932))
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(20932)) -replace \
+		'# Original translations', \
+		'# Generated from ja.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(20932))
+
+# Convert cs.po to create cs.cp1250.po.
+cs.cp1250.po: cs.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t CP1250 -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f ISO-8859-2 -t CP1250 $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(28592)), \
+		[System.Text.Encoding]::GetEncoding(1250))
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1250)) -replace \
+		'charset=iso-8859-2', 'charset=CP1250'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1250))
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1250)) -replace \
+		'# Original translations', \
+		'# Generated from cs.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1250))
+
+# Convert pl.po to create pl.cp1250.po.
+pl.cp1250.po: pl.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t CP1250 -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f ISO-8859-2 -t CP1250 $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(28592)), \
+		[System.Text.Encoding]::GetEncoding(1250))
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1250)) -replace \
+		'charset=iso-8859-2', 'charset=CP1250'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1250))
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1250)) -replace \
+		'# Original translations', \
+		'# Generated from pl.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1250))
+
+# Convert pl.po to create pl.UTF-8.po.
+pl.UTF-8.po: pl.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t UTF-8 -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f ISO-8859-2 -t UTF-8 $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(28592)))
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		(Get-Content -Raw -Encoding UTF8 $@ \
+		^| % {$$_-replace 'charset=iso-8859-2', 'charset=UTF-8'}) \
+		^| 1>nul New-Item -Force -Path . -ItemType file -Name $@
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		(Get-Content -Raw -Encoding UTF8 $@ \
+		^| % {$$_-replace '# Original translations', \
+		'# Generated from pl.po, DO NOT EDIT'}) \
+		^| 1>nul New-Item -Force -Path . -ItemType file -Name $@
+
+# Convert sk.po to create sk.cp1250.po.
+sk.cp1250.po: sk.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t CP1250 -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f ISO-8859-2 -t CP1250 $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(28592)), \
+		[System.Text.Encoding]::GetEncoding(1250))
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1250)) -replace \
+		'charset=iso-8859-2', 'charset=CP1250'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1250))
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1250)) -replace \
+		'# Original translations', \
+		'# Generated from sk.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1250))
+
+# Convert zh_CN.UTF-8.po to create zh_CN.po.
+zh_CN.po: zh_CN.UTF-8.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t GB2312 -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f UTF-8 -t GB2312 $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(65001)), \
+		[System.Text.Encoding]::GetEncoding(936))
+
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(936)) -replace \
+		'charset=UTF-8', 'charset=GB2312'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(936))
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(936)) -replace \
+		'# Original translations', \
+		'# Generated from zh_CN.UTF-8.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(936))
+
+# Convert zh_CN.UTF-8.po to create zh_CN.cp936.po.
+# Set 'charset' to gbk to avoid that msfmt generates a warning.
+# This used to convert from zh_CN.po, but that results in a conversion error.
+zh_CN.cp936.po: zh_CN.UTF-8.po
+	-$(RM) $@
+!IF DEFINED (ICONV)
+	$(ICONV) -f UTF-8 -t CP936 $? > $@
+!ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(65001)), \
+		[System.Text.Encoding]::GetEncoding(20936))
+
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(20936)) \
+		-replace 'charset=UTF-8', 'charset=GBK'\
+		-replace '# Original translations', \
+		'# Generated from zh_CN.UTF-8.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(20936))
+
+# Convert zh_TW.UTF-8.po to create zh_TW.po
+zh_TW.po: zh_TW.UTF-8.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t BIG5 -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f UTF-8 -t BIG5 $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(65001)), \
+		[System.Text.Encoding]::GetEncoding(950))
+
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(950)) -replace \
+		'charset=UTF-8', 'charset=BIG5'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(950))
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(950)) -replace \
+		'# Original translations', \
+		'# Generated from zh_TW.UTF-8.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(950))
+
+# Convert zh_TW.UTF-8.po to create zh_TW.po with backslash characters
+# Requires doubling backslashes in the second byte.  Don't depend on big5corr,
+# it should only be compiled when zh_TW.po is outdated.
+#
+#  06.11.23, added by Restorer:
+#  For more details, see:
+#  https://github.com/vim/vim/pull/3261
+#  https://github.com/vim/vim/pull/3476
+#  https://github.com/vim/vim/pull/12153
+#  (read all comments)
+#
+#  I checked the workability on the list of backslash characters
+#  specified in zh_TW.UTF-8.po. It works.
+#  But it is better to have someone native speaker check it.
+#
+
+#zh_TW.po: zh_TW.UTF-8.po
+#	@$(MAKE) -nologo -f Make_mvc.mak big5corr
+#	-$(RM) $@
+#!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+#	"$(GETTEXT_PATH)\msgconv.exe" -t BIG5 $? | .\big5corr.exe > $@
+#!ELSEIF DEFINED (ICONV)
+#	$(ICONV) -f UTF-8 -t BIG5 $? | .\big5corr.exe > $@
+#!ELSE
+#	powershell -nologo -noprofile -Command \
+#		[System.IO.File]::WriteAllText(\"$@\", \
+#		[System.IO.File]::ReadAllText(\"$?\", \
+#		[System.Text.Encoding]::GetEncoding(65001)), \
+#		[System.Text.Encoding]::GetEncoding(950))
+#	type $@ | .\big5corr.exe > tmp.$@
+#	@$(MV) tmp.$@ $@
+#!ENDIF
+#	powershell -nologo -noprofile -Command \
+#		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+#		[System.Text.Encoding]::GetEncoding(950)) \
+#		-replace \"`r`n\", \"`n\"; \
+#		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+#		[System.Text.Encoding]::GetEncoding(950))
+
+# see above in the zh_TW.po conversion section for backslashes.
+#big5corr: big5corr.c
+#	$(CC) big5corr.c
+
+# Convert ko.UTF-8.po to create ko.po.
+ko.po: ko.UTF-8.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t EUC-KR -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f UTF-8 -t EUC-KR $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(65001)), \
+		[System.Text.Encoding]::GetEncoding(51949))
+
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(51949)) -replace \
+		'charset=UTF-8', 'charset=EUC-KR'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(51949))
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(51949)) -replace \
+		'# Original translations', \
+		'# Generated from ko.UTF-8.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(51949))
+
+# Convert ru.po to create ru.cp1251.po.
+ru.cp1251.po: ru.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t CP1251 -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f UTF-8 -t CP1251 $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(65001)), \
+		[System.Text.Encoding]::GetEncoding(1251))
+
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1251)) -replace \
+		'charset=UTF-8', 'charset=CP1251'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1251))
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1251)) -replace \
+		'# Original translations', \
+		'# Generated from ru.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1251))
+
+# Convert uk.po to create uk.cp1251.po.
+uk.cp1251.po: uk.po
+	-$(RM) $@
+!IF EXIST ("$(GETTEXT_PATH)\msgconv.exe")
+	"$(GETTEXT_PATH)\msgconv.exe" -t CP1251 -o $@ $?
+!ELSE
+! IF DEFINED (ICONV)
+	$(ICONV) -f UTF-8 -t CP1251 $? > $@
+! ELSE
+	powershell -nologo -noprofile -Command \
+		[System.IO.File]::WriteAllText(\"$@\", \
+		[System.IO.File]::ReadAllText(\"$?\", \
+		[System.Text.Encoding]::GetEncoding(65001)), \
+		[System.Text.Encoding]::GetEncoding(1251))
+
+! ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1251)) -replace \
+		'charset=UTF-8', 'charset=CP1251'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1251))
+!ENDIF
+	powershell -nologo -noprofile -Command \
+		$$out = [System.IO.File]::ReadAllText(\"$@\", \
+		[System.Text.Encoding]::GetEncoding(1251)) -replace \
+		'# Original translations', \
+		'# Generated from uk.po, DO NOT EDIT'; \
+		[System.IO.File]::WriteAllText(\"$@\", $$out, \
+		[System.Text.Encoding]::GetEncoding(1251))
 
 .po.mo:
 	set OLD_PO_FILE_INPUT=yes
 	$(MSGFMT) -o $@ $<
 
-all: $(MOFILES) $(MOCONVERTED)
-
 PO_INPUTLIST = \
 	..\*.c \
 	..\if_perl.xs \
@@ -57,22 +498,32 @@
 	$(LS) $(LSFLAGS) $(PO_INPUTLIST) > .\files
 
 first_time: files
-	$(VIM) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
+	$(VIM) -u NONE --not-a-term -S tojavascript.vim $(LANGUAGE).po \
+		$(PO_VIM_INPUTLIST)
 	set OLD_PO_FILE_INPUT=yes
 	set OLD_PO_FILE_OUTPUT=yes
-	$(XGETTEXT) --default-domain=$(LANGUAGE) --add-comments $(XGETTEXT_KEYWORDS) --files-from=.\files $(PO_VIM_JSLIST)
-	$(VIM) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).pot $(PO_VIM_INPUTLIST)
+	$(XGETTEXT) --default-domain=$(LANGUAGE) --add-comments $(XGETTEXT_KEYWORDS) \
+		--files-from=.\files $(PO_VIM_JSLIST)
+	$(VIM) -u NONE --not-a-term -S fixfilenames.vim $(LANGUAGE).po \
+		$(PO_VIM_INPUTLIST)
 	$(RM) *.js
 
 $(PACKAGE).pot: files
-	$(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
+	$(VIM) -u NONE --not-a-term -S tojavascript.vim $(PACKAGE).pot \
+		$(PO_VIM_INPUTLIST)
 	set OLD_PO_FILE_INPUT=yes
 	set OLD_PO_FILE_OUTPUT=yes
-	$(XGETTEXT) --default-domain=$(PACKAGE) --add-comments $(XGETTEXT_KEYWORDS) --files-from=.\files $(PO_VIM_JSLIST)
+	$(XGETTEXT) --default-domain=$(PACKAGE) --add-comments $(XGETTEXT_KEYWORDS) \
+		--files-from=.\files $(PO_VIM_JSLIST)
 	$(MV) $(PACKAGE).po $(PACKAGE).pot
-	$(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot $(PO_VIM_INPUTLIST)
+	$(VIM) -u NONE --not-a-term -S fixfilenames.vim $(PACKAGE).pot \
+		$(PO_VIM_INPUTLIST)
 	$(RM) *.js
 
+# When updating ja.sjis.po there are a bunch of errors and a crash.
+# The files that are converted to a different encoding clearly state "DO NOT EDIT".
+update-po: $(MOFILES:.mo=)
+
 # Don't add a dependency here, we only want to update the .po files manually
 $(LANGUAGES):
 	@$(MAKE) -nologo -f Make_mvc.mak $(PACKAGE).pot GETTEXT_PATH=$(GETTEXT_PATH)
@@ -81,15 +532,27 @@
 	$(MSGMERGE) $@.po.old $(PACKAGE).pot -o $@.po
 	$(RM) $@.po.old
 
-install:
+install: $(LANGUAGE).mo
 	if not exist $(INSTALLDIR) $(MKD) $(INSTALLDIR)
 	$(CP) $(LANGUAGE).mo $(INSTALLDIR)\$(PACKAGE).mo
 
 install-all: all
-	FOR %%l IN ($(LANGUAGES)) DO @IF NOT EXIST $(VIMRUNTIME)\lang\%%l\LC_MESSAGES $(MKD) $(VIMRUNTIME)\lang\%%l\LC_MESSAGES
-	FOR %%l IN ($(LANGUAGES)) DO @$(CP) %%l.mo $(VIMRUNTIME)\lang\%%l\LC_MESSAGES\$(PACKAGE).mo
+	for %%l in ($(LANGUAGES)) do @if not exist $(VIMRUNTIME)\lang\%%l\LC_MESSAGES \
+		$(MKD) $(VIMRUNTIME)\lang\%%l\LC_MESSAGES
+	for %%l in ($(LANGUAGES)) do @$(CP) %%l.mo \
+		$(VIMRUNTIME)\lang\%%l\LC_MESSAGES\$(PACKAGE).mo
 
-clean:
+cleanup-po: $(LANGUAGE).po
+	$(VIM) -u NONE -e -X -S cleanup.vim -c wq $**
+
+cleanup-po-all: $(POFILES)
+	!$(VIM) -u NONE -e -X -S cleanup.vim -c wq $**
+
+clean: checkclean
 	$(RM) *.mo
 	$(RM) *.pot
 	$(RM) files
+	$(RM) sjiscorr.obj sjiscorr.exe
+#	$(RM) big5corr.obj big5corr.exe
+
+# vim: set noet sw=8 ts=8 sts=0 wm=0 tw=0 ft=make:
diff --git a/src/po/Makefile b/src/po/Makefile
index b637f12..5ecfb1d 100644
--- a/src/po/Makefile
+++ b/src/po/Makefile
@@ -102,78 +102,128 @@
 ja.sjis.po: ja.po
 	@$(MAKE) sjiscorr
 	rm -f ja.sjis.po
-	iconv -f utf-8 -t cp932 ja.po | ./sjiscorr > ja.sjis.po
+	iconv -f UTF-8 -t CP932 ja.po | ./sjiscorr > ja.sjis.po
 
 sjiscorr: sjiscorr.c
 	$(CC) -o sjiscorr sjiscorr.c
 
 ja.euc-jp.po: ja.po
-	iconv -f utf-8 -t euc-jp ja.po | \
-		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=euc-jp/' -e 's/# Original translations/# Generated from ja.po, DO NOT EDIT/' > ja.euc-jp.po
+	iconv -f UTF-8 -t EUC-JP ja.po | \
+		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=EUC-JP/' \
+			-e 's/# Original translations/# Generated from ja.po, DO NOT EDIT/' \
+			> ja.euc-jp.po
 
 # Convert cs.po to create cs.cp1250.po.
 cs.cp1250.po: cs.po
 	rm -f cs.cp1250.po
-	iconv -f iso-8859-2 -t cp1250 cs.po | \
-		$(SED) -e 's/charset=ISO-8859-2/charset=cp1250/' -e 's/# Original translations/# Generated from cs.po, DO NOT EDIT/' > cs.cp1250.po
+	iconv -f ISO-8859-2 -t CP1250 cs.po | \
+		$(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=CP1250/' \
+			-e 's/# Original translations/# Generated from cs.po, DO NOT EDIT/' \
+			> cs.cp1250.po
 
 # Convert pl.po to create pl.cp1250.po.
 pl.cp1250.po: pl.po
 	rm -f pl.cp1250.po
-	iconv -f iso-8859-2 -t cp1250 pl.po | \
-		$(SED) -e 's/charset=ISO-8859-2/charset=cp1250/' -e 's/# Original translations/# Generated from pl.po, DO NOT EDIT/' > pl.cp1250.po
+	iconv -f ISO-8859-2 -t CP1250 pl.po | \
+		$(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=CP1250/' \
+			-e 's/# Original translations/# Generated from pl.po, DO NOT EDIT/' \
+			> pl.cp1250.po
 
 # Convert pl.po to create pl.UTF-8.po.
 pl.UTF-8.po: pl.po
 	rm -f pl.UTF-8.po
-	iconv -f iso-8859-2 -t utf-8 pl.po | \
-		$(SED) -e 's/charset=ISO-8859-2/charset=UTF-8/' -e 's/# Original translations/# Generated from pl.po, DO NOT EDIT/' > pl.UTF-8.po
+	iconv -f ISO-8859-2 -t UTF-8 pl.po | \
+		$(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=UTF-8/' \
+			-e 's/# Original translations/# Generated from pl.po, DO NOT EDIT/' \
+			> pl.UTF-8.po
 
 # Convert sk.po to create sk.cp1250.po.
 sk.cp1250.po: sk.po
 	rm -f sk.cp1250.po
-	iconv -f iso-8859-2 -t cp1250 sk.po | \
-		$(SED) -e 's/charset=ISO-8859-2/charset=cp1250/' -e 's/# Original translations/# Generated from sk.po, DO NOT EDIT/' > sk.cp1250.po
+	iconv -f ISO-8859-2 -t CP1250 sk.po | \
+		$(SED) -e 's/charset=[iI][sS][oO]-8859-2/charset=CP1250/' \
+			-e 's/# Original translations/# Generated from sk.po, DO NOT EDIT/' \
+			> sk.cp1250.po
 
 # Convert zh_CN.UTF-8.po to create zh_CN.po.
 zh_CN.po: zh_CN.UTF-8.po
 	rm -f zh_CN.po
-	iconv -f UTF-8 -t gb2312 zh_CN.UTF-8.po | \
-		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=gb2312/' -e 's/# Original translations/# Generated from zh_CN.UTF-8.po, DO NOT EDIT/' > zh_CN.po
+	iconv -f UTF-8 -t GB2312 zh_CN.UTF-8.po | \
+		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=GB2312/' \
+			-e 's/# Original translations/# Generated from zh_CN.UTF-8.po, DO NOT EDIT/' \
+			> zh_CN.po
 
 # Convert zh_CN.UTF-8.po to create zh_CN.cp936.po.
 # Set 'charset' to gbk to avoid that msfmt generates a warning.
 # This used to convert from zh_CN.po, but that results in a conversion error.
 zh_CN.cp936.po: zh_CN.UTF-8.po
 	rm -f zh_CN.cp936.po
-	iconv -f UTF-8 -t cp936 zh_CN.UTF-8.po | \
-		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=gbk/' -e 's/# Original translations/# Generated from zh_CN.UTF-8.po, DO NOT EDIT/' > zh_CN.cp936.po
+	iconv -f UTF-8 -t CP936 zh_CN.UTF-8.po | \
+		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=GBK/' \
+			-e 's/# Original translations/# Generated from zh_CN.UTF-8.po, DO NOT EDIT/' \
+			> zh_CN.cp936.po
 
 # Convert zh_TW.UTF-8.po to create zh_TW.po
 zh_TW.po: zh_TW.UTF-8.po
 	rm -f zh_TW.po
-	iconv -f UTF-8 -t big5 zh_TW.UTF-8.po | \
-		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=big5/' -e 's/# Original translations/# Generated from zh_TW.UTF-8.po, DO NOT EDIT/' > zh_TW.po
+	iconv -f UTF-8 -t BIG5 zh_TW.UTF-8.po | \
+		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=BIG5/' \
+			-e 's/# Original translations/# Generated from zh_TW.UTF-8.po, DO NOT EDIT/' \
+			> zh_TW.po
+
+
+# Convert zh_TW.UTF-8.po to create zh_TW.po with backslash characters
+# Requires doubling backslashes in the second byte.  Don't depend on big5corr,
+# it should only be compiled when zh_TW.po is outdated.
+
+#
+#  06.11.23, added by Restorer
+#  For more details, see:
+#  https://github.com/vim/vim/pull/3261
+#  https://github.com/vim/vim/pull/3476
+#  https://github.com/vim/vim/pull/12153
+#  (read all comments)
+#
+#  I checked the workability on the list of backslash characters
+#  specified in zh_TW.UTF-8.po. It works.
+#  But it is better to have someone native speaker check it.
+#
+
+#zh_TW.po: zh_TW.UTF-8.po
+#	@$(MAKE) big5corr
+#	rm -f zh_TW.po
+#	iconv -f UTF-8 -t BIG5 zh_TW.UTF-8.po | ./big5corr > zh_TW.po
+
+
+# 06.11.23, added by Restorer
+# see above in the zh_tw.po conversion section for backslashes.
+#big5corr: big5corr.c
+#	$(CC) -o big5corr big5corr.c
+
 
 # Convert ko.UTF-8.po to create ko.po.
 ko.po: ko.UTF-8.po
 	rm -f ko.po
-	iconv -f UTF-8 -t euc-kr ko.UTF-8.po | \
-		$(SED) -e 's/charset=UTF-8/charset=euc-kr/' \
-		    -e 's/# Korean translation for Vim/# Generated from ko.UTF-8.po, DO NOT EDIT/' \
-		    > ko.po
+	iconv -f UTF-8 -t EUC-KR ko.UTF-8.po | \
+		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=EUC-KR/' \
+			-e 's/# Original translations/# Generated from ko.UTF-8.po, DO NOT EDIT/' \
+			> ko.po
 
 # Convert ru.po to create ru.cp1251.po.
 ru.cp1251.po: ru.po
 	rm -f ru.cp1251.po
-	iconv -f utf-8 -t cp1251 ru.po | \
-		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=cp1251/' -e 's/# Original translations/# Generated from ru.po, DO NOT EDIT/' > ru.cp1251.po
+	iconv -f UTF-8 -t CP1251 ru.po | \
+		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=CP1251/' \
+			-e 's/# Original translations/# Generated from ru.po, DO NOT EDIT/' \
+			> ru.cp1251.po
 
 # Convert uk.po to create uk.cp1251.po.
 uk.cp1251.po: uk.po
 	rm -f uk.cp1251.po
-	iconv -f utf-8 -t cp1251 uk.po | \
-		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=cp1251/' -e 's/# Original translations/# Generated from uk.po, DO NOT EDIT/' > uk.cp1251.po
+	iconv -f UTF-8 -t CP1251 uk.po | \
+		$(SED) -e 's/charset=[uU][tT][fF]-8/charset=CP1251/' \
+			-e 's/# Original translations/# Generated from uk.po, DO NOT EDIT/' \
+			> uk.cp1251.po
 
 prefixcheck:
 	@if test "x" = "x$(prefix)"; then \
@@ -186,6 +236,7 @@
 clean: checkclean
 	rm -f core core.* *.old.po *.mo *.pot sjiscorr
 	rm -f LINGUAS vim.desktop gvim.desktop tmp_*desktop
+#	rm -f big5corr
 
 distclean: clean
 
@@ -231,7 +282,9 @@
 	if command -v desktop-file-validate; then desktop-file-validate tmp_gvim.desktop; fi
 	mv tmp_gvim.desktop gvim.desktop
 
-update-po: $(LANGUAGES)
+# When updating ja.sjis.po there are a bunch of errors and a crash.
+# The files that are converted to a different encoding clearly state "DO NOT EDIT".
+update-po: $(MOFILES:.mo=)
 
 # Don't add a dependency here, we only want to update the .po files manually
 $(LANGUAGES):
diff --git a/src/po/README.txt b/src/po/README.txt
index 039038b..5a09d1f 100644
--- a/src/po/README.txt
+++ b/src/po/README.txt
@@ -30,10 +30,12 @@
 on MS-Windows.  Download the gettext packages, for example from:
 
 	http://sourceforge.net/projects/gettext
+	or
+	https://mlocati.github.io/articles/gettext-iconv-windows.html
 
 You might have to do the commands manually.  Example:
 
-   cd c:\vim\vim81
+   cd c:\vim\vim91
    mkdir runtime\lang\ja\LC_MESSAGES
    msgfmt -o runtime\lang\ja\LC_MESSAGES\vim.mo src\po\ja.po
 
@@ -51,7 +53,7 @@
 We will use "xx.po" as an example here, replace "xx" with the name of your
 language.
 
-- Edit Makefile to add xx to LANGUAGES and xx.mo to MOFILES.
+- Edit Make_all.mak to add xx to LANGUAGES and xx.mo to MOFILES.
 - If you haven't done so already, run ./configure in the top vim directory
   (i.e. go up two directories) and then come back here afterwards.
 - Execute these commands:
diff --git a/src/po/README_mingw.txt b/src/po/README_mingw.txt
index abb5cd7..d00ba30 100644
--- a/src/po/README_mingw.txt
+++ b/src/po/README_mingw.txt
@@ -20,7 +20,7 @@
 First of all you must set the environment variable LANGUAGE to xx, where xx is
 the name of your language. You can do it from the command line or adding a
 line to your autoexec.bat file: set LANGUAGE=xx. You must also add your
-language to the Make_ming.mak file in the lines LANGUAGES, MOFILES, AND
+language to the Make_all.mak file in the lines LANGUAGES, MOFILES, AND
 POFILES.
 
 If you don't have a xx.po file, you must create it with the command:
diff --git a/src/po/README_mvc.txt b/src/po/README_mvc.txt
index c63ad1f..691e6ae 100644
--- a/src/po/README_mvc.txt
+++ b/src/po/README_mvc.txt
@@ -14,6 +14,11 @@
 expat will install into its own directory.  You should copy libexpat.dll into
 the bin directory created from the gettext/libiconv packages.
 
+Or Michele Locati kindly provides precompiled binaries gettext 0.21 and
+iconv 1.16 for Windows on his site: 
+
+	https://mlocati.github.io/articles/gettext-iconv-windows.html
+
 First read the README.txt file in this directory for general remarks on
 translating Vim messages.
 
@@ -26,9 +31,9 @@
 
 	http://www.geocities.com/click2speak/languages.html
 
-Another possibility is to use the gnuwin32 port of gettext. This is
+Another possibility is to use the GnuWin32 port of gettext. This is
 recommended especially if you use already gnuwin32 tools to gunzip, bunzip,
-patch etc. these files. You find the gnuwin32 version of gettext here:
+patch etc. these files. You find the GnuWin32 version of gettext here:
 
         http://gnuwin32.sourceforge.net/packages/gettext.htm
 
@@ -51,7 +56,7 @@
 CREATING A NEW TRANSLATION
 
 When creating a new translation you must add your language code to the
-Make_mvc.mak file in the lines defining LANGUAGES and MOFILES.  To create the
+Make_all.mak file in the lines defining LANGUAGES and MOFILES.  To create the
 initial .po file for your language you must use the command:
 
 	make -f make_mvc.mak first_time
@@ -64,11 +69,11 @@
 
 You will also need to edit the file names in the comments in the .po file.
 You need to remove the absolute directory specification (which has the form
-c:\vim61\src\).  You can do this in Vim with the following command with the
+c:\vim91\src\).  You can do this in Vim with the following command with the
 appropriate directory specification for where you have installed the Vim
 source:
 
-	%s/c:\\vim61\\src\\//g
+	%s/c:\\vim91\\src\\//g
 
 
 UPDATING A TRANSLATION
diff --git a/src/po/big5corr.c b/src/po/big5corr.c
new file mode 100644
index 0000000..de8045e
--- /dev/null
+++ b/src/po/big5corr.c
@@ -0,0 +1,58 @@
+/*
+ * Simplistic program to correct Big5 inside strings.  When a trail byte is a
+ * backslash it needs to be doubled.
+ * Public domain.
+ */
+
+/*
+ * 06.11.23, added by Restorer:
+ * For more details, see:
+ * https://github.com/vim/vim/pull/3261
+ * https://github.com/vim/vim/pull/3476
+ * https://github.com/vim/vim/pull/12153
+ * (read all comments)
+ *
+ * I checked the workability on the list of backslash characters
+ * specified in zh_TW.UTF-8.po. It works.
+ * But it is better to have someone native speaker check it.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+	int
+main(int argc, char **argv)
+{
+	char buffer[BUFSIZ];
+	char *p;
+
+	while (fgets(buffer, BUFSIZ, stdin) != NULL)
+	{
+		for (p = buffer; *p != 0; p++)
+		{
+			if (strncmp(p, "charset=utf-8", 13) == 0
+				|| strncmp(p, "charset=UTF-8", 13) == 0)
+			{
+				fputs("charset=BIG-5", stdout);
+				p += 12;
+			}
+			else if (strncmp(p, "# Original translations", 23) == 0)
+			{
+				fputs("# Generated from zh_TW.UTF-8.po, DO NOT EDIT.", stdout);
+				while (p[1] != '\n')
+					++p;
+			}
+			else
+			{
+				if (*(unsigned char *)p >= 0xA1)
+				{
+					putchar(*p++);
+					if (*p == '\\')
+						putchar(*p);
+				}
+				putchar(*p);
+			}
+		}
+	}
+}
diff --git a/src/po/sjiscorr.c b/src/po/sjiscorr.c
index 7aa0533..c6c3983 100644
--- a/src/po/sjiscorr.c
+++ b/src/po/sjiscorr.c
@@ -19,12 +19,12 @@
 			if (strncmp(p, "charset=utf-8", 13) == 0
 				|| strncmp(p, "charset=UTF-8", 13) == 0)
 			{
-				fputs("charset=cp932", stdout);
+				fputs("charset=CP932", stdout);
 				p += 12;
 			}
 			else if (strncmp(p, "# Original translations", 23) == 0)
 			{
-				fputs("# generated from ja.po, DO NOT EDIT", stdout);
+				fputs("# Generated from ja.po, DO NOT EDIT.", stdout);
 				while (p[1] != '\n')
 					++p;
 			}
diff --git a/src/version.c b/src/version.c
index 8e35aaa..6f3397e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2127,
+/**/
     2126,
 /**/
     2125,