texlive[69488] Master: unicode-math-input (18jan24)

commits+karl at tug.org commits+karl at tug.org
Thu Jan 18 22:21:08 CET 2024


Revision: 69488
          https://tug.org/svn/texlive?view=revision&revision=69488
Author:   karl
Date:     2024-01-18 22:21:08 +0100 (Thu, 18 Jan 2024)
Log Message:
-----------
unicode-math-input (18jan24)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/unicode-math-input/README
    trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input-script.py
    trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input.pdf
    trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input.tex
    trunk/Master/texmf-dist/tex/latex/unicode-math-input/unicode-math-input-table.tex
    trunk/Master/texmf-dist/tex/latex/unicode-math-input/unicode-math-input.sty
    trunk/Master/tlpkg/libexec/ctan2tds

Modified: trunk/Master/texmf-dist/doc/latex/unicode-math-input/README
===================================================================
--- trunk/Master/texmf-dist/doc/latex/unicode-math-input/README	2024-01-18 21:19:05 UTC (rev 69487)
+++ trunk/Master/texmf-dist/doc/latex/unicode-math-input/README	2024-01-18 21:21:08 UTC (rev 69488)
@@ -8,7 +8,7 @@
 
 ========
 
-Copyright 2022-2023 user202729
+Copyright 2022-2024 user202729
 
 This work  may be  distributed and/or  modified under  the conditions  of the
 LaTeX Project Public License (LPPL),  either version 1.3c  of this license or

Modified: trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input-script.py
===================================================================
--- trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input-script.py	2024-01-18 21:19:05 UTC (rev 69487)
+++ trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input-script.py	2024-01-18 21:21:08 UTC (rev 69488)
@@ -1,7 +1,47 @@
 #!/bin/python3
-# This file is not used while TeX is running. It's for generating unicode-math-input-table.tex file only.
-# This requires pythonimmediate (not sure which version is compatible but commit 63f94476a5cb11e33db1215a9bf7c17657d9773d on Python 3.10.10 is)
+"""
+This file is not used while TeX is running. It's for generating unicode-math-input-table.tex file only.
+This requires pythonimmediate (not sure which version is compatible but
+commit 020068db8a966c138b5b0b93695c0fefdef03d0a on Python 3.11.3 is)
 
+To generate: run::
+	python3 unicode-math-input-script.py > unicode-math-input-table.tex
+
+How does it work?
+
+The mapping is determined from multiple sources:
+
+* The unicode-math package itself, which defines a "command → Unicode character" mapping.
+  This does not always work because different TeX packages may name the command differently.
+
+* Synonym table, obtained by looking at STIX's command definition
+
+* TeX's glyph → unicode mapping (used to facilitate copy-paste in PDF),
+  e.g. /usr/share/texmf-dist/tex/generic/pdftex/glyphtounicode.tex
+  This should be good, but is currently not used. Furthermore, not all TeX commands are implemented by
+  getting a single character from a font...
+
+How does the Unicode mapping work?
+
+First there's the `pdftex.map` file, then there's umsa.cmap for msam10.tfm/afm/pfm/pfb/mf (metafont source file)
+
+/usr/share/texmf-dist/fonts/source/public/amsfonts/symbols/msam10.mf
+	/usr/share/texmf-dist/fonts/source/public/amsfonts/symbols/asymbols.mf
+
+/usr/share/texmf-dist/fonts/afm/public/amsfonts/symbols/msam10.afm
+→ plaintext-looking file may work
+
+/usr/share/texmf-dist/fonts/tfm/public/amsfonts/symbols/msam10.tfm
+/usr/share/texmf-dist/fonts/type1/public/amsfonts/symbols/msam10.pfm
+/usr/share/texmf-dist/fonts/type1/public/amsfonts/symbols/msam10.pfb
+
+The glyphtounicode.tex may be a bit problematic...
+	https://tex.stackexchange.com/questions/66300/how-to-fix-missing-or-incorrect-mappings-from-glyphtounicode-tex
+
+See also: section 3.2 How to find a table of correspondences? in https://tex.stackexchange.com/a/628285/250119
+
+"""
+
 from __future__ import annotations
 
 from pythonimmediate.engine import ChildProcessEngine
@@ -8,7 +48,8 @@
 from pythonimmediate.engine import default_engine
 from pythonimmediate import*
 import pythonimmediate
-from collections import defaultdict
+from collections import defaultdict, Counter
+from itertools import groupby
 import os
 import json
 import subprocess
@@ -25,13 +66,10 @@
 
 
 # ======== start a luatex engine
-engine=ChildProcessEngine("luatex", env={**os.environ, "hash_extra": "0"})
 # https://tex.stackexchange.com/questions/574607/tex-hashtokens-incomplete
-default_engine.set_engine(engine)
+default_engine.set_engine(ChildProcessEngine("luatex", env={**os.environ, "hash_extra": "0"}))
 
-Catcode.active("a").meaning_str()
 
