Towards a \ucshape and \textuc command for uppercase text (XeTeX, LuaTeX)
A full implementation in LuaTeX:
\documentclass{article}
\usepackage{fontspec}
\usepackage{xcolor}
\usepackage{luacode}
\usepackage{luatexbase}
\usepackage{luatexbase-attr}
\newluatexattribute\uppercaseattr
\begin{luacode*}
local ucattr = luatexbase.attributes.uppercaseattr
local GLYPH = node.id("glyph")
local function makeuppercase(head)
local orighead = head
local string = unicode.utf8
while head do
if head.id == GLYPH then
local att = node.has_attribute(head,ucattr)
if att then
if head.char == 223 then -- ß
-- insert two 'S' glyphs
head.char = 83
orighead = node.insert_before(orighead,head,node.copy(head))
elseif head.char == 64258 then -- fl
head.char = 70 -- F
orighead = node.insert_before(orighead,head,node.copy(head))
head.char = 76 -- L
elseif head.char == 64256 then -- ff
head.char = 70 -- F
orighead = node.insert_before(orighead,head,node.copy(head))
head.char = 70 -- F
elseif head.char == 64257 then -- fi
head.char = 70 -- F
orighead = node.insert_before(orighead,head,node.copy(head))
head.char = 73 -- I
elseif head.char == 64259 then -- ffi
head.char = 70 -- F
orighead = node.insert_before(orighead,head,node.copy(head))
head.char = 70 -- F
orighead = node.insert_before(orighead,head,node.copy(head))
head.char = 73 -- I
elseif head.char == 64260 then -- ffl
head.char = 70 -- F
orighead = node.insert_before(orighead,head,node.copy(head))
head.char = 70 -- F
orighead = node.insert_before(orighead,head,node.copy(head))
head.char = 76 -- L
else
head.char = string.byte(string.upper(string.char(head.char)))
end
end
end
head = head.next
end
return orighead
end
function makeuppercase_hbox(head,groupcode)
local orighead = head
if groupcode == "adjusted_hbox" or groupcode == "hbox" then
makeuppercase(head)
end
return orighead
end
luatexbase.add_to_callback("hpack_filter",makeuppercase_hbox,"makeuppercasehbox")
luatexbase.add_to_callback("pre_linebreak_filter",makeuppercase,"makeuppercase")
\end{luacode*}
\newcommand*\ucshape{\uppercaseattr=1}
\DeclareTextFontCommand{\textuc}{\ucshape}
\begin{document}
\hsize 7.2cm
\newcommand\sample{Draußen \i \ij\ ffl fluffiest fish \textit{König} \textcolor{blue}{àéîàáâãäåæ} çèéêëìíîï ff \hbox{ðñòóôõö} ùúûüýþÿœš}
Lowercase {\ucshape \sample} Lowercase
Lowercase \textuc{\sample} Lowercase
% textcolor doesn't work in LaTeX's \MakeUppercase
% Lowercase \MakeUppercase{\sample} Lowercase
\end{document}
which yields
The program above just manipulates the nodelist iff the given attribute is set (to any value). Attributes are grouped, just like any TeX assignment.
It's a bit more complicated than I thought because we need to treat \hbox{}
es separately.