\documentclass{article} \PassOptionsToPackage{log-declarations=false}{xparse} \PassOptionsToPackage{no-math}{fontspec} \PassOptionsToPackage{table}{xcolor} \PassOptionsToPackage{titles}{tocloft} %\PassOptionsToPackage{showframe}{geometry} \usepackage{% expl3,xparse, ctexheading,geometry,fancyhdr,tocloft,fontspec,xcolor,hologo, array,longtable,multirow,hhline, hyperref,zref-totpages} \makeatletter\ExplSyntaxOn \seq_const_from_clist:Nn \c_@@_unicode_reserved_seq { % Greek and Coptic 378, 379, 380, 381, 382, 383, 38B, 38D, 3A2, % General Punctuation 2065, % Superscripts and Subscripts 2072, 2073, 208F, 209D, 209E, 209F, % Currency Symbols 20C0, 20C1, 20C2, 20C3, 20C4, 20C5, 20C6, 20C7, 20C8, 20C9, 20CA, 20CB, 20CC, 20CD, 20CE, 20CF, % Combining Diacritical Marks for Symbols 20F1, 20F2, 20F3, 20F4, 20F5, 20F6, 20F7, 20F8, 20F9, 20FA, 20FB, 20FC, 20FD, 20FE, 20FF, % Number Forms 218C, 218D, 218E, 218F, % Control Pictures 2427, 2428, 2429, 242A, 242B, 242C, 242D, 242E, 242F, 2430, 2431, 2432, 2433, 2434, 2435, 2436, 2437, 2438, 2439, 243A, 243B, 243C, 243D, 243E, 243F, % Optical Character Recognition 244B, 244C, 244D, 244E, 244F, 2450, 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458, 2459, 245A, 245B, 245C, 245D, 245E, 245F, % Miscellaneous Symbols and Arrows 2B74, 2B75, 2B96, % Alphabetic Presentation Forms FB07, FB08, FB09, FB0A, FB0B, FB0C, FB0D, FB0E, FB0F, FB10, FB11, FB12, FB18, FB19, FB1A, FB1B, FB1C, FB37, FB3D, FB3F, FB42, FB45, % Arabic Presentation Forms-B FE75, FEFD, FEFE, % Mathematical Alphanumeric Symbols 1D455, 1D49D, 1D4A0, 1D4A1, 1D4A3, 1D4A4, 1D4A7, 1D4A8, 1D4AD, 1D4BA, 1D4BC, 1D4C4, 1D506, 1D50B, 1D50C, 1D515, 1D51D, 1D53A, 1D53F, 1D545, 1D547, 1D548, 1D549, 1D551, 1D6A6, 1D6A7, 1D7CC, 1D7CD, % Geometric Shapes Extended 1F7D9, 1F7DA, 1F7DB, 1F7DC, 1F7DD, 1F7DE, 1F7DF, 1F7EC, 1F7ED, 1F7EE, 1F7EF, 1F7F0, 1F7F1, 1F7F2, 1F7F3, 1F7F4, 1F7F5, 1F7F6, 1F7F7, 1F7F8, 1F7F9, 1F7FA, 1F7FB, 1F7FC, 1F7FD, 1F7FE, 1F7FF, } \seq_const_from_clist:Nn \c_@@_unicode_control_seq { % C0 Controls and Basic Latin 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 1C, 1D, 1E, 1F, 7F, % C1 Controls and Latin-1 Supplement 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 8A, 8B, 8C, 8D, 8E, 8F, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 9A, 9B, 9C, 9D, 9E, 9F } % Require `\c_@@_glyph_non_unicode_with_type_seq` \file_input:n { firamath-glyph-list.tex } % #1 = symbol index \cs_new_protected:Npn \@@_symbol:n #1 { \tex_char:D \int_eval:n {#1} \scan_stop: } \prg_new_protected_conditional:Npnn \@@_if_char_exist:n #1 { T, F, TF } { \tex_iffontchar:D \tex_font:D \int_eval:n {#1} \scan_stop: \prg_return_true: \else: \prg_return_false: \fi: } % #1 = glyph name % See https://tex.stackexchange.com/q/420167 \cs_new_protected:Npn \@@_glyph_from_name:n #1 { \tex_XeTeXglyph:D \tex_XeTeXglyphindex:D "#1" \scan_stop: } % Centering with fixed width \newcolumntype {C} [1] { > { \centering \arraybackslash } m {#1} } % Empty array rule \newcolumntype {E} { ! { \skip_horizontal:N \arrayrulewidth } } \definecolor { encoding @ bg } { HTML } { BDBDBD } \definecolor { reserved @ bg } { HTML } { EA4335 } \definecolor { control @ bg } { HTML } { 4285F4 } \definecolor { nochar @ text } { HTML } { E0E0E0 } \cs_set:Npn \NumberStyle { \ttfamily \footnotesize } \cs_set:Npn \GlyphStyle { \SymbolFont \Large } \cs_set:Npn \EncodingStyle { \ttfamily \fontsize { 4 } { 5 } \selectfont \cellcolor { encoding@bg } } \cs_set:Npn \GlyphStrut { \@@_set_arstrut:nn { 20 pt } { 10 pt } } \cs_set:Npn \NonUnicodeGlyphStrut { \@@_set_arstrut:nn { 32 pt } { 20 pt } } \cs_set:Npn \NonUnicodeHighGlyphStrut { \@@_set_arstrut:nn { 64 pt } { 40 pt } } \cs_set:Npn \EncodingStrut { \@@_set_arstrut:nn { 4.5 pt } { 1 pt } } \dim_const:Nn \c_@@_cell_wd_dim { 30 pt } \dim_const:Nn \c_@@_column_sep_dim { 0 pt } \dim_const:Nn \c_@@_row_number_ht_dim { 20 pt } \dim_const:Nn \c_@@_row_number_sep_dim { 6 pt } \dim_const:Nn \c_@@_non_unicode_wd_dim { 87 pt } % The total number of glyphs. \newcounter { glyph } \setcounter { glyph } { -1 } % The main function. \NewDocumentCommand \fonttable { s m g } { \IfBooleanTF {#1} { \@@_non_unicode:nn {#2} } { \@@_unicode:nn {#2} {#3} } \clearpage } % #1 = section name % #2 = begin/end encoding \cs_new_protected:Npn \@@_unicode:nn #1#2 { \tl_set:Nn \l_@@_glyph_count_tl { \ref* { count: glyph @ #1 } / \ref* { count: codepoint @ #1 } } \section { #1 ~ (\tl_use:N \l_@@_glyph_count_tl) } \cs_set_eq:NN \@@_left_foot: \@@_left_foot_unicode: \@@_parse_encoding:n {#2} \int_gzero:N \g_@@_glyph_int \int_gzero:N \g_@@_code_point_int \@@_make_table: \newcounter { glyph @ #1 } \newcounter { codepoint @ #1 } \int_set:cn { c @ glyph @ #1 } { \g_@@_glyph_int - 1 } \int_set:cn { c @ codepoint @ #1 } { \g_@@_code_point_int - 1 } \refstepcounter { glyph @ #1 } \label { count: glyph @ #1 } \refstepcounter { codepoint @ #1 } \label { count: codepoint @ #1 } } \tl_new:N \l_@@_glyph_count_tl \int_new:N \g_@@_glyph_int \int_new:N \g_@@_code_point_int \cs_new_protected:Npn \@@_left_foot_unicode: { \mode_leave_vertical: \footnotesize \@@_color_box:nn { reserved @ bg } Reserved~ Code~ Points, \quad \@@_color_box:nn { control @ bg } Control~ Codes. } \cs_new_protected:Npn \@@_color_box:nn #1#2 { \group_begin: \color {#1} \rule [ -2 pt ] { 10 pt } { 10 pt } \group_end: \ = \ #2 } % #1 = `begin` - `end` \cs_new_protected:Npn \@@_parse_encoding:n #1 { \seq_set_split:Nnn \l_tmpa_seq { - } {#1} \int_set:Nn \l_@@_begin_int { \seq_item:Nn \l_tmpa_seq { 1 } } \int_set:Nn \l_@@_end_int { \seq_item:Nn \l_tmpa_seq { 2 } } } \int_new:N \l_@@_begin_int \int_new:N \l_@@_end_int \cs_new_protected:Npn \@@_make_table: { \longtable { r | * { 16 } { C { \c_@@_cell_wd_dim } | } } \@@_long_table_head: \@@_multi_row:nn { \int_use:N \l_@@_begin_int } { \int_use:N \l_@@_end_int } \endlongtable } \dim_set_eq:NN \tabcolsep \c_@@_column_sep_dim % These functions must be expandable: % \@@_long_table_head:, \@@_first_row:, % \@@_multi_row:nn, \@@_row:n, \@@_div_sixteen:n, % \@@_hline:, \@@_set_arstrut:nn, \@@_restore_arstrut:, etc., % so that `noalign` can work properly. % Hence we use `\cs_new:Npn` and `\int_step_function:nnnN` here. \cs_new:Npn \@@_long_table_head: { % It's very hackable here! % The dimension is measured by hand. Not universal at all. \@@_set_arstrut:nn { 0 pt } { 0 pt } \multicolumn { 17 } { c } { \rule { 0 pt } { 1.29 cm } } \\ \@@_first_row: \endhead \@@_first_row: \endfirsthead } \cs_new:Npn \@@_first_row: { \multicolumn { 17 } { r } { \tabular { % Skip row number r | * { 15 } { C { \c_@@_cell_wd_dim } E } C { \c_@@_cell_wd_dim } | } % I don't know why there are so many `#`. \int_step_inline:nnn { 0 } { 15 } { & \@@_first_row_cell:n {####1} } \endtabular } \\* \@@_hline: } \cs_new_protected:Npn \@@_first_row_cell:n #1 { \NumberStyle \int_to_Hex:n {#1} } \cs_new:Npn \@@_multi_row:nn #1#2 { \int_step_function:nnnN { \@@_div_sixteen:n {#1} * 16 } { 16 } { (\@@_div_sixteen:n {#2} + 1) * 16 - 1 } \@@_row:n } \cs_new:Npn \@@_div_sixteen:n #1 { \int_div_truncate:nn {#1} { 16 } } \cs_new:Npn \@@_row:n #1 { % Glyph row \GlyphStrut % Row number \multirow { 2 } * { \@@_row_nummber:n {#1} } \int_step_inline:nnn {#1} { #1 + 15 } { & \@@_glyph:n {##1} } \\* \@@_restore_arstrut: % Encoding row \@@_hline: \EncodingStrut \int_step_inline:nnn {#1} { #1 + 15 } { & \@@_encoding:n {##1} } \\ \@@_hline: } % To skip the first column (i.e. row index). % LaTeX3 syntax makes `~` to equal space, so we need to change its catcode temporarily. \group_begin: \char_set_catcode_active:N \~ \cs_new:Npn \@@_hline: { \hhline { ~ | * { 16 } { - } } } \group_end: \cs_new:Npn \@@_set_arstrut:nn #1#2 { \tex_noalign:D { \group_begin: % Store the old strutbox \box_gset_eq:NN \l_@@_old_arstrut_box \@arstrutbox % Change the dimensions of \@arstrutbox \hbox_set_to_wd:Nnn \l_tmpa_box { \c_zero_dim } { } \box_set_ht:Nn \l_tmpa_box {#1} \box_set_dp:Nn \l_tmpa_box {#2} \hbox_gset:Nn \@arstrutbox { \box_use:N \l_tmpa_box } \group_end: } } \cs_new:Npn \@@_restore_arstrut: { \tex_noalign:D { \box_gset_eq:NN \@arstrutbox \l_@@_old_arstrut_box } } \box_new:N \l_@@_old_arstrut_box \cs_new_protected:Npn \@@_row_nummber:n #1 { \raisebox { \dim_use:N \c_@@_row_number_ht_dim } { \NumberStyle \int_set:Nn \l_tmpa_int { #1 / 16 } \int_compare:nNnTF { \l_tmpa_int } < { "10 } { 00 } { \int_compare:nNnT { \l_tmpa_int } < { "100 } { 0 } } \int_to_Hex:n { \l_tmpa_int } \skip_horizontal:N \c_@@_row_number_sep_dim } } \cs_new_protected:Npn \@@_glyph:n #1 { \tl_set:Nx \l_tmpa_tl { \int_to_Hex:n {#1} } \seq_if_in:NVTF \c_@@_unicode_reserved_seq \l_tmpa_tl { \cellcolor { reserved@bg } } { \seq_if_in:NVTF \c_@@_unicode_control_seq \l_tmpa_tl { \cellcolor { control@bg } } { % It must be outside `\@@_if_char_exist` \GlyphStyle \@@_if_char_exist:nTF {#1} { \@@_symbol:n {#1} \refstepcounter { glyph } \int_gincr:N \g_@@_glyph_int } { \normalfont \int_compare:nNnTF {#1} < { "10000 } { \BMPFallbackFont } { \SMPFallbackFont } \textcolor { nochar@text } { \@@_symbol:n {#1} } } \int_gincr:N \g_@@_code_point_int } } } \cs_new_protected:Npn \@@_encoding:n #1 { \group_begin: \EncodingStyle \int_compare:nNnTF {#1} < { "10 } { 000 } { \int_compare:nNnTF {#1} < { "100 } { 00 } { \int_compare:nNnT {#1} < { "1000 } { 0 } } } \int_to_Hex:n {#1} \group_end: } % #1 = section name % #2 = non-unicode data file \cs_new_protected:Npn \@@_non_unicode:nn #1#2 { \tl_set:Nn \l_@@_glyph_count_tl { \ref* { count: glyph @ non-unicode } } \section { #1 ~ (\tl_use:N \l_@@_glyph_count_tl) } \cs_set_eq:NN \@@_left_foot: \prg_do_nothing: \int_gzero:N \g_@@_non_unicode_glyph_int \@@_non_unicode_print: \newcounter { glyph @ non-unicode } \int_set:cn { c @ glyph @ non-unicode } { \g_@@_non_unicode_glyph_int - 1 } \refstepcounter { glyph @ non-unicode } \label { count: glyph @ non-unicode } \refstepcounter { glyph } \label { count: glyph } } \int_new:N \g_@@_non_unicode_glyph_int \cs_new_protected:Npn \@@_non_unicode_print: { \seq_map_inline:Nn \c_@@_glyph_non_unicode_with_type_seq { \@@_non_unicode_print_class:nn ##1 } } % #1 = class % #2 = clist of glyph names \cs_new_protected:Npn \@@_non_unicode_print_class:nn #1#2 { \subsection { #1 ~ (\clist_count:n {#2}) } \clist_map_inline:nn {#2} { \@@_non_unicode_cell:n {##1} \refstepcounter { glyph } \int_gincr:N \g_@@_non_unicode_glyph_int } } \cs_new_protected:Npn \@@_non_unicode_cell:n #1 { \tabular { | C { \c_@@_non_unicode_wd_dim } | } % Glyph \hline \NonUnicodeGlyphStrut \GlyphStyle \@@_glyph_from_name:n {#1} \\ \@@_restore_arstrut: % Encoding (glyph name) \hline \EncodingStrut \EncodingStyle #1 \\ \@@_restore_arstrut: \hline \endtabular % A space allowing line break \ } % Header and footer. \fancyhf { } \fancyhead [ R ] { \thepage } \fancyfoot [ L ] { \footnotesize \int_compare:nNnTF { \int_use:c { c@page } } = { \ztotpages } { \@@_left_foot_last_page: } { \@@_left_foot: } } \fancyfoot [ R ] { \footnotesize \itshape Copyright~ \copyright{}~ 2018--2020~ by~ Xiangdong~ Zeng } % `\headrulewidth` is not a dim variable. \cs_set:Npn \headrulewidth { 0 pt } \cs_new_protected:Npn \@@_left_foot_last_page: { \itshape Other~ fonts~ used~ in~ this~ document:~ FiraGO,~ Fira~ Code,~ GNU~ Unifont. \\ Colors~ are~ inspired~ by~ Google~ Material~ Design. } \ExplSyntaxOff\makeatother \geometry{a4paper, hmargin=1cm, vmargin=2.5cm} \ctexset{section/format=\Large\bfseries\centering} \hypersetup{bookmarksnumbered=true, colorlinks=true, linkcolor=[HTML]34A853, urlcolor=[HTML]E91E63} \setmainfont{FiraGO}[BoldFont=* SemiBold, Numbers=Monospaced] \setmonofont{Fira Code}[UprightFont=* Light, BoldFont=* Regular] \newfontface\BMPFallbackFont{Unifont} \newfontface\SMPFallbackFont{Unifont Upper} \newfontface\SymbolFont{Fira Math Regular} \title{\bfseries\huge Fira Math\\ \itshape\Large Sans-serif font with Unicode math support} \author{Xiangdong Zeng} \date{2020/10/15\quad v0.3.4} \begin{document} \newgeometry{hmargin=1.5in, vmargin=1.0in} \maketitle \begin{abstract} \href{https://github.com/firamath/firamath}{Fira Math} is a sans-serif font with Unicode math support. The design of this font is based on \href{https://github.com/mozilla/Fira}{Fira Sans} and \href{https://bboxtype.com/typefaces/FiraGO}{FiraGO}. Fira Math is distributed in OpenType format, and can be used with \href{https://www.ctan.org/pkg/unicode-math}{unicode-math} package under \hologo{XeTeX} or \hologo{LuaTeX}. There are \ref*{count:glyph} glyphs in Fira Math at present. Fira Math is licensed under the \href{http://scripts.sil.org/OFL}{SIL Open Font License}, Version 1.1. \end{abstract} \setlength\cftbeforesubsecskip{1ex} \tableofcontents \clearpage \restoregeometry \pagestyle{fancy} \fonttable{C0 Controls and Basic Latin}{"0-"7F} \fonttable{C1 Controls and Latin-1 Supplement}{"80-"FF} \fonttable{Latin Extended-A}{"100-"17F} \fonttable{Latin Extended-B}{"180-"24F} \fonttable{Combining Diacritical Marks}{"300-"36F} \fonttable{Greek and Coptic}{"370-"3FF} \fonttable{Cyrillic}{"400-"4FF} \fonttable{General Punctuation}{"2000-"206F} \fonttable{Currency Symbols}{"20A0-"20CF} \fonttable{Combining Diacritical Marks for Symbols}{"20D0-"20FF} \fonttable{Letterlike Symbols}{"2100-"214F} \fonttable{Number Forms}{"2150-"218F} \fonttable{Arrows}{"2190-"21FF} \fonttable{Mathematical Operators}{"2200-"22FF} \fonttable{Miscellaneous Technical}{"2300-"23FF} \fonttable{Block Elements}{"2580-"259F} \fonttable{Geometric Shapes}{"25A0-"25FF} \fonttable{Miscellaneous Symbols}{"2600-"26FF} \fonttable{Miscellaneous Mathematical Symbols-A}{"27C0-"27EF} \fonttable{Supplemental Arrows-A}{"27F0-"27FF} \fonttable{Supplemental Arrows-B}{"2900-"297F} \fonttable{Miscellaneous Mathematical Symbols-B}{"2980-"29FF} \fonttable{Supplemental Mathematical Operators}{"2A00-"2AFF} \fonttable{Miscellaneous Symbols and Arrows}{"2B00-"2BFF} \fonttable{Alphabetic Presentation Forms}{"FB00-"FB4F} \fonttable{Mathematical Alphanumeric Symbols}{"1D400-"1D7FF} \fonttable{Geometric Shapes Extended}{"1F780-"1F7FF} \fonttable*{Non-Unicode Glyphs} \end{document}