-
 """
 from the TeXbook: 
 
@@ -93,10 +131,108 @@
 	assert match
 	unicode_char=chr(int(match[1], 16))
 	csname=match[2]
-	#unicode_math_table_.append(Item(unicode_char=unicode_char, csname=csname))
+	#unicode_math_table_.append(Item(unicode_char=unicode_char, csname))
 	unicode_math_table_[unicode_char].append(csname)
 unicode_math_table={unicode_char: tuple(csnames) for unicode_char, csnames in unicode_math_table_.items()}
 
+# ======== extract unicode-math synonyms
+
+def control_sequences()->list[str]:
+	return (lua_try_eval(r"""
+	do
+		local s={}
+		for k, v in pairs(tex.hashtokens()) do
+			if v:find("^[A-Za-z]+$") then
+				s[v]=0
+			end
+		end
+		local t={}
+		for v, _ in pairs(s) do table.insert(t, v) end
+		return table.concat(t, "\x00")
+	end
+	""") or "").split("\x00")
+
+extra_synonyms_list: list[list[str]] = [
+					  ["adots", "iddots"],
+					  ["unicodecdots", "cdots"], # https://github.com/wspr/unicode-math/issues/571
+					  ["unicodeellipsis", "ldots"],
+					  #["llbracket", "lBrack"],
+					  #["rrbracket", "rBrack"],
+					  ]
+
+
+
+
+c=control_sequences()
+m={x: T[x].meaning_str() for x in c}
+
+pattern=re.compile(r'\\protected macro:->\\([A-Za-z]+) ?')
+
+extra_synonyms_list += [[c, match[1]] for c, m in m.items()
+ if (match:=pattern.fullmatch(m))
+ ]
+
+def same_meaning_control_sequences(meaning: dict[str, str])->list[list[str]]:
+	return [
+		l
+		for m, l0 in groupby(sorted(c, key=lambda x: meaning[x]), lambda x: meaning[x])
+		if m!="undefined"
+		for l in [[*l0]]
+		if len(l)>=2
+		]
+
+extra_synonyms_list += same_meaning_control_sequences(m)
+
+# ======== extract amsmath&stix synonyms
+
+
+m_values=[]
+for preamble in [
+r"""
+\documentclass{article}
+\usepackage{amsmath}
+\usepackage{amssymb}
+\usepackage{amsfonts}
+\begin{document}
+""",
+r"""
+\documentclass{article}
+\usepackage{stix}
+\begin{document}
+"""
+]:
+	with ChildProcessEngine("luatex", env={**os.environ, "hash_extra": "0"}) as e, default_engine.set_engine(e):
+		execute(preamble)
+		c=control_sequences()
+		m={x: T[x].meaning_str() for x in c}
+		extra_synonyms_list += same_meaning_control_sequences(m)
+		m_values.append(m)
+[amsmath_meaning, stix_meaning]=m_values
+# ======== build extra_synonyms table
+
+while True:
+	tmp=Counter([x for l in extra_synonyms_list for x in l])
+	[(item, frequency)]=tmp.most_common(1)
+	if frequency==1: break
+	assert frequency>1
+	extra_synonyms_list=[
+			# the group that contain item
+			[*{x for l in extra_synonyms_list if item in l for x in l}]
+			] + [
+					# remaining groups
+					l for l in extra_synonyms_list if item not in l]
+	
+
+extra_synonyms_list=sorted([sorted(l) for l in {frozenset(
+	item for item in l
+	if item not in ("dotsc", "dotsm", "dotsb", "dots")  # some simple filtering -- we will just use \cdots and \ldots
+	) for l in extra_synonyms_list} if len(l)>1]) # deduplicate
+
+tmp=Counter(sum(extra_synonyms_list, []))
+assert tmp.most_common()[0][1]==1, tmp
+
+extra_synonyms = {v: u for u in extra_synonyms_list for v in u}
+
 # ======== check how much of the table is valid on unicode-math/luatex
 
 def getdelcode(x: str)->tuple[int, int, int, int]:
@@ -289,12 +425,12 @@
 	r"\Zeta"   : "Z",
 	}
 
-extra_synonyms = {v: u for u in 
-				  [
-					  ["adots", "iddots"]
-					  ]
-				  for v in u}
 
+ASCII_symbol_synonym = {
+		"minus": "-",
+		"mid": "|",
+		}
+
 ##
 
 remaining_chars = changed_chars - {*unicode_math_table} - specially_handled - not_handled
@@ -306,11 +442,11 @@
 	if fullch in remaining_chars: remaining_chars.remove(fullch)
 	print(r'\__umi_define_char{' + fullch + r'}{\char'+str(i)+' }')
 
-defined_csnames = {x for l in unicode_math_table.values() for x in l}
+defined_csnames = {x for l in unicode_math_table.values() for x in l} | {*stix_meaning} | {*amsmath_meaning}
 
 
 pdf_engine=ChildProcessEngine("pdftex")
-execute(r"""
+with default_engine.set_engine(pdf_engine): execute(r"""
 \documentclass{article}
 \usepackage{amsmath}
 \usepackage{amssymb}
@@ -317,8 +453,17 @@
 \usepackage{amsfonts}
 \usepackage{mathrsfs}
 \begin{document}
-""", engine=pdf_engine)
+""")
 
+def remove_not(a: str)->Optional[str]:
+	global defined_csnames
+	if a in (r"\ni", r"\nu"): return None
+	if a.startswith(r"\not") and a.removeprefix(r"\not") in defined_csnames:
+		return '\\' + a.removeprefix(r"\not")
+	elif a.startswith(r"\n") and a.removeprefix(r"\n") in defined_csnames:
+		return '\\' + a.removeprefix(r"\n")
+	else: return None
+
 for unicode_char, csnames_ in unicode_math_table.items():
 	csnames = [*csnames_]
 	if unicodedata.combining(unicode_char) != 0:
@@ -374,16 +519,18 @@
 		for csname in [*csnames]:
 			if csname in extra_synonyms:
 				csnames+=extra_synonyms[csname]
-		csnames=[*set(csnames)]
+		csnames=[*{csname: None for csname in csnames}]
 
 		items1=[]
 		for csname in csnames:
 			if not is_delimiter:
-				assert "delimiter" not in T[csname].meaning_str(engine=pdf_engine), (unicode_char, csname)
+				with default_engine.set_engine(pdf_engine):
+					assert "delimiter" not in T[csname].meaning_str(), (unicode_char, csname)
 				# that is the symbol is not a delimiter in pdf_engine either (check is not particularly reliable but okay)
 
 			for prefix, replacement in math_alphabet_translate.items():
 				if csname.startswith(prefix):
+					assert csname not in ASCII_symbol_synonym
 					cs = math_alphabet_csname_translation[csname.removeprefix(prefix)]
 					def wrap_in_alphabet_selector(cs: str)->str:
 						if replacement is None: return cs
@@ -398,30 +545,39 @@
 					break
 			else:
 				items1.append("\\" + csname)
+				if csname in ASCII_symbol_synonym: items1+=ASCII_symbol_synonym[csname]
 
+		assert items1
+		if is_delimiter and len(items1)>1:
+			print("Warning: Synonym for delimiter not supported?", unicode_char, delimiter, items1, file=sys.stderr)
+			del items1[1:]
+
 		if len(items1)==1:
 			a = items1[0]
-			if a.startswith(r"\not") and a.removeprefix(r"\not") in defined_csnames:
+			b = remove_not(a)
+			if b is not None:
 				assert not is_delimiter
-				b='\\' + a.removeprefix(r"\not")
 				print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{\__umi_alternatives_not{a}{b}}}")
-				a.removeprefix(r"\not")
-			elif a.startswith(r"\n") and a.removeprefix(r"\n") in defined_csnames:
-				assert not is_delimiter
-				b='\\' + a.removeprefix(r"\n")
-				print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{\__umi_alternatives_not{a}{b}}}")
-				a.removeprefix(r"\n")
 			else:
 				if is_delimiter:
 					print(f"\\__umi_define_char_maybe_delimiter{{{optional_space}{unicode_char}}}{{{a}}}")
 				else:
 					print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{{a}}}")
+		elif len(items1)==2:
+			assert re.fullmatch(r'\\[a-zA-Z]+', items1[0]), items1
+			assert re.fullmatch(r'\\[a-zA-Z]+|[^a-zA-Z]', items1[1]), items1
+			b=remove_not(items1[0])
+			if b is not None:
+				d=remove_not(items1[1])
+				assert d is not None, items1
+				print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{\\__umi_alternatives_not_two{items1[0]}{items1[1]}{b}{d}}}")
+			else:
+				print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{\\__umi_alternatives{items1[0]}{items1[1]}}}")
 		else:
-			assert not is_delimiter, (unicode_char, delimiter)
-			assert len(items1)==2, items1
-			assert re.fullmatch(r'\\[a-zA-Z]+', items1[0]), items1
-			assert re.fullmatch(r'\\[a-zA-Z]+', items1[1]), items1
-			print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{\\__umi_alternatives{items1[0]}{items1[1]}}}")
+			assert len(items1)>=3, items1
+			assert all(remove_not(x) is None for x in items1), items1
+			assert all(re.fullmatch(r'\\[a-zA-Z]+', c) for c in items1), items1
+			print(f"\\__umi_define_char{{{optional_space}{unicode_char}}}{{\\__umi_alternatives_m{{{''.join(items1)}}}}}")
 
 ##
 
@@ -431,96 +587,14 @@
 
 # ========  part below are draft.
 
-T.longdivisionsign.meaning_str()
+default_engine.set_engine(ChildProcessEngine("luatex", env={**os.environ, "hash_extra": "0"}, autorestart=True))
+execute(r'\documentclass{article}\usepackage{unicode-math}\begin{document}')
 
+execute(r'\documentclass{article}\usepackage{amsmath,amssymb,amsfonts}\begin{document}')
 
+execute(r'\documentclass{article}\usepackage{amsmath}\usepackage{amssymb}\usepackage{amsfonts}\usepackage{tikz}')
 
-T.mathexclam.meaning_str()
 
-T.symoperators.meaning_str()
-
-T.perp.meaning_str()
-
-umathcode[" ̅"[1]]
-
-BalancedTokenList(r'\the\Udelcode `̅').expand_o().int()
-
-x = BalancedTokenList(r'\the\Udelcode `!').expand_o().int()
-print(hex(x))
-
-hex(BalancedTokenList(r'\the\delcode `!').expand_o().int())
-
-
-
-
-
-if 0:
-
-	data = TokenList([r"\directlua", TokenList.fstr(
-	r"""
-	for k, v in pairs(tex.hashtokens()) do
-		tex.print(-2, v .. "\0")
-	end
-	"""
-	)]).expand_x().str()
-	control_sequences = data.split("\x00")
-	assert control_sequences[-1]==""
-	del control_sequences[-1]
-
-
-Path("/tmp/control_sequences.json").write_text(json.dumps(control_sequences))  # type: ignore
-control_sequences = json.loads(Path("/tmp/control_sequences.json").read_text())  # type: ignore
-
-
-Path("/tmp/control_sequences_unicode_math.json").write_text(json.dumps(control_sequences))
-control_sequences = json.loads(Path("/tmp/control_sequences_unicode_math.json").read_text())
-assert "mitrho" in control_sequences
-
-if 0:
-	# try some other random things
-
-	control_sequences = data.split("\x00")
-	assert control_sequences[-1]==""
-	del control_sequences[-1]
-
-
-
-	BalancedTokenList(r'\the\Umathcode `′').expand_o().int() == 0x1000000
-
-
-control_sequences
-
-BalancedTokenList(r'\the\mathcode`⨁').expand_o().int()
-
-Catcode.active("⨁").meaning_str(engine=engine)
-
-Catcode.active("′").meaning_str(engine=engine)
-
-T.bigoplus_sym.meaning_str()
-
-T.bigoplusop.meaning_str()
-
-T.bigoplus.meaning_str()
-
-
-
-T.rho.meaning_str()
-
-T.mitrho.meaning_str()
-
-T.bigoplus.meaning_str()
-
-engine._stdout_lines[-100:] + [bytes(engine._stdout_buffer)]
-
-
-
-T.mscrA.meaning_str()
-
-
-
-
-
-
 @functools.lru_cache(maxsize=None)
 def is_defined(csname: str)->bool:
 	return T[csname].meaning_str()!="undefined"
@@ -586,6 +660,3 @@
 BalancedTokenList(r"\csname\noexpand\aa\endcsname").expand_o(engine=test_engine)  # give error
 BalancedTokenList(r"\csname\string\aa\endcsname").expand_o(engine=test_engine)  # \[\aa] as expected
 
-T.iddots.meaning_str(engine=engine)
-
-T.adots.meaning_str(engine=engine)

Modified: trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input.tex	2024-01-18 21:19:05 UTC (rev 69487)
+++ trunk/Master/texmf-dist/doc/latex/unicode-math-input/unicode-math-input.tex	2024-01-18 21:21:08 UTC (rev 69488)
@@ -1,5 +1,6 @@
 %! TEX program = lualatex
-\ProvidesFile{unicode-math-input.tex} [2023/05/12 v0.0.0 ]
+\ProvidesFile{unicode-math-input.tex} [2024/01/18 v0.1.0 ]
+\PassOptionsToPackage{hyphens}{url}
 \RequirePackage{fvextra}
 \documentclass{l3doc}
 \usepackage[svgnames]{xcolor}
@@ -15,7 +16,12 @@
 \tracinglostchars=3
 \newcommand\csref[1]{\texttt{\hyperref[doc/function//#1]{\textbackslash #1}}}
 \newcommand\varref[1]{\texttt{\hyperref[doc/function//#1]{#1}}}
+\usepackage{precattl}
 \begin{document}
+\precattlExec{
+\NewDocumentEnvironment{option}{v}{\begin{variable}{#1\cO\}\iffalse}\fi Package option.\par}{\end{variable}}
+}
+
 \hfuzz=1pt
 \GetFileInfo{\jobname.tex}
 
@@ -45,6 +51,15 @@
 We compare the situation with several existing packages:
 
 \begin{itemize}
+	\item \pkg{commonunicode}:
+		\begin{itemize}
+			\item defines all characters to be active, which means it breaks usage of |α| in \pkg{fancyvrb}'s |Verbatim| environment for example.
+			\item changes the behavior of e.g. |½| in text mode in PDF\LaTeX.
+			\item does not always select best option, for example |∄| always get mapped to |\not\exists| even though the outcome is worse than |\nexists|.
+			\item fakes several symbols such as |≝| even when there's better option e.g. |\eqdef|,
+			\item uses |\ensuremath| extensively, which means no error message when it's used in text mode,
+			\item not as good symbol coverage.
+		\end{itemize}
 	\item \pkg{unixode}:
 		\begin{itemize}
 			\item defines |′| to be |\prime| which is big and not usable, it should be |^{\prime}|
@@ -177,6 +192,13 @@
 		corresponding Unicode character (|π|) will also change. This will incur a small loss in efficiency however.
 
 		(modulo the issue with |\Udelcode| mentioned above)
+
+	\item The character |⋯| is mapped to |\cdots| and |…| is mapped to |\ldots|. Note that |\dots| behaves
+		the same as |\ldots| without \pkg{amsmath} package loaded, but with it it smartly detect which variant to use
+		depends on the following character, for example |$\dots +$| prints $\dots +$ but |$\dots ,$| prints $\dots ,$.
+
+		There's another discrepancy with the spacing around these 2 characters,
+		see \url{https://github.com/wspr/unicode-math/issues/571}.
 \end{itemize}
 
 There are some issues however:
@@ -227,6 +249,8 @@
 
 	For example you can |\renewcommand\umiMathbf[1]{\mathbf{#1}}| which is the default behavior.
 
+	Or you can execute, for example, |\renewcommand\umiMathscr[1]{\mathcal{#1}}| to use the calligraphic instead of the script alphabet for script characters.
+
 	More usefully, you may want to |\renewcommand\umiMathbf{\bm}| to make entered characters such as
 	$𝐚$ appear bold italic in the output, remember to load package \pkg{bm} if you want to do so (which is |unicode-math| behavior
 	with |[bold-style=ISO]| package option).
@@ -240,27 +264,27 @@
 	|\let\umiFrac\tfrac| (or more clearly, |\renewcommand\umiFrac[2]{\tfrac{#1}{#2}}|)
 	to customize the appearance of Unicode characters like |½|.
 
-	If you want to customize the appearance of individual symbols, consider using \csref{umiDefineMathChar}.
+	If you want to customize the appearance of individual symbols, consider using \csref{umiDeclareMathChar}.
 \end{function}
 
-\begin{function}{\umiDefineMathChar}
+\begin{function}{\umiDeclareMathChar}
 	\begin{syntax}
-		|\umiDefineMathChar {α} {\alpha}|
+		|\umiDeclareMathChar {α} {\alpha}|
 	\end{syntax}
-	Does what it says.
+	Does what it says. Will override existing definitions, if any.
 
 	Note that the Unicode character must be braced.
 
-	(You may choose to call \csref{umiPatchCmdUnicodeArg}| \umiDefineMathChar|
+	(You may choose to call \csref{umiPatchCmdUnicodeArg}| \umiDeclareMathChar|
 	beforehand so bracing is not necessary, but this is not really recommended)
 
 	This might or might not destroy the existing text-mode definition. For now,
-	one way to preserve it is |\umiDefineMathChar {²} {\TextOrMath{\texttwosuperior}{^2}}|.
+	one way to preserve it is |\umiDeclareMathChar {²} {\TextOrMath{\texttwosuperior}{^2}}|.
 \end{function}
 
-\begin{function}{\umiDefineMathDelimiter}
+\begin{function}{\umiDeclareMathDelimiter}
 	\begin{syntax}
-		|\umiDefineMathDelimiter {⟨} \langle|
+		|\umiDeclareMathDelimiter {⟨} \langle|
 	\end{syntax}
 	You must use this in order to use the Unicode character with |\left|, |\big|, |\bigl| etc.
 	(because of the internal detail being that in Xe\LaTeX\ and Lua\LaTeX,
@@ -269,9 +293,14 @@
 
 	In that case the second argument must be a single token.
 
-	Unfortunately, the command does not always work.
+	Unfortunately, the command does not always work -- it must detect the second argument to be a delimiter, but
+	if the detection fails it may not work.
 \end{function}
 
+\emph{Note}: There's no need to provide |\umiDeclareMathAlphabet|, |\umiDeclareMathAccent| or |\umiDeclareMathRadical|, for |\umiDeclareMathChar| suffices.
+It's not supported to define \emph{control sequences}, for that the typical |\RenewDocumentCommand|
+or |\RenewCommandCopy| suffices.
+
 \begin{function}{\umiRefreshDelimiterList}
 	\begin{syntax}
 	    |\umiRefreshDelimiterList|
@@ -282,17 +311,15 @@
 
 	This command will check all the normal delimiter Unicode characters. In PDF\LaTeX\ this command does nothing.
 
-	Another way is to use \csref{umiDefineMathDelimiter} to manually refresh individual Unicode characters,
+	Another way is to use \csref{umiDeclareMathDelimiter} to manually refresh individual Unicode characters,
 	this is also useful if you define an Unicode character that is not "normally" a delimiter.
 \end{function}
 
-\begin{variable}{ignore-refresh-delimiter-list}
-	Package option.
-
+\begin{option}{ignore-refresh-delimiter-list}
 	\csref{umiRefreshDelimiterList} will be run |\AtBeginDocument|. Pass this to disable it running.
 
 	Only needed if there's some package clash or if there's spurious warning on "not determined to be a delimiter" etc.
-\end{variable}
+\end{option}
 
 \begin{function}{\umiPatchCmdUnicodeArg,\umiUnpatchCmdUnicodeArg}
 	\begin{syntax}
@@ -336,12 +363,14 @@
 	The command being patched must take exactly one argument.
 
 	This is useful because some \TeX\ primitives such as |^| or |\mathopen|
-	requires either a single "character" or a group braced with |{...}| / |\bgroup...\egroup|.
+	requires either a single "character" or a group braced with |{...}| / |\bgroup...\egroup| --
+	in particular, |\Big|'s original definition is such that |\Bigl| being defined
+	as |\mathopen \Big| can work, and we must ensure it still work after the patch.
 \end{function}
 
-\begin{variable}{ignore-patch-delimiter-commands}
-	Package option. Pass this to avoid patching |\Big| etc. with the command above (only needed if there's some package clash).
-\end{variable}
+\begin{option}{ignore-patch-delimiter-commands}
+	Pass this to avoid patching |\Big| etc. with the command above (only needed if there's some package clash).
+\end{option}
 
 \begin{function}{\umiBraceNext}
 	\begin{syntax}
@@ -362,11 +391,11 @@
 then |\big⟨| will eventually execute |\oldbig{⟨}| which is the desired behavior (that |\oldbig| expects one braced argument).
 \end{function}
 
-\begin{variable}{ignore-patch-prime}
+\begin{option}{ignore-patch-prime}
 	Do not patch the default definition of |'| in math mode.
 
 	By default it's patched to allow |G'²| and |G²'| to work. Only use this when there's some package clash.
-\end{variable}
+\end{option}
 
 \begin{function}{\umiPatchPrime,\umiUnpatchPrime}
 	\begin{syntax}
@@ -384,6 +413,50 @@
 
 This package should have tested with various \TeX\ distribution versions on Overleaf.
 
+\section{Advanced remarks}
+
+As mentioned before, by design this package defines the Unicode character in math mode to do whatever the corresponding
+\LaTeX\ command does \emph{at the time of use}, so if you redefine the meaning of |\alpha|, then the Unicode character |α|
+will change as well.
+
+The other "standard" way to define commands in \LaTeX\ is to assign the mathcode to the character/control sequence directly,
+using |\DeclareMathSymbol| etc. which is used to define almost all the standard control sequences.
+For efficiency reasons or other reasons, you may want to \emph{copy} the definition of an existing control sequence
+(this way the definition of the Unicode character is not changed when the control sequence changes),
+you can do that by:
+
+\begin{function}{\umiDeclareMathCharCopy}
+	\begin{syntax}
+		|\umiDeclareMathCharCopy {±} \pm|
+	\end{syntax}
+	Does what it says.
+
+	The second argument must be a single control sequence.
+\end{function}
+
+\begin{function}{\umiDeclareMathDelimiterCopy}
+	\begin{syntax}
+		|\umiDeclareMathDelimiterCopy {‖} \Vert|
+	\end{syntax}
+	Does what it says. Refer to \csref{umiDeclareMathDelimiter} for difference between this command and \csref{umiDeclareMathCharCopy}.
+\end{function}
+
+In case you want to explicitly specify a font/slot pair for an Unicode character, you can use |\DeclareMathSymbol| etc.
+directly, then use one of the commands above to copy it to the Unicode character.
+
+Useful resources:
+
+\begin{sloppypar}
+	\hbadness=10000
+\begin{itemize}
+	\item \url{https://tex.stackexchange.com/questions/98781/create-a-font-table-for-all-available-characters-for-a-particular-font}
+	\item \url{https://tex.stackexchange.com/questions/380775/font-table-for-opentype-truetype-fonts}
+	\item \url{https://ctan.org/pkg/fonttable} (need double quotes if font name has spaces: \url{https://tex.stackexchange.com/a/506246/250119})
+	\item Although there's always |texdoc encguide| for the default (non-Unicode) encodings.
+\end{itemize}
+\end{sloppypar}
+
+
 \PrintChanges
 \PrintIndex
 \Finale

Modified: trunk/Master/texmf-dist/tex/latex/unicode-math-input/unicode-math-input-table.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/unicode-math-input/unicode-math-input-table.tex	2024-01-18 21:19:05 UTC (rev 69487)
+++ trunk/Master/texmf-dist/tex/latex/unicode-math-input/unicode-math-input-table.tex	2024-01-18 21:21:08 UTC (rev 69488)
@@ -96,12 +96,12 @@
 \__umi_define_char{£}{\mathsterling}
 \__umi_define_char{¥}{\mathyen}
 \__umi_define_char{§}{\mathsection}
-\__umi_define_char{¬}{\neg}
+\__umi_define_char{¬}{\__umi_alternatives\neg\lnot}
 \__umi_define_char{±}{\pm}
 \__umi_define_char{¶}{\mathparagraph}
-\__umi_define_char{·}{\cdotp}
+\__umi_define_char{·}{\__umi_alternatives\cdotp\centerdot}
 \__umi_define_char{×}{\times}
-\__umi_define_char{ð}{\matheth}
+\__umi_define_char{ð}{\__umi_alternatives\matheth\eth}
 \__umi_define_char{÷}{\div}
 \__umi_define_char{Ƶ}{\Zbar}
 \__umi_define_char{Α}{\__umi_alternatives_iisafe\Alpha A}
@@ -156,13 +156,13 @@
 \__umi_define_char{ϑ}{\vartheta}
 \__umi_define_char{ϕ}{\phi}
 \__umi_define_char{ϖ}{\varpi}
-\__umi_define_char{Ϝ}{\upDigamma}
-\__umi_define_char{ϝ}{\updigamma}
+\__umi_define_char{Ϝ}{\__umi_alternatives\upDigamma\Digamma}
+\__umi_define_char{ϝ}{\__umi_alternatives\updigamma\digamma}
 \__umi_define_char{ϰ}{\varkappa}
 \__umi_define_char{ϱ}{\varrho}
 \__umi_define_char{ϴ}{\varTheta}
 \__umi_define_char{ϵ}{\epsilon}
-\__umi_define_char{϶}{\upbackepsilon}
+\__umi_define_char{϶}{\__umi_alternatives\upbackepsilon\backepsilon}
 \__umi_define_char{‐}{\mathhyphen}
 \__umi_define_char{―}{\horizbar}
 \__umi_define_char_maybe_delimiter{‖}{\Vert}
@@ -169,9 +169,9 @@
 \__umi_define_char{‗}{\twolowline}
 \__umi_define_char{†}{\dagger}
 \__umi_define_char{‡}{\ddagger}
-\__umi_define_char{•}{\smblkcircle}
+\__umi_define_char{•}{\__umi_alternatives_m{\smblkcircle\bullet\vysmblkcircle}}
 \__umi_define_char{‥}{\enleadertwodots}
-\__umi_define_char{…}{\unicodeellipsis}
+\__umi_define_char{…}{\__umi_alternatives\unicodeellipsis\ldots}
 \__umi_define_char{‸}{\caretinsert}
 \__umi_define_char{‼}{\Exclam}
 \__umi_define_char{⁀}{\tieconcat}
@@ -191,7 +191,7 @@
 \__umi_define_char{ℌ}{\umiMathfrak{H}}
 \__umi_define_char{ℍ}{\umiMathbb{H}}
 \__umi_define_char{ℎ}{\Planckconst}
-\__umi_define_char{ℏ}{\hslash}
+\__umi_define_char{ℏ}{\__umi_alternatives\hslash\hbar}
 \__umi_define_char{ℐ}{\umiMathscr{I}}
 \__umi_define_char{ℑ}{\Im}
 \__umi_define_char{ℒ}{\umiMathscr{L}}
@@ -236,9 +236,9 @@
 \__umi_define_char{ⅉ}{\umiMathbbit{j}}
 \__umi_define_char{⅊}{\PropertyLine}
 \__umi_define_char{⅋}{\upand}
-\__umi_define_char{←}{\leftarrow}
+\__umi_define_char{←}{\__umi_alternatives\leftarrow\gets}
 \__umi_define_char_maybe_delimiter{↑}{\uparrow}
-\__umi_define_char{→}{\rightarrow}
+\__umi_define_char{→}{\__umi_alternatives\rightarrow\to}
 \__umi_define_char_maybe_delimiter{↓}{\downarrow}
 \__umi_define_char{↔}{\leftrightarrow}
 \__umi_define_char_maybe_delimiter{↕}{\updownarrow}
@@ -246,7 +246,7 @@
 \__umi_define_char{↗}{\nearrow}
 \__umi_define_char{↘}{\searrow}
 \__umi_define_char{↙}{\swarrow}
-\__umi_define_char{↚}{\__umi_alternatives_not\nleftarrow\leftarrow}
+\__umi_define_char{↚}{\__umi_alternatives_not_two\nleftarrow\ngets\leftarrow\gets}
 \__umi_define_char{↛}{\__umi_alternatives_not\nrightarrow\rightarrow}
 \__umi_define_char{↜}{\leftwavearrow}
 \__umi_define_char{↝}{\rightwavearrow}
@@ -313,7 +313,7 @@
 \__umi_define_char{⇚}{\Lleftarrow}
 \__umi_define_char{⇛}{\Rrightarrow}
 \__umi_define_char{⇜}{\leftsquigarrow}
-\__umi_define_char{⇝}{\rightsquigarrow}
+\__umi_define_char{⇝}{\__umi_alternatives\rightsquigarrow\leadsto}
 \__umi_define_char_maybe_delimiter{⇞}{\nHuparrow}
 \__umi_define_char_maybe_delimiter{⇟}{\nHdownarrow}
 \__umi_define_char{⇠}{\leftdasharrow}
@@ -344,13 +344,13 @@
 \__umi_define_char{∂}{\partial}
 \__umi_define_char{∃}{\exists}
 \__umi_define_char{∄}{\__umi_alternatives_not\nexists\exists}
-\__umi_define_char{∅}{\varnothing}
+\__umi_define_char{∅}{\__umi_alternatives\varnothing\emptyset}
 \__umi_define_char{∆}{\increment}
 \__umi_define_char{∇}{\nabla}
 \__umi_define_char{∈}{\in}
 \__umi_define_char{∉}{\__umi_alternatives_not\notin\in}
 \__umi_define_char{∊}{\smallin}
-\__umi_define_char{∋}{\ni}
+\__umi_define_char{∋}{\__umi_alternatives\ni\owns}
 \__umi_define_char{∌}{\__umi_alternatives_not\nni\ni}
 \__umi_define_char{∍}{\smallni}
 \__umi_define_char{∎}{\QED}
@@ -357,14 +357,14 @@
 \__umi_define_char{∏}{\prod}
 \__umi_define_char{∐}{\coprod}
 \__umi_define_char{∑}{\sum}
-\__umi_define_char{−}{\minus}
+\__umi_define_char{−}{\__umi_alternatives\minus-}
 \__umi_define_char{∓}{\mp}
 \__umi_define_char{∔}{\dotplus}
 \__umi_define_char_maybe_delimiter{∕}{\divslash}
 \__umi_define_char{∖}{\smallsetminus}
 \__umi_define_char{∗}{\ast}
-\__umi_define_char{∘}{\vysmwhtcircle}
-\__umi_define_char{∙}{\vysmblkcircle}
+\__umi_define_char{∘}{\__umi_alternatives_m{\vysmwhtcircle\circ\smwhtcircle}}
+\__umi_define_char{∙}{\__umi_alternatives_m{\vysmblkcircle\bullet\smblkcircle}}
 \__umi_define_char{∝}{\propto}
 \__umi_define_char{∞}{\infty}
 \__umi_define_char{∟}{\rightangle}
@@ -371,12 +371,12 @@
 \__umi_define_char{∠}{\angle}
 \__umi_define_char{∡}{\measuredangle}
 \__umi_define_char{∢}{\sphericalangle}
-\__umi_define_char{∣}{\mid}
+\__umi_define_char{∣}{\__umi_alternatives\mid|}
 \__umi_define_char{∤}{\__umi_alternatives_not\nmid\mid}
 \__umi_define_char{∥}{\parallel}
 \__umi_define_char{∦}{\__umi_alternatives_not\nparallel\parallel}
-\__umi_define_char{∧}{\wedge}
-\__umi_define_char{∨}{\vee}
+\__umi_define_char{∧}{\__umi_alternatives\wedge\land}
+\__umi_define_char{∨}{\__umi_alternatives\vee\lor}
 \__umi_define_char{∩}{\cap}
 \__umi_define_char{∪}{\cup}
 \__umi_define_char{∫}{\int}
@@ -404,7 +404,7 @@
 \__umi_define_char{≁}{\__umi_alternatives_not\nsim\sim}
 \__umi_define_char{≂}{\eqsim}
 \__umi_define_char{≃}{\__umi_alternatives\simeq\sime}
-\__umi_define_char{≄}{\__umi_alternatives\nsimeq\nsime}
+\__umi_define_char{≄}{\__umi_alternatives_not_two\nsime\nsimeq\sime\simeq}
 \__umi_define_char{≅}{\cong}
 \__umi_define_char{≆}{\simneqq}
 \__umi_define_char{≇}{\__umi_alternatives_not\ncong\cong}
@@ -417,7 +417,7 @@
 \__umi_define_char{≎}{\Bumpeq}
 \__umi_define_char{≏}{\bumpeq}
 \__umi_define_char{≐}{\doteq}
-\__umi_define_char{≑}{\Doteq}
+\__umi_define_char{≑}{\__umi_alternatives\Doteq\doteqdot}
 \__umi_define_char{≒}{\fallingdotseq}
 \__umi_define_char{≓}{\risingdotseq}
 \__umi_define_char{≔}{\coloneq}
@@ -432,12 +432,12 @@
 \__umi_define_char{≝}{\eqdef}
 \__umi_define_char{≞}{\measeq}
 \__umi_define_char{≟}{\questeq}
-\__umi_define_char{≠}{\ne}
+\__umi_define_char{≠}{\__umi_alternatives\ne\neq}
 \__umi_define_char{≡}{\equiv}
 \__umi_define_char{≢}{\__umi_alternatives_not\nequiv\equiv}
 \__umi_define_char{≣}{\Equiv}
-\__umi_define_char{≤}{\leq}
-\__umi_define_char{≥}{\geq}
+\__umi_define_char{≤}{\__umi_alternatives\leq\le}
+\__umi_define_char{≥}{\__umi_alternatives\geq\ge}
 \__umi_define_char{≦}{\leqq}
 \__umi_define_char{≧}{\geqq}
 \__umi_define_char{≨}{\lneqq}
@@ -448,8 +448,8 @@
 \__umi_define_char{≭}{\__umi_alternatives_not\nasymp\asymp}
 \__umi_define_char{≮}{\__umi_alternatives_not\nless\less}
 \__umi_define_char{≯}{\ngtr}
-\__umi_define_char{≰}{\__umi_alternatives_not\nleq\leq}
-\__umi_define_char{≱}{\__umi_alternatives_not\ngeq\geq}
+\__umi_define_char{≰}{\__umi_alternatives_not_two\nleq\nle\leq\le}
+\__umi_define_char{≱}{\__umi_alternatives_not_two\ngeq\nge\geq\ge}
 \__umi_define_char{≲}{\lesssim}
 \__umi_define_char{≳}{\gtrsim}
 \__umi_define_char{≴}{\__umi_alternatives_not\nlesssim\lesssim}
@@ -532,7 +532,7 @@
 \__umi_define_char{⋁}{\bigvee}
 \__umi_define_char{⋂}{\bigcap}
 \__umi_define_char{⋃}{\bigcup}
-\__umi_define_char{⋄}{\smwhtdiamond}
+\__umi_define_char{⋄}{\__umi_alternatives\smwhtdiamond\diamond}
 \__umi_define_char{⋅}{\cdot}
 \__umi_define_char{⋆}{\star}
 \__umi_define_char{⋇}{\divideontimes}
@@ -546,14 +546,14 @@
 \__umi_define_char{⋏}{\curlywedge}
 \__umi_define_char{⋐}{\Subset}
 \__umi_define_char{⋑}{\Supset}
-\__umi_define_char{⋒}{\Cap}
-\__umi_define_char{⋓}{\Cup}
+\__umi_define_char{⋒}{\__umi_alternatives\Cap\doublecap}
+\__umi_define_char{⋓}{\__umi_alternatives\Cup\doublecup}
 \__umi_define_char{⋔}{\pitchfork}
 \__umi_define_char{⋕}{\equalparallel}
 \__umi_define_char{⋖}{\lessdot}
 \__umi_define_char{⋗}{\gtrdot}
-\__umi_define_char{⋘}{\lll}
-\__umi_define_char{⋙}{\ggg}
+\__umi_define_char{⋘}{\__umi_alternatives\lll\llless}
+\__umi_define_char{⋙}{\__umi_alternatives\ggg\gggtr}
 \__umi_define_char{⋚}{\lesseqgtr}
 \__umi_define_char{⋛}{\gtreqless}
 \__umi_define_char{⋜}{\eqless}
@@ -575,8 +575,8 @@
 \__umi_define_char{⋬}{\__umi_alternatives_not\ntrianglelefteq\trianglelefteq}
 \__umi_define_char{⋭}{\__umi_alternatives_not\ntrianglerighteq\trianglerighteq}
 \__umi_define_char{⋮}{\vdots}
-\__umi_define_char{⋯}{\unicodecdots}
-\__umi_define_char{⋰}{\__umi_alternatives\iddots\adots}
+\__umi_define_char{⋯}{\__umi_alternatives\unicodecdots\cdots}
+\__umi_define_char{⋰}{\__umi_alternatives\adots\iddots}
 \__umi_define_char{⋱}{\ddots}
 \__umi_define_char{⋲}{\disin}
 \__umi_define_char{⋳}{\varisins}
@@ -673,8 +673,8 @@
 \__umi_define_char{░}{\blockqtrshaded}
 \__umi_define_char{▒}{\blockhalfshaded}
 \__umi_define_char{▓}{\blockthreeqtrshaded}
-\__umi_define_char{■}{\mdlgblksquare}
-\__umi_define_char{□}{\mdlgwhtsquare}
+\__umi_define_char{■}{\__umi_alternatives\mdlgblksquare\blacksquare}
+\__umi_define_char{□}{\__umi_alternatives_m{\mdlgwhtsquare\Box\square}}
 \__umi_define_char{▢}{\squoval}
 \__umi_define_char{▣}{\blackinwhitesquare}
 \__umi_define_char{▤}{\squarehfill}
@@ -692,7 +692,7 @@
 \__umi_define_char{▰}{\parallelogramblack}
 \__umi_define_char{▱}{\parallelogram}
 \__umi_define_char{▲}{\bigblacktriangleup}
-\__umi_define_char{△}{\bigtriangleup}
+\__umi_define_char{△}{\__umi_alternatives_m{\bigtriangleup\triangle\varbigtriangleup}}
 \__umi_define_char{▴}{\blacktriangle}
 \__umi_define_char{▵}{\vartriangle}
 \__umi_define_char{▶}{\blacktriangleright}
@@ -702,7 +702,7 @@
 \__umi_define_char{►}{\blackpointerright}
 \__umi_define_char{▻}{\whitepointerright}
 \__umi_define_char{▼}{\bigblacktriangledown}
-\__umi_define_char{▽}{\bigtriangledown}
+\__umi_define_char{▽}{\__umi_alternatives\bigtriangledown\varbigtriangledown}
 \__umi_define_char{▾}{\blacktriangledown}
 \__umi_define_char{▿}{\triangledown}
 \__umi_define_char{◀}{\blacktriangleleft}
@@ -715,8 +715,8 @@
 \__umi_define_char{◇}{\mdlgwhtdiamond}
 \__umi_define_char{◈}{\blackinwhitediamond}
 \__umi_define_char{◉}{\fisheye}
-\__umi_define_char{◊}{\mdlgwhtlozenge}
-\__umi_define_char{○}{\mdlgwhtcircle}
+\__umi_define_char{◊}{\__umi_alternatives_m{\mdlgwhtlozenge\Diamond\lozenge}}
+\__umi_define_char{○}{\__umi_alternatives\mdlgwhtcircle\bigcirc}
 \__umi_define_char{◌}{\dottedcircle}
 \__umi_define_char{◍}{\circlevertfill}
 \__umi_define_char{◎}{\bullseye}
@@ -743,7 +743,7 @@
 \__umi_define_char{◣}{\llblacktriangle}
 \__umi_define_char{◤}{\ulblacktriangle}
 \__umi_define_char{◥}{\urblacktriangle}
-\__umi_define_char{◦}{\smwhtcircle}
+\__umi_define_char{◦}{\__umi_alternatives_m{\smwhtcircle\circ\vysmwhtcircle}}
 \__umi_define_char{◧}{\squareleftblack}
 \__umi_define_char{◨}{\squarerightblack}
 \__umi_define_char{◩}{\squareulblack}
@@ -889,9 +889,9 @@
 \__umi_define_char{⤋}{\Ddownarrow}
 \__umi_define_char{⤌}{\leftbkarrow}
 \__umi_define_char{⤍}{\rightbkarrow}
-\__umi_define_char{⤎}{\leftdbkarrow}
-\__umi_define_char{⤏}{\dbkarrow}
-\__umi_define_char{⤐}{\drbkarrow}
+\__umi_define_char{⤎}{\__umi_alternatives\leftdbkarrow\dashleftarrow}
+\__umi_define_char{⤏}{\__umi_alternatives_m{\dbkarrow\dasharrow\dashrightarrow\dbkarow}}
+\__umi_define_char{⤐}{\__umi_alternatives\drbkarrow\drbkarow}
 \__umi_define_char{⤑}{\rightdotarrow}
 \__umi_define_char{⤒}{\baruparrow}
 \__umi_define_char{⤓}{\downarrowbar}
@@ -912,8 +912,8 @@
 \__umi_define_char{⤢}{\neswarrow}
 \__umi_define_char{⤣}{\hknwarrow}
 \__umi_define_char{⤤}{\hknearrow}
-\__umi_define_char{⤥}{\hksearrow}
-\__umi_define_char{⤦}{\hkswarrow}
+\__umi_define_char{⤥}{\__umi_alternatives\hksearrow\hksearow}
+\__umi_define_char{⤦}{\__umi_alternatives\hkswarrow\hkswarow}
 \__umi_define_char{⤧}{\tona}
 \__umi_define_char{⤨}{\toea}
 \__umi_define_char{⤩}{\tosa}
@@ -1351,7 +1351,7 @@
 \__umi_define_char{⫙}{\forkv}
 \__umi_define_char{⫚}{\topfork}
 \__umi_define_char{⫛}{\mlcp}
-\__umi_define_char{⫝̸}{\forks}
+\__umi_define_char{⫝̸}{\__umi_alternatives\forks\nforksnot}
 \__umi_define_char{⫝}{\forksnot}
 \__umi_define_char{⫞}{\shortlefttack}
 \__umi_define_char{⫟}{\shortdowntack}

Modified: trunk/Master/texmf-dist/tex/latex/unicode-math-input/unicode-math-input.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/unicode-math-input/unicode-math-input.sty	2024-01-18 21:19:05 UTC (rev 69487)
+++ trunk/Master/texmf-dist/tex/latex/unicode-math-input/unicode-math-input.sty	2024-01-18 21:21:08 UTC (rev 69488)
@@ -1,5 +1,5 @@
 % File: unicode-math-input.sty
-% Copyright 2022-2023 user202729
+% Copyright 2022-2024 user202729
 %
 % This work  may be  distributed and/or  modified under  the conditions  of the
 % LaTeX Project Public License (LPPL),  either version 1.3c  of this license or
@@ -14,7 +14,7 @@
 
 \RequirePackage{expl3}
 \RequirePackage{iftex}
-\ProvidesExplPackage{unicode-math-input}{2023-05-12}{0.0.0}{Allow entering Unicode symbols in math formulas}
+\ProvidesExplPackage{unicode-math-input}{2024-01-18}{0.1.0}{Allow entering Unicode symbols in math formulas}
 
 \makeatletter
 \AtBeginDocument{
@@ -38,7 +38,17 @@
 \cs_new_protected:Npn \umiMathbf    {\__umi_check_math_alphabet \mathbf     \umiMathbf     }
 \cs_new_protected:Npn \umiMathit    {\__umi_check_math_alphabet \mathit     \umiMathit     }
 \cs_new_protected:Npn \umiMathbfit  {\__umi_check_math_alphabet \bm         \umiMathbfit   }
-\cs_new_protected:Npn \umiMathscr   {\__umi_check_math_alphabet \mathscr    \umiMathscr    }
+\cs_new_protected:Npn \umiMathscr   {
+	\ifdefined \mathscr
+		\expandafter \mathscr
+	\else
+		\ifdefined \mathcal
+			\expandafter \expandafter \expandafter \mathcal
+		\else
+			\msg_error:nnnn {unicode-math-input} {define-math-alphabet} {\mathscr/\mathcal} {\umiMathscr}
+		\fi
+	\fi
+}
 \cs_new_protected:Npn \umiMathbfscr {\__umi_check_math_alphabet \mathbfscr  \umiMathbfscr  }
 \cs_new_protected:Npn \umiMathfrak  {\__umi_check_math_alphabet \mathfrak   \umiMathfrak   }
 \cs_new_protected:Npn \umiMathbb    {\__umi_check_math_alphabet \mathbb     \umiMathbb     }
@@ -79,11 +89,23 @@
 		\ifdefined #2
 			#2
 		\else
-			\msg_error:nnn {unicode-math-input} {undefined-cs} {#1#2}
+			\__umi_raise_error {#1#2}
 		\fi
 	\fi
 }
 
+\cs_new_protected:Npn \__umi_alternatives_m #1 {
+	\tl_map_inline:nn {#1} {
+		\ifdefined ##1
+			##1
+			\tl_map_break:n {\use_none:nn}
+		\fi
+	}
+	\__umi_raise_error {#1}
+}
+
+\cs_new_protected:Npn \__umi_raise_error { \msg_error:nnn {unicode-math-input} {undefined-cs} }
+
 % #1 is control sequence, #2 is anything (must not peek ahead!)
 \cs_new_protected:Npn \__umi_alternatives_iisafe #1 #2 {
 	\ifdefined #1
@@ -107,6 +129,16 @@
 	\fi
 }
 
+\cs_new_protected:Npn \__umi_alternatives_not_two #1 #2 #3 #4{
+	\ifdefined #1   #1       \else
+	\ifdefined #2   #2       \else
+	\ifdefined #3   \not#3   \else
+	\ifdefined #4   \not#4   \else
+		\msg_error:nnn {unicode-math-input} {undefined-cs} {#1#2#3#4}
+	\fi \fi \fi \fi
+}
+
+
 % ======== \__umi_require_math
 \msg_new:nnn {unicode-math-input} {not-math-mode} {
 	This~symbol~can~only~be~used~in~math~mode!
@@ -213,8 +245,8 @@
 	}
 
 
-	\cs_new_eq:NN \umiDefineMathChar \__umi_define_char_single
-	\cs_new_protected:Npn \umiDefineMathDelimiter #1 #2 {
+	\cs_new_eq:NN \umiDeclareMathChar \__umi_define_char_single
+	\cs_new_protected:Npn \umiDeclareMathDelimiter #1 #2 {
 		\cs_new_protected:Npn \__umi_check_delimiter_defined_not_delimiter ##1 ##2 {
 			\msg_error:nnnn {unicode-math-input} {not-delimiter} {##1} {##2}
 		}
@@ -278,7 +310,7 @@
 
 	\cs_new_eq:NN \__umi_define_char_maybe_delimiter \__umi_define_char
 
-	\cs_new_protected:Npn \umiDefineMathChar #1 #2{
+	\cs_new_protected:Npn \umiDeclareMathChar #1 #2{
 		\ifnum \str_count:n{#1}=1
 			\__umi_define_char_single #1 {#2}
 		\else
@@ -285,9 +317,16 @@
 			\cs_gset_protected:cpx {u8:\detokenize{#1}} {\unexpanded{\__umi_require_math #2}}
 		\fi
 	}
-	\cs_new_eq:NN \umiDefineMathDelimiter \umiDefineMathChar
+	\cs_new_eq:NN \umiDeclareMathDelimiter \umiDeclareMathChar
 }
 
+
+\cs_new_eq:NN \umiDefineMathChar \umiDeclareMathChar
+\cs_new_eq:NN \umiDefineMathDelimiter \umiDeclareMathDelimiter  % backwards compatibility
+
+\cs_new_protected:Npn \umiDeclareMathCharCopy { \__umi_internal_error }
+\cs_new_protected:Npn \umiDeclareMathDelimiterCopy { \__umi_internal_error }
+
 \__umi_if_engine_unicode {
 	\tl_build_begin:N \__umi_delimiter_list
 } {}
@@ -451,8 +490,9 @@
 		\expandafter \__umi_continue_script_aux \exp:w\exp_end_continue_f:w
 		\char_generate:nn {\expandafter \__umi_gobble_the_character \meaning #1} {13}
 	} {
-		\cs_gset_eq:NN \__umi_script \__umi_put_script_normal
-		^{\l_tmpa_tl} #1
+		% is not the case, finished (put back the #1)
+		\__umi_script_collect_done
+		\__umi_script_cat{\l_tmpa_tl} #1
 	}
 }
 
@@ -492,12 +532,13 @@
 	}
 
 	\def \__umi_brace_error             {\__umi_internal_error \l_tmpa_tl}
+	\def \__umi_brace_nobrace           {\l_tmpa_tl}
 	\def \__umi_brace_two   #1 #2       {\l_tmpa_tl {#1 #2}}
 	\def \__umi_brace_three #1 #2 #3    {\l_tmpa_tl {#1 #2 #3}}
 	\def \__umi_brace_four  #1 #2 #3 #4 {\l_tmpa_tl {#1 #2 #3 #4}}
 
 	\int_step_inline:nnn {"00} {"7F} {
-		\expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \relax
+		\expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_nobrace
 	}
 	\int_step_inline:nnn {"80} {"BF} {
 		\expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_error

Modified: trunk/Master/tlpkg/libexec/ctan2tds
===================================================================
--- trunk/Master/tlpkg/libexec/ctan2tds	2024-01-18 21:19:05 UTC (rev 69487)
+++ trunk/Master/tlpkg/libexec/ctan2tds	2024-01-18 21:21:08 UTC (rev 69488)
@@ -2556,7 +2556,7 @@
  'underscore',  '^..[^s].*\.sty',       # not miscdoc.sty
  'undolabl',    '\.sty|[^c]\.cfg',      # omit ltxdoc.cfg, would be system-wide
  'unicode-alphabets',	'\..sv|' . $standardtex,
- 'unicode-math-input',	'\.sty',	# not .py
+ 'unicode-math-input',	'\.sty|unicode-math-input-table\.tex',	# not .py
  'unicodefonttable',	'(\.sty|unicodefont.tex)$',	# not .cls
  'unimath-plain-xetex',	'unimath-plain-xetex\.tex',
  'uninormalize',	'\.lua|' . $standardtex,



More information about the tex-live-commits mailing list.