%% hangulmath.sty %% Hangul jamo as math symbols. %% %% Copyright (C) 2026 Inkyu Park %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either version 1.3c %% of this license or (at your option) any later version. %% The latest version of this license is in %% https://www.latex-project.org/lppl.txt %% and version 1.3c or later is part of all distributions of LaTeX %% version 2008 or later. %% %% This work has the LPPL maintenance status `maintained'. %% The Current Maintainer of this work is Inkyu Park. %% %% This work consists of the files hangulmath.sty, %% hangulmath-metrics.def, hangulmath-metrics.py and %% hangulmath-doc.tex. The fonts hangulmath-sans.otf and %% hangulmath-sans-light.otf are distributed under the SIL Open Font %% License 1.1 (see OFL.txt). %% \NeedsTeXFormat{LaTeX2e}[2022/06/01] \ProvidesPackage{hangulmath}[2026/10/10 v0.5 Hangul jamo as math symbols] \RequirePackage{iftex} \RequireTUTeX \RequirePackage{fontspec} \RequirePackage{amstext}% \text: scales correctly in sub/superscripts \RequirePackage{graphicx}% \scalebox for operator forms % --------------------------------------------------------------- % Options % font = symbol font % (default: bundled hangulmath-sans.otf) % opfont = font for large operators % (default: bundled hangulmath-sans-light.otf) % metrics = glyph metrics (.def), made by % hangulmath-metrics.py; required for non-default fonts % scale = (default: from metrics file) % sidebearing = space left/right of each glyph % --------------------------------------------------------------- \def\hm@bundledfont{hangulmath-sans.otf} \def\hm@bundledopfont{hangulmath-sans-light.otf} \def\hm@fontname{\hm@bundledfont} \def\hm@opfontname{\hm@bundledopfont} \def\hm@metricsfile{hangulmath-metrics} \def\hm@scale{} \def\hm@sb{0.06} \DeclareKeys[hangulmath]{ font.store = \hm@fontname, opfont.store = \hm@opfontname, metrics.store = \hm@metricsfile, scale.store = \hm@scale, sidebearing.store = \hm@sb, } \ProcessKeyOptions[hangulmath] % --------------------------------------------------------------- % Glyph metrics % \hm@metric{}{}{} (in em) % Missing metrics -> glyph is used with the font's own spacing. % --------------------------------------------------------------- \def\hm@baseshift{0} \def\hm@defaultscale{1} \newcommand\hm@metric[3]{% \@namedef{hm@L@#1}{#2}\@namedef{hm@R@#1}{#3}} \newcommand\hm@get[2]{% \ifcsname hm@#1@#2\endcsname\@nameuse{hm@#1@#2}\else 0\fi} \InputIfFileExists{\hm@metricsfile.def}{}{% \PackageWarningNoLine{hangulmath}{% Metrics file `\hm@metricsfile.def' not found.\MessageBreak Glyphs are not trimmed or aligned to the baseline.\MessageBreak Run hangulmath-metrics.py for your font}} \ifx\hm@scale\@empty \let\hm@scale\hm@defaultscale \fi % --------------------------------------------------------------- % Fonts % A requested font that is not installed falls back to the % bundled font with a warning, so documents always compile. % --------------------------------------------------------------- \newcommand\hm@loadfont[3]{% #1 family cs, #2 requested, #3 bundled \edef\hm@tmp{#2}% \IfFontExistsTF{\hm@tmp}{}{% \PackageWarningNoLine{hangulmath}{% Font `\hm@tmp' not found;\MessageBreak using bundled `#3'}% \def\hm@tmp{#3}}% \expandafter\setfontfamily\expandafter#1\expandafter{\hm@tmp}[Scale=\hm@scale]} \newcommand\hangulmathfont[1]{\hm@loadfont\hm@font{#1}{\hm@bundledfont}} \newcommand\hangulmathopfont[1]{\hm@loadfont\hm@opfont{#1}{\hm@bundledopfont}} \hangulmathfont{\hm@fontname} \hangulmathopfont{\hm@opfontname} \let\hm@curfont\hm@font % --------------------------------------------------------------- % Core symbol builder % - trims side bearings to the ink, adds \hm@sb on each side % - lowers by \hm@baseshift so consonants sit on the baseline % - always upright; \ensuremath allows use in running text % --------------------------------------------------------------- \newcommand\hm@sym[1]{% \ensuremath{\mathord{\text{\normalfont\hm@curfont \lower\hm@baseshift em\hbox{% \kern\dimexpr\hm@sb em-\hm@get{L}{#1}em\relax \symbol{"#1}% \kern\dimexpr\hm@sb em-\hm@get{R}{#1}em\relax}}}}} % \hm@define{}{}{} % \newcommand raises an error if a name is already taken. \newcommand\hm@define[3]{% \expandafter\newcommand\csname #1\endcsname{\hm@sym{#3}}% \if\relax\detokenize{#2}\relax\else \expandafter\newcommand\csname #2\endcsname{\hm@sym{#3}}% \fi} % --------------------------------------------------------------- % Consonants (official RR name, 4-letter alias, Unicode) % --------------------------------------------------------------- \hm@define{giyeok}{giug}{3131}% ㄱ \hm@define{nieun} {niun}{3134}% ㄴ \hm@define{digeut}{diud}{3137}% ㄷ \hm@define{rieul} {liul}{3139}% ㄹ \hm@define{mieum} {mium}{3141}% ㅁ \hm@define{bieup} {biub}{3142}% ㅂ \hm@define{siot} {sius}{3145}% ㅅ \hm@define{ieung} {iung}{3147}% ㅇ \hm@define{jieut} {jiuj}{3148}% ㅈ \hm@define{chieut}{ciuc}{314A}% ㅊ \hm@define{kieuk} {kiuk}{314B}% ㅋ \hm@define{tieut} {tiut}{314C}% ㅌ \hm@define{pieup} {piup}{314D}% ㅍ \hm@define{hieut} {hiuh}{314E}% ㅎ % --------------------------------------------------------------- % Vowels (sound + trailing h) % --------------------------------------------------------------- \hm@define{ah} {}{314F}% ㅏ \hm@define{yah} {}{3151}% ㅑ \hm@define{eoh} {}{3153}% ㅓ \hm@define{yeoh}{}{3155}% ㅕ \hm@define{oh} {}{3157}% ㅗ \hm@define{yoh} {}{315B}% ㅛ \hm@define{uh} {}{315C}% ㅜ \hm@define{yuh} {}{3160}% ㅠ \hm@define{euh} {}{3161}% ㅡ \hm@define{ih} {}{3163}% ㅣ % --------------------------------------------------------------- % Double consonants (official name, alias = first letter doubled) % --------------------------------------------------------------- \hm@define{ssanggiyeok}{ggiug}{3132}% ㄲ \hm@define{ssangdigeut}{ddiud}{3138}% ㄸ \hm@define{ssangbieup} {bbiub}{3143}% ㅃ \hm@define{ssangsiot} {ssius}{3146}% ㅆ \hm@define{ssangjieut} {jjiuj}{3149}% ㅉ % --------------------------------------------------------------- % Compound vowels (sound + trailing h; glide w written as u) % --------------------------------------------------------------- \hm@define{aeh} {}{3150}% ㅐ \hm@define{yaeh}{}{3152}% ㅒ \hm@define{eh} {}{3154}% ㅔ \hm@define{yeh} {}{3156}% ㅖ \hm@define{uah} {}{3158}% ㅘ \hm@define{uaeh}{}{3159}% ㅙ \hm@define{oeh} {}{315A}% ㅚ \hm@define{ueoh}{}{315D}% ㅝ \hm@define{ueh} {}{315E}% ㅞ \hm@define{uih} {}{315F}% ㅟ \hm@define{euih}{}{3162}% ㅢ % --------------------------------------------------------------- % Operator forms (work with any symbol, e.g. \hangulsum\tiut) % \hangulsum{} large, limits below/above in display (like \sum) % \hangulint{} large, limits at the side (like \int) % \hangullim{} normal size, limits below in display (like \lim) % Large forms use the lighter operator font so that scaling up % does not make the strokes too heavy. % Sizes: \hangulopscale{}{} % --------------------------------------------------------------- \newcommand\hm@opdisplay{2.0} \newcommand\hm@optext{1.3} \newcommand\hangulopscale[2]{% \renewcommand\hm@opdisplay{#1}\renewcommand\hm@optext{#2}} \newcommand\hm@opbox[2]{% #1 scale, #2 symbol \vcenter{\hbox{\let\hm@curfont\hm@opfont \scalebox{#1}{$\m@th#2$}}}} \newcommand\hm@bigop[1]{\mathop{\mathchoice {\hm@opbox{\hm@opdisplay}{#1}} {\hm@opbox{\hm@optext}{#1}} {\vcenter{\hbox{$\m@th\scriptstyle#1$}}} {\vcenter{\hbox{$\m@th\scriptscriptstyle#1$}}}}} \newcommand\hangulsum[1]{\hm@bigop{#1}\displaylimits} \newcommand\hangulint[1]{\hm@bigop{#1}\nolimits} \newcommand\hangullim[1]{\mathop{#1}\displaylimits} \endinput