Unicode sequences, @typeface, and the font/typeface distinction
A run of Unicode code points now needs one pair of carets, not one pair
each: ^9053 53EF 9053^ renders the characters adjacently, and a single
character inside such a run stands for itself. An invalid code point is
an error naming the position that wrote it, rather than an apology
rendered into the finished document; noncharacters are refused alongside
surrogates; and a code point that lands on a Klammertext special is safe
through the re-reads that assemble a document. The character tables now
produce the precomposed form, so a diacritic written as ^a" and one typed
directly are the same text to a search or a copy-paste.
"kdesc -u" describes how to write a Unicode character, with tables of
glyphs beside the codes that produce them. It is new and not yet
complete: it predates the sequence form and the typeface klammer below.
A typeface and a style are no longer both called "font". A typeface is a
family resolved by name; a style code is the one letter naming a type
style. So @document takes :serif_typeface and its siblings, a table takes
:style, captions take :caption_style and :caption_size, the uniform scale
is :text_scale, and the command is "kdesc --typeface". This renames
arguments a document may already use; an old name is a located error
rather than a silent omission.
@typeface sets a passage in another typeface for the length of that
passage:
@typeface Noto Sans Egyptian Hieroglyphs | ^132AA 133CF^ :scale 1.5 @
Writing the klammer is the whole declaration -- the document resolves the
typeface, embeds it in what it produces, and carries its license along.
Two typefaces for scripts no text font covers now ship with Klammertext:
Noto Sans Egyptian Hieroglyphs and Noto Sans Cuneiform. Every typeface in
the distribution now carries its license file.
(from dev 61e598698891)
This commit is contained in:
1 parent
37b6ba1c4f
commit
af29bbf7ac
47 files changed
+1921
-135
No files matched your search
@@ -51,7 +51,7 @@ are regenerated on each release — patches cannot be merged directly.
|
|||||||
Report problems (or send patches) to the author; accepted changes are
|
Report problems (or send patches) to the author; accepted changes are
|
||||||
applied to the development tree and appear in a following snapshot.
|
applied to the development tree and appear in a following snapshot.
|
||||||
|
|
||||||
This snapshot was assembled from development commit `07ce5ea86a0a`.
|
This snapshot was assembled from development commit `61e598698891`.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
+8
-3
@@ -161,10 +161,11 @@ int main(int argc, char* argv[])
|
|||||||
// rather than verbosity levels.
|
// rather than verbosity levels.
|
||||||
args.var("k", "Show klammers. With <text>, only those whose name or description contains <text>.", "text");
|
args.var("k", "Show klammers. With <text>, only those whose name or description contains <text>.", "text");
|
||||||
args.flag("c", "Show the codes for accented vowels and other special characters");
|
args.flag("c", "Show the codes for accented vowels and other special characters");
|
||||||
|
args.flag("u", "Describe including Unicode characters in KLammertext");
|
||||||
args.flag("t", "Show the targets for Klammertext output");
|
args.flag("t", "Show the targets for Klammertext output");
|
||||||
args.opt("i", "Input filename to analyze containing klammer and other definitions", "filename", "", "'text'");
|
args.opt("i", "Input filename to analyze containing klammer and other definitions", "filename", "", "'text'");
|
||||||
args.var("klammersets", "List the available klammersets, or load one or more for analysis. Enter \"--klammersets help\" for details.", "symbols");
|
args.var("klammersets", "List the available klammersets, or load one or more for analysis. Enter \"--klammersets help\" for details.", "symbols");
|
||||||
args.var("font", "List installed fonts. Enter \"--font help\" for font maintenance commands.");
|
args.var("typeface", "List installed typefaces. Enter \"--typeface help\" for typeface maintenance commands.");
|
||||||
args.flag("argtypes", "Show the klammer argument types");
|
args.flag("argtypes", "Show the klammer argument types");
|
||||||
args.var("katoms", "Show the katom types. Enter \"--katoms help\" for details.");
|
args.var("katoms", "Show the katom types. Enter \"--katoms help\" for details.");
|
||||||
args.flag("rewrite", "Show the katom rewrite patterns");
|
args.flag("rewrite", "Show the katom rewrite patterns");
|
||||||
@@ -192,6 +193,10 @@ int main(int argc, char* argv[])
|
|||||||
std::cout << "\n";
|
std::cout << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p("u")) {
|
||||||
|
unicode_examples();
|
||||||
|
}
|
||||||
|
|
||||||
if (p("argtypes")) {
|
if (p("argtypes")) {
|
||||||
Argtype_registry argtypes;
|
Argtype_registry argtypes;
|
||||||
std::cout << boldblack << "\nStandard klammer argument types\n" << black;
|
std::cout << boldblack << "\nStandard klammer argument types\n" << black;
|
||||||
@@ -219,8 +224,8 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
// The --font subcommands operate on the Klammertext font store
|
// The --font subcommands operate on the Klammertext font store
|
||||||
// (infrastructure) and load no klammer set.
|
// (infrastructure) and load no klammer set.
|
||||||
if (args.given("font")) {
|
if (args.given("typeface")) {
|
||||||
font_command(option_words(args, "font"));
|
font_command(option_words(args, "typeface"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ That's it — you're running Klammertext.
|
|||||||
others) are built in, so PDFs work with no internet connection. Font
|
others) are built in, so PDFs work with no internet connection. Font
|
||||||
resolution is entirely offline: asking for a font that isn't installed
|
resolution is entirely offline: asking for a font that isn't installed
|
||||||
lists the available fonts, and additional fonts are installed from font
|
lists the available fonts, and additional fonts are installed from font
|
||||||
files you already have with `kdesc --font install <folder>` (`kdesc --font
|
files you already have with `kdesc --typeface install <folder>` (`kdesc --typeface
|
||||||
help` explains).
|
help` explains).
|
||||||
- **Updating later.** When a new version is announced, run `klammertext-update`
|
- **Updating later.** When a new version is announced, run `klammertext-update`
|
||||||
in Terminal.
|
in Terminal.
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
Copyright 2018 The Crimson Pro Project Authors (https://github.com/Fonthausen/CrimsonPro)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
(The copyright line above and the license URL are the font's own, read
|
||||||
|
from its name table; the license text below is the canonical OFL 1.1.)
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
Copyright 2017 The EB Garamond Project Authors (https://github.com/octaviopardo/EBGaramond12)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://openfontlicense.org
|
||||||
|
|
||||||
|
(The copyright line above and the license URL are the font's own, read
|
||||||
|
from its name table; the license text below is the canonical OFL 1.1.)
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
Copyright 2006 The Inconsolata Project Authors (https://github.com/cyrealtype/Inconsolata)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
(The copyright line above and the license URL are the font's own, read
|
||||||
|
from its name table; the license text below is the canonical OFL 1.1.)
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
Copyright (c) 2012, Pablo Impallari (www.impallari.com|impallari@gmail.com), Copyright (c) 2012, Rodrigo Fuenzalida (www.rfuenzalida.com|hello@rfuenzalida.com), with Reserved Font Name Libre Baskerville.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
(The copyright line above and the license URL are the font's own, read
|
||||||
|
from its name table; the license text below is the canonical OFL 1.1.)
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Noto Sans Cuneiform';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url('noto-sans-cuneiform/Regular.ttf') format('truetype');
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2022 The Noto Project Authors (https://github.com/notofonts/cuneiform)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Noto Sans Egyptian Hieroglyphs';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url('noto-sans-egyptian-hieroglyphs/Regular.ttf') format('truetype');
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2022 The Noto Project Authors (https://github.com/notofonts/egyptian-hieroglyphs)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
Binary file not shown.
@@ -0,0 +1,95 @@
|
|||||||
|
Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
(The copyright line above and the license URL are the font's own, read
|
||||||
|
from its name table; the license text below is the canonical OFL 1.1.)
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/),
|
||||||
|
with Reserved Font Name 'Source'.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://openfontlicense.org
|
||||||
|
|
||||||
|
(The copyright line above is the font's own, read from its name table.
|
||||||
|
This binary carries no license record of its own -- it predates the
|
||||||
|
practice -- so the license is stated from the upstream release it comes
|
||||||
|
from: https://github.com/adobe-fonts/source-code-pro, whose LICENSE.md
|
||||||
|
is the OFL 1.1 text below.)
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
© 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
(The copyright line above and the license URL are the font's own, read
|
||||||
|
from its name table; the license text below is the canonical OFL 1.1.)
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
+2
-2
@@ -63,11 +63,11 @@ public:
|
|||||||
// next -/-- token (zero or more). get(name) returns the words
|
// next -/-- token (zero or more). get(name) returns the words
|
||||||
// space-joined; given(name) distinguishes "--name with no words"
|
// space-joined; given(name) distinguishes "--name with no words"
|
||||||
// from an absent --name. Used for subcommand-style interfaces
|
// from an absent --name. Used for subcommand-style interfaces
|
||||||
// (kdesc --font install <dir>).
|
// (kdesc --typeface install <dir>).
|
||||||
// A variadic option: the words after the flag, up to the next one.
|
// A variadic option: the words after the flag, up to the next one.
|
||||||
// `parameter` is shown in the usage line as "[<parameter>]" -- an option
|
// `parameter` is shown in the usage line as "[<parameter>]" -- an option
|
||||||
// whose words are a free argument (a search phrase) should name it, so
|
// whose words are a free argument (a search phrase) should name it, so
|
||||||
// the usage says what may follow; a subcommand-style option (--font,
|
// the usage says what may follow; a subcommand-style option (--typeface,
|
||||||
// --coverage) leaves it empty and documents its words in its own help.
|
// --coverage) leaves it empty and documents its words in its own help.
|
||||||
void var(const std::string& name, const std::string& desc,
|
void var(const std::string& name, const std::string& desc,
|
||||||
const std::string& parameter = "");
|
const std::string& parameter = "");
|
||||||
|
|||||||
+97
-10
@@ -2,9 +2,26 @@
|
|||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "character.h"
|
#include "character.h"
|
||||||
|
#include "precomposed.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "target.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "show.h"
|
#include "show.h"
|
||||||
|
|
||||||
|
// A base letter composed with a combining mark. The PRECOMPOSED (NFC)
|
||||||
|
// code point is emitted where one exists -- that is the byte sequence
|
||||||
|
// editors and input methods produce for direct entry, so ^a" and a typed
|
||||||
|
// ä compare equal (search, copy-paste); the tables formerly emitted
|
||||||
|
// base + combining mark, which renders identically but is a different
|
||||||
|
// string. Pairs with no precomposed form keep the combining fallback.
|
||||||
|
// The table is GENERATED: doc/make_precomposed_table.py -> precomposed.h.
|
||||||
|
static std::string compose(const std::string& base, const std::string& mark_cp)
|
||||||
|
{
|
||||||
|
auto it = precomposed.find(base + mark_cp);
|
||||||
|
if (it != precomposed.end()) return it->second;
|
||||||
|
return base + utf8char(std::stoi(mark_cp, nullptr, 16));
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
std::string klammertext_special_characters { "@|*^#" };
|
std::string klammertext_special_characters { "@|*^#" };
|
||||||
|
|
||||||
@@ -44,6 +61,24 @@ std::string utf8char(int cp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool valid_codepoint(int cp)
|
||||||
|
{
|
||||||
|
if (cp < 0 || cp > 0x10FFFF) return false;
|
||||||
|
if (0xD800 <= cp && cp <= 0xDFFF) return false; // surrogates
|
||||||
|
if (0xFDD0 <= cp && cp <= 0xFDEF) return false; // noncharacters
|
||||||
|
if ((cp & 0xFFFE) == 0xFFFE) return false; // U+xFFFE / U+xFFFF
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string invalid_codepoint_reason(int cp)
|
||||||
|
{
|
||||||
|
if (cp < 0 || cp > 0x10FFFF)
|
||||||
|
return "beyond U+10FFFF, the top of the Unicode range";
|
||||||
|
if (0xD800 <= cp && cp <= 0xDFFF)
|
||||||
|
return "a surrogate (U+D800-U+DFFF), not a character";
|
||||||
|
return "a noncharacter, reserved by Unicode for internal use";
|
||||||
|
}
|
||||||
|
|
||||||
std::string unicode_hex_to_char(std::string s, int width=4) //, std::string marker)
|
std::string unicode_hex_to_char(std::string s, int width=4) //, std::string marker)
|
||||||
{
|
{
|
||||||
(void)K::log(4, s);
|
(void)K::log(4, s);
|
||||||
@@ -82,7 +117,7 @@ std::string process_diacritics(std::string s)
|
|||||||
std::regex hit { regex_escape((*p)[0].str()) };
|
std::regex hit { regex_escape((*p)[0].str()) };
|
||||||
std::string ch = (*p)[1].str();
|
std::string ch = (*p)[1].str();
|
||||||
std::string d = (*p)[2].str();
|
std::string d = (*p)[2].str();
|
||||||
result = std::regex_replace(result, hit, ch + unicode_hex_to_char(diacritics[d].first));
|
result = std::regex_replace(result, hit, compose(ch, diacritics[d].first));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -124,15 +159,14 @@ std::string process_pinyin(std::string s)
|
|||||||
std::string vowel = (*p)[1].str();
|
std::string vowel = (*p)[1].str();
|
||||||
std::string tone = (*p)[2].str();
|
std::string tone = (*p)[2].str();
|
||||||
result = std::regex_replace(result, hit,
|
result = std::regex_replace(result, hit,
|
||||||
vowel + unicode_hex_to_char(pinyin_tones[tone].first));
|
compose(vowel, pinyin_tones[tone].first));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string process_unicode_codepoint(std::string s)
|
std::string process_unicode_codepoint(std::string s, const Locator& loc = Locator::none())
|
||||||
{
|
{
|
||||||
(void)K::log(4);
|
(void)K::log(4);
|
||||||
//return std::regex_replace(s, unicode_re, hidehat + "$1" + hidehat);
|
|
||||||
std::string result {s};
|
std::string result {s};
|
||||||
std::sregex_iterator end {};
|
std::sregex_iterator end {};
|
||||||
for (std::sregex_iterator p { s.begin(), s.end(), unicode_re }; p!= end; ++p) {
|
for (std::sregex_iterator p { s.begin(), s.end(), unicode_re }; p!= end; ++p) {
|
||||||
@@ -141,8 +175,22 @@ std::string process_unicode_codepoint(std::string s)
|
|||||||
// its argument at a fixed width, and its 4-digit default truncated a
|
// its argument at a fixed width, and its 4-digit default truncated a
|
||||||
// 5-digit code point to its first four digits (^13000^ rendered as
|
// 5-digit code point to its first four digits (^13000^ rendered as
|
||||||
// U+1300 followed by a literal "0").
|
// U+1300 followed by a literal "0").
|
||||||
|
int cp = std::stoi((*p)[1].str(), nullptr, 16);
|
||||||
|
// An invalid code point is a located ERROR, not text in the document
|
||||||
|
// (the no-warn-and-continue policy): a generator's typo must not
|
||||||
|
// produce a finished-looking document with an apology embedded
|
||||||
|
// where a character should be.
|
||||||
|
if (!valid_codepoint(cp)) {
|
||||||
|
throw Parsing_error("Invalid Unicode code point \"" + (*p)[0].str()
|
||||||
|
+ "\": " + invalid_codepoint_reason(cp), loc);
|
||||||
|
}
|
||||||
|
// A code point that lands on a Klammertext structural character
|
||||||
|
// (@ | # ^ : *) is hidden as its KTESC marker, exactly as the
|
||||||
|
// quoted form of that character would be -- a bare "@" from
|
||||||
|
// ^0040^ would otherwise be re-interpreted when the text is
|
||||||
|
// re-katomized (@document :text, the @eval read-back).
|
||||||
result = std::regex_replace(result, hit_re,
|
result = std::regex_replace(result, hit_re,
|
||||||
utf8char(std::stoi((*p)[1].str(), nullptr, 16)));
|
hide_structural_characters(utf8char(cp)));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -154,7 +202,7 @@ std::string process_unicode_codepoint(std::string s)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string encode(const std::string& s)
|
std::string encode(const std::string& s, const Locator& loc)
|
||||||
{
|
{
|
||||||
if (s.find("^") == std::string::npos)
|
if (s.find("^") == std::string::npos)
|
||||||
return s;
|
return s;
|
||||||
@@ -177,7 +225,7 @@ std::string encode(const std::string& s)
|
|||||||
result = process_extended_latin(result);
|
result = process_extended_latin(result);
|
||||||
if (dbg) std::cout << "extended_latin: " << result << "\n";
|
if (dbg) std::cout << "extended_latin: " << result << "\n";
|
||||||
|
|
||||||
result = process_unicode_codepoint(result);
|
result = process_unicode_codepoint(result, loc);
|
||||||
if (dbg) std::cout << "unicode: " << result << "\n";
|
if (dbg) std::cout << "unicode: " << result << "\n";
|
||||||
|
|
||||||
result = process_diacritics(result);
|
result = process_diacritics(result);
|
||||||
@@ -225,7 +273,7 @@ void diacritics_examples(const std::string& kt_filename)
|
|||||||
<< " @i-Displayed | @i-Written | @i-Name\n";
|
<< " @i-Displayed | @i-Written | @i-Name\n";
|
||||||
else
|
else
|
||||||
std::cout << boldblack
|
std::cout << boldblack
|
||||||
<< "\nDiacritics (with typical base characters)\n" << black;
|
<< "\nDiacritics (with typical base characters)\n\n" << black;
|
||||||
|
|
||||||
std::string line_sep = "|| @line@ ";
|
std::string line_sep = "|| @line@ ";
|
||||||
for (char symbol : diacritic_symbols_order) {
|
for (char symbol : diacritic_symbols_order) {
|
||||||
@@ -260,7 +308,7 @@ void extended_latin_examples(const std::string& kt_filename)
|
|||||||
kt << "@table :caption " << title << " |\n"
|
kt << "@table :caption " << title << " |\n"
|
||||||
<< " @i-Displayed | @i-Written | @i-Name\n";
|
<< " @i-Displayed | @i-Written | @i-Name\n";
|
||||||
else
|
else
|
||||||
std::cout << "\n" << boldblack << title << black << "\n";
|
std::cout << "\n" << boldblack << title << black << "\n\n";
|
||||||
|
|
||||||
std::string line_sep = "|| @line@ ";
|
std::string line_sep = "|| @line@ ";
|
||||||
for (const std::string& symbol : extended_latin_symbols) {
|
for (const std::string& symbol : extended_latin_symbols) {
|
||||||
@@ -291,7 +339,7 @@ void pinyin_examples(const std::string& kt_filename)
|
|||||||
<< " @i-Displayed | @i-Written | @i-Name\n";
|
<< " @i-Displayed | @i-Written | @i-Name\n";
|
||||||
else
|
else
|
||||||
std::cout << boldblack
|
std::cout << boldblack
|
||||||
<< "\nMandarin pinyin tones (using vowel \"a\")\n" << black;
|
<< "\nMandarin pinyin tones (using vowel \"a\")\n\n" << black;
|
||||||
|
|
||||||
std::string line_sep = "|| @line@ ";
|
std::string line_sep = "|| @line@ ";
|
||||||
for (auto [symbol, codename] : pinyin_tones) {
|
for (auto [symbol, codename] : pinyin_tones) {
|
||||||
@@ -309,6 +357,45 @@ void pinyin_examples(const std::string& kt_filename)
|
|||||||
write_kt_example_file(kt, kt_filename);
|
write_kt_example_file(kt, kt_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void unicode_examples(const std::string& kt_filename)
|
||||||
|
{
|
||||||
|
std::stringstream kt {};
|
||||||
|
bool write_kt_file = kt_filename.size() != 0;
|
||||||
|
|
||||||
|
std::cout << boldblack << "\nIncluding Unicode in Klammertext files\n\n" << black
|
||||||
|
<< "To specify a wide variety of different letter forms, the Unicode Standard\n"
|
||||||
|
<< "defines a large set of \"code points\" organized by groups. To include a\n"
|
||||||
|
<< "Unicode character in Klammertext, you surround its hexadecimal number with\n"
|
||||||
|
<< "the \"^\" character. For example, the Cyrillic captial letter \"I\" is \"И\",\n"
|
||||||
|
<< "included in Klammertext as ^0418^.\n\n"
|
||||||
|
<< "To search for Unicode characters by their description, see:\n"
|
||||||
|
<< " https://www.fileformat.info/info/unicode/char/search.htm\n";
|
||||||
|
|
||||||
|
std::cout << "\n⟐ Examples of Chinese characters\n\n"
|
||||||
|
<< " Pinyin\n";
|
||||||
|
for (auto chr : dao) {
|
||||||
|
std::string code = "^" + chr[1] + "^";
|
||||||
|
std::cout << " " << process_unicode_codepoint(code) << " "
|
||||||
|
<< code << " "
|
||||||
|
<< chr[0] << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "\n⟐ Examples of Egyptian hieroglyphs\n\n";
|
||||||
|
std::cout << std::setw(16) << " " << "Sound Gardiner\n";
|
||||||
|
for (auto glyph : ptolemy) {
|
||||||
|
std::cout << " " << std::setw(4) << process_unicode_codepoint("^" + glyph[2] + "^") << " "
|
||||||
|
<< "^" + glyph[2] + "^ "
|
||||||
|
<< std::setw(4)
|
||||||
|
<< glyph[1] << " "
|
||||||
|
<< std::setw(4)
|
||||||
|
<< glyph[0] << "\n";
|
||||||
|
}
|
||||||
|
std::cout << "\nSee: https://en.wikipedia.org/wiki/List_of_Egyptian_hieroglyphs\n"
|
||||||
|
<< "The Unicode codepoint in the second column of the \"List of hieroglyphs\"\n"
|
||||||
|
<< "table is the number in the ^...^ code used by Klammertext.\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
void show_special_characters()
|
void show_special_characters()
|
||||||
{
|
{
|
||||||
std::cout << std::setfill(' ');
|
std::cout << std::setfill(' ');
|
||||||
|
|||||||
+45
-3
@@ -11,6 +11,8 @@
|
|||||||
#include <regex>
|
#include <regex>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "locator.h"
|
||||||
|
|
||||||
// ^UUUU^ — a Unicode code point in hex, 4 to 6 digits (^263A^ is the BMP,
|
// ^UUUU^ — a Unicode code point in hex, 4 to 6 digits (^263A^ is the BMP,
|
||||||
// ^13000^ EGYPTIAN HIEROGLYPH A001, ^10FFFD^ the top of the range), or a
|
// ^13000^ EGYPTIAN HIEROGLYPH A001, ^10FFFD^ the top of the range), or a
|
||||||
// single digit. Lengths 2-3 are NOT accepted: two- and three-letter
|
// single digit. Lengths 2-3 are NOT accepted: two- and three-letter
|
||||||
@@ -89,21 +91,61 @@ std::map<std::string, std::pair<std::string, std::string>> pinyin_tones {
|
|||||||
{"3", {"030C", "falling-rising"}},
|
{"3", {"030C", "falling-rising"}},
|
||||||
{"4", {"0300", "falling"}}};
|
{"4", {"0300", "falling"}}};
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::vector<std::vector<std::string>> ptolemy {
|
||||||
|
{"Q3", "P", "132AA"},
|
||||||
|
{"X1", "t", "133CF"},
|
||||||
|
{"V4", "o/wa", "13371"},
|
||||||
|
{"E23", "l/r", "130ED"},
|
||||||
|
{"Aa15", "m", "1340D"},
|
||||||
|
{"M17A", "e/y", "131CC"},
|
||||||
|
{"S29", "s", "132F4"}};
|
||||||
|
|
||||||
|
/*
|
||||||
|
道 (dào): U+9053
|
||||||
|
可 (kě): U+53EF
|
||||||
|
道 (dào): U+9053
|
||||||
|
非 (fēi): U+975E
|
||||||
|
常 (cháng): U+5E38
|
||||||
|
道 (dào): U+9053
|
||||||
|
*/
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::vector<std::vector<std::string>> dao {
|
||||||
|
{"dào", "9053"},
|
||||||
|
{"kě", "53EF"},
|
||||||
|
{"dào", "9053"},
|
||||||
|
{"fēi", "975E"},
|
||||||
|
{"cháng", "5E38"},
|
||||||
|
{"dào", "9053"}};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
bool is_tty() { return isatty(fileno(stdout)); }
|
bool is_tty() { return isatty(fileno(stdout)); }
|
||||||
//const char* italic_on() { return tty() ? "\033[3m" : ""; }
|
|
||||||
//const char* italic_off() { return tty() ? "\033[0m" : ""; }
|
|
||||||
inline
|
inline
|
||||||
const std::string italic_on() { return is_tty() ? "\033[3m" : ""; }
|
const std::string italic_on() { return is_tty() ? "\033[3m" : ""; }
|
||||||
inline
|
inline
|
||||||
const std::string italic_off() { return is_tty() ? "\033[0m" : ""; }
|
const std::string italic_off() { return is_tty() ? "\033[0m" : ""; }
|
||||||
|
|
||||||
|
std::string encode(const std::string& s, const Locator& loc);
|
||||||
|
|
||||||
std::string encode(const std::string& s);
|
// UTF-8 encoding of one code point (to U+10FFFF; surrogates and values
|
||||||
|
// above the range yield an "Invalid Unicode: N" text). Used by the
|
||||||
|
// character tables here and by the ^UUUU UUUU ...^ sequence pass
|
||||||
|
// (process_unicode_sequences in katom_list.cpp).
|
||||||
|
std::string utf8char(int cp);
|
||||||
|
|
||||||
|
// Whether cp may be written in a ^...^ form: within the Unicode range,
|
||||||
|
// not a surrogate, and not a NONCHARACTER (U+FDD0-U+FDEF and the last two
|
||||||
|
// code points of every plane) -- the standard reserves those for internal
|
||||||
|
// use, never for interchange. An invalid code point in a document is a
|
||||||
|
// located Parsing_error (the no-warn-and-continue policy; the in-band
|
||||||
|
// "Invalid Unicode" text is no longer reachable from input).
|
||||||
|
bool valid_codepoint(int cp);
|
||||||
|
std::string invalid_codepoint_reason(int cp);
|
||||||
|
|
||||||
void diacritics_examples(const std::string& kt_filename = "");
|
void diacritics_examples(const std::string& kt_filename = "");
|
||||||
void extended_latin_examples(const std::string& kt_filename = "");
|
void extended_latin_examples(const std::string& kt_filename = "");
|
||||||
void pinyin_examples(const std::string& kt_filename = "");
|
void pinyin_examples(const std::string& kt_filename = "");
|
||||||
|
void unicode_examples(const std::string& kt_filename = "");
|
||||||
|
|
||||||
void show_special_characters();
|
void show_special_characters();
|
||||||
+8
-8
@@ -206,7 +206,7 @@ static void extract_font_metrics(Resolved_font& font)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Resolved_font resolve_font(const std::string& family_name)
|
Resolved_font resolve_font(const std::string& family_name, const Locator& loc)
|
||||||
{
|
{
|
||||||
if (family_name.empty())
|
if (family_name.empty())
|
||||||
return {};
|
return {};
|
||||||
@@ -222,26 +222,26 @@ Resolved_font resolve_font(const std::string& family_name)
|
|||||||
if (!font.family_name.empty()) {
|
if (!font.family_name.empty()) {
|
||||||
extract_font_metrics(font);
|
extract_font_metrics(font);
|
||||||
// A DERIVED value: an installed font may shadow a default one, and
|
// A DERIVED value: an installed font may shadow a default one, and
|
||||||
// which directory won is not readable from ":serif_font Whatever".
|
// which directory won is not readable from ":serif_typeface Whatever".
|
||||||
// The commonest font question -- "why does it not look like the
|
// The commonest font question -- "why does it not look like the
|
||||||
// one I installed?" -- is answered by this line.
|
// one I installed?" -- is answered by this line.
|
||||||
(void)K::log(1, "Font \"" + family_name + "\": " + base + "/" + dir_name);
|
(void)K::log(1, "Typeface \"" + family_name + "\": " + base + "/" + dir_name);
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream ss {};
|
std::stringstream ss {};
|
||||||
ss << "The font \"" << family_name << "\" is not installed.\n\n"
|
ss << "The typeface \"" << family_name << "\" is not installed.\n\n"
|
||||||
<< "Available fonts:\n";
|
<< "Available typefaces:\n";
|
||||||
for (const std::string& name : available_font_families()) {
|
for (const std::string& name : available_font_families()) {
|
||||||
ss << " " << name << "\n";
|
ss << " " << name << "\n";
|
||||||
}
|
}
|
||||||
ss << "\nFonts are searched in the directories of the KLAMMERTEXT_FONTS\n"
|
ss << "\nTypefaces are searched in the directories of the KLAMMERTEXT_FONTS\n"
|
||||||
<< "environment variable (colon-separated; default $HOME/.klammertext/fonts)\n"
|
<< "environment variable (colon-separated; default $HOME/.klammertext/fonts)\n"
|
||||||
<< "and then in the default font set. To install a font,\n"
|
<< "and then in the default set. To install a typeface,\n"
|
||||||
<< "place its files as <fonts-dir>/" << dir_name << "/*.ttf with a\n"
|
<< "place its files as <fonts-dir>/" << dir_name << "/*.ttf with a\n"
|
||||||
<< "<fonts-dir>/" << dir_name << ".css declaring its @font-face variants.";
|
<< "<fonts-dir>/" << dir_name << ".css declaring its @font-face variants.";
|
||||||
throw Argument_error(ss.str());
|
throw Argument_error(ss.str(), loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+6
-1
@@ -3,6 +3,7 @@
|
|||||||
// The Klammertext font store (infrastructure; see font_store.cpp).
|
// The Klammertext font store (infrastructure; see font_store.cpp).
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "locator.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct Resolved_font {
|
struct Resolved_font {
|
||||||
@@ -27,7 +28,11 @@ std::vector<std::string> installed_font_dirs();
|
|||||||
std::string default_font_dir();
|
std::string default_font_dir();
|
||||||
// Every installable font family found across those directories.
|
// Every installable font family found across those directories.
|
||||||
std::vector<std::string> available_font_families();
|
std::vector<std::string> available_font_families();
|
||||||
Resolved_font resolve_font(const std::string& family_name);
|
// The Locator is the DOCUMENT location to blame when the typeface is not
|
||||||
|
// installed: without it the "not installed" error cites font_store.cpp,
|
||||||
|
// a source location no user can act on (the no-.cpp-location rule).
|
||||||
|
Resolved_font resolve_font(const std::string& family_name,
|
||||||
|
const Locator& loc = Locator::none());
|
||||||
void install_resolved_font(const Resolved_font& font, std::string output_dir);
|
void install_resolved_font(const Resolved_font& font, std::string output_dir);
|
||||||
|
|
||||||
// One font file classified by its internal metadata (name table, OS/2).
|
// One font file classified by its internal metadata (name table, OS/2).
|
||||||
|
|||||||
+154
-1
@@ -281,11 +281,164 @@ void encode_nonascii_characters(katom_list& katoms)
|
|||||||
{
|
{
|
||||||
for (Katom& k : katoms) {
|
for (Katom& k : katoms) {
|
||||||
if (is_nonascii(k)) {
|
if (is_nonascii(k)) {
|
||||||
k.m_text = encode(k.m_text);
|
k.m_text = encode(k.m_text, k.m_loc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unicode sequences
|
||||||
|
|
||||||
|
// ^UUUU UUUU ...^ -- a whitespace-delimited sequence of Unicode code
|
||||||
|
// points between ONE pair of carets: ^9053 53EF 9053^ renders the three
|
||||||
|
// characters adjacently. The single-token form ^UUUU^ is the katomizer's
|
||||||
|
// nonascii katom, resolved by encode(); a sequence cannot be a katom at
|
||||||
|
// all, because whitespace is preserved as separate katoms and no katom
|
||||||
|
// spans it. So the tokens arrive as word katoms -- the opener "^"+hex,
|
||||||
|
// the closer hex+"^", bare hex between, separated by SPACE katoms only (a
|
||||||
|
// newline aborts: a sequence is one line; so does any other katom, which
|
||||||
|
// is also what enforces "no space inside the delimiters' elbows": a bare
|
||||||
|
// "^" is not an opener) -- and are assembled here. Each token is 4-6 hex
|
||||||
|
// digits, the same rule as the single form. The rendered characters
|
||||||
|
// replace the opening katom's text; the other members are marked
|
||||||
|
// replaced. Skipped inside @@/@@@ definition spans and
|
||||||
|
// @eval/@read/@cond argument spans (code keeps its carets -- the rule the
|
||||||
|
// string-level single-form pass cannot honor) and for literal katoms
|
||||||
|
// (verbatim content; mark_literal_* run before this).
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool hex_token(const std::string& s)
|
||||||
|
{
|
||||||
|
if (s.size() < 4 || s.size() > 6) return false;
|
||||||
|
for (char c : s) {
|
||||||
|
bool hex = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')
|
||||||
|
|| (c >= 'A' && c <= 'F');
|
||||||
|
if (!hex) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A sequence token is a 4-6-digit hex code point or a SINGLE character
|
||||||
|
// standing for itself ("^" excluded -- a lone caret cannot say which
|
||||||
|
// caret closes). The single-character reading exists only inside a
|
||||||
|
// sequence; ^s^ alone stays the mnemonic.
|
||||||
|
bool shape_token(const std::string& s)
|
||||||
|
{
|
||||||
|
return hex_token(s) || (s.size() == 1 && s[0] != '^');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render one scanned token. A hex token is validated -- an invalid code
|
||||||
|
// point is a located error, not text in the document -- and a structural
|
||||||
|
// character in the result is hidden as its KTESC marker. A single
|
||||||
|
// character behaves exactly as if quoted with "^": alphanumerics stand
|
||||||
|
// bare, anything else becomes its marker.
|
||||||
|
std::string render_token(const std::string& s, const Locator& loc)
|
||||||
|
{
|
||||||
|
if (hex_token(s)) {
|
||||||
|
int cp = std::stoi(s, nullptr, 16);
|
||||||
|
if (!valid_codepoint(cp)) {
|
||||||
|
throw Parsing_error(
|
||||||
|
"Invalid Unicode code point \"" + s + "\" in a ^...^ sequence: "
|
||||||
|
+ invalid_codepoint_reason(cp), loc);
|
||||||
|
}
|
||||||
|
return hide_structural_characters(utf8char(cp));
|
||||||
|
}
|
||||||
|
char c = s[0];
|
||||||
|
bool alnum = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')
|
||||||
|
|| (c >= 'A' && c <= 'Z');
|
||||||
|
return alnum ? s : Target::escape_marker(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void process_unicode_sequences(katom_list& katoms)
|
||||||
|
{
|
||||||
|
(void)K::log(4);
|
||||||
|
int definition_depth = 0;
|
||||||
|
int code_depth = 0; // inside an @eval/@read/@cond span
|
||||||
|
std::vector<bool> apply_is_code; // one entry per open application
|
||||||
|
for (size_t i = 0; i < katoms.size(); ++i) {
|
||||||
|
Katom& k = katoms[i];
|
||||||
|
switch (k.m_type) {
|
||||||
|
case katom_t::define_begin:
|
||||||
|
case katom_t::machine_begin:
|
||||||
|
++definition_depth;
|
||||||
|
continue;
|
||||||
|
case katom_t::define_end:
|
||||||
|
case katom_t::machine_end:
|
||||||
|
if (definition_depth > 0) --definition_depth;
|
||||||
|
continue;
|
||||||
|
case katom_t::eval_begin:
|
||||||
|
case katom_t::read_begin:
|
||||||
|
case katom_t::cond_begin:
|
||||||
|
apply_is_code.push_back(true);
|
||||||
|
++code_depth;
|
||||||
|
continue;
|
||||||
|
case katom_t::apply_begin:
|
||||||
|
apply_is_code.push_back(false);
|
||||||
|
continue;
|
||||||
|
case katom_t::apply_end:
|
||||||
|
if (!apply_is_code.empty()) {
|
||||||
|
if (apply_is_code.back()) --code_depth;
|
||||||
|
apply_is_code.pop_back();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (definition_depth > 0 || code_depth > 0) continue;
|
||||||
|
if (k.m_type != katom_t::word && k.m_type != katom_t::text) continue;
|
||||||
|
// The opener: "^" + one token, nothing else.
|
||||||
|
if (k.m_text.size() < 2 || k.m_text[0] != '^') continue;
|
||||||
|
if (!shape_token(k.m_text.substr(1))) continue;
|
||||||
|
// Phase 1 -- SCAN by shape only, no validation: an unclosed run
|
||||||
|
// must fall through untouched (it may be innocent prose about hex),
|
||||||
|
// so an invalid code point may only error once the sequence has
|
||||||
|
// actually closed. Tokens are word katoms separated by SPACE
|
||||||
|
// katoms; any other katom (a newline included: one line only)
|
||||||
|
// aborts.
|
||||||
|
std::vector<std::pair<std::string, const Locator*>> tokens {
|
||||||
|
{ k.m_text.substr(1), &k.m_loc } };
|
||||||
|
std::vector<size_t> members {};
|
||||||
|
bool closed = false;
|
||||||
|
size_t j = i + 1;
|
||||||
|
for (; j < katoms.size(); ++j) {
|
||||||
|
Katom& t = katoms[j];
|
||||||
|
if (t.m_type == katom_t::space) {
|
||||||
|
members.push_back(j);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (t.m_type != katom_t::word && t.m_type != katom_t::text) break;
|
||||||
|
const std::string& s = t.m_text;
|
||||||
|
if (s.size() >= 2 && s.back() == '^'
|
||||||
|
&& shape_token(s.substr(0, s.size() - 1))) {
|
||||||
|
tokens.push_back({ s.substr(0, s.size() - 1), &t.m_loc });
|
||||||
|
members.push_back(j);
|
||||||
|
closed = true;
|
||||||
|
++j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (shape_token(s)) {
|
||||||
|
tokens.push_back({ s, &t.m_loc });
|
||||||
|
members.push_back(j);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!closed) continue;
|
||||||
|
// Phase 2 -- render, validating each code point at its own katom.
|
||||||
|
std::string rendered {};
|
||||||
|
for (const auto& [text, loc] : tokens) {
|
||||||
|
rendered += render_token(text, *loc);
|
||||||
|
}
|
||||||
|
k.m_text = rendered;
|
||||||
|
k.m_unparsed = false;
|
||||||
|
for (size_t m : members) {
|
||||||
|
mark_as_replaced(katoms[m]);
|
||||||
|
}
|
||||||
|
i = j - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Literal
|
// Literal
|
||||||
|
|
||||||
void mark_literal_katoms(katom_list& katoms)
|
void mark_literal_katoms(katom_list& katoms)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ find_span_katoms(
|
|||||||
std::vector<Katom>::iterator kbegin, std::vector<Katom>::iterator kend, const Katom& begin, const Katom& end);
|
std::vector<Katom>::iterator kbegin, std::vector<Katom>::iterator kend, const Katom& begin, const Katom& end);
|
||||||
|
|
||||||
void encode_nonascii_characters(std::vector<Katom>& katoms);
|
void encode_nonascii_characters(std::vector<Katom>& katoms);
|
||||||
|
void process_unicode_sequences(std::vector<Katom>& katoms);
|
||||||
void mark_literal_katoms(std::vector<Katom>& katoms);
|
void mark_literal_katoms(std::vector<Katom>& katoms);
|
||||||
void hide_special_katoms(std::vector<Katom>& katoms);
|
void hide_special_katoms(std::vector<Katom>& katoms);
|
||||||
void mark_ignored_katoms(std::vector<Katom>& katoms);
|
void mark_ignored_katoms(std::vector<Katom>& katoms);
|
||||||
|
|||||||
@@ -135,3 +135,25 @@ std::string locator_summary(std::vector<Locator> locators)
|
|||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse "[<file>:<line>.<column>]" -- see the declaration in locator.h.
|
||||||
|
// Scanned from the RIGHT, because a pathname may itself contain ":" and
|
||||||
|
// "." while the line and column never do.
|
||||||
|
Locator Locator::from_string(const std::string& s)
|
||||||
|
{
|
||||||
|
if (s.size() < 6 || s.front() != '[' || s.back() != ']')
|
||||||
|
return Locator::none();
|
||||||
|
std::string body = s.substr(1, s.size() - 2);
|
||||||
|
size_t dot = body.rfind('.');
|
||||||
|
if (dot == std::string::npos) return Locator::none();
|
||||||
|
size_t colon = body.rfind(':', dot);
|
||||||
|
if (colon == std::string::npos) return Locator::none();
|
||||||
|
try {
|
||||||
|
int line = std::stoi(body.substr(colon + 1, dot - colon - 1));
|
||||||
|
int chr = std::stoi(body.substr(dot + 1));
|
||||||
|
// str() prints m_chr + 1; undo that so a round trip is exact.
|
||||||
|
return Locator(fs::path(body.substr(0, colon)), line, chr - 1);
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
return Locator::none();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,13 @@ public:
|
|||||||
// errors (found by the error gallery, 2026-08-22). Locator() is for
|
// errors (found by the error gallery, 2026-08-22). Locator() is for
|
||||||
// logging; errors either carry a real document location or this.
|
// logging; errors either carry a real document location or this.
|
||||||
static Locator none() { return Locator(fs::path{}, -1, -1); }
|
static Locator none() { return Locator(fs::path{}, -1, -1); }
|
||||||
|
// The inverse of str(): "[<file>:<line>.<column>]" back to a Locator.
|
||||||
|
// A klammer implementation receives its position as the STATE value
|
||||||
|
// K_loc, which is that string; without this it can only pass a
|
||||||
|
// default-constructed Locator, which captures the C++ source location
|
||||||
|
// and prints a file no user can act on. Anything unparseable gives
|
||||||
|
// none() -- a missing location beats a wrong one.
|
||||||
|
static Locator from_string(const std::string& s);
|
||||||
std::string str(bool relative = false) const;
|
std::string str(bool relative = false) const;
|
||||||
std::string desc(bool relative = false) const;
|
std::string desc(bool relative = false) const;
|
||||||
std::string abbrev(bool include_chr=true) const;
|
std::string abbrev(bool include_chr=true) const;
|
||||||
|
|||||||
@@ -435,6 +435,11 @@ void Machine::process_katoms(
|
|||||||
{
|
{
|
||||||
mark_literal_klammer_content(katoms);
|
mark_literal_klammer_content(katoms);
|
||||||
if (literal) mark_literal_katoms(katoms);
|
if (literal) mark_literal_katoms(katoms);
|
||||||
|
// Sequences BEFORE the quoted-punctuation hiding: a single-character
|
||||||
|
// token such as the "-" in ^9053 - 53EF^ must reach the sequence pass
|
||||||
|
// as written; an unmatched run falls through untouched and the hiding
|
||||||
|
// then treats its ^P pairs normally.
|
||||||
|
if (nonascii) process_unicode_sequences(katoms);
|
||||||
hide_special_katoms(katoms);
|
hide_special_katoms(katoms);
|
||||||
if (nonascii) encode_nonascii_characters(katoms);
|
if (nonascii) encode_nonascii_characters(katoms);
|
||||||
if (ignore) mark_ignored_katoms(katoms);
|
if (ignore) mark_ignored_katoms(katoms);
|
||||||
|
|||||||
@@ -0,0 +1,250 @@
|
|||||||
|
#pragma once
|
||||||
|
// GENERATED by doc/make_precomposed_table.py -- do not edit.
|
||||||
|
// (base letter + combining code point) -> precomposed UTF-8.
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
inline
|
||||||
|
const std::map<std::string, std::string> precomposed {
|
||||||
|
{"a0300", "\xc3\xa0"}, // LATIN SMALL LETTER A WITH GRAVE
|
||||||
|
{"a0301", "\xc3\xa1"}, // LATIN SMALL LETTER A WITH ACUTE
|
||||||
|
{"a0302", "\xc3\xa2"}, // LATIN SMALL LETTER A WITH CIRCUMFLEX
|
||||||
|
{"a0303", "\xc3\xa3"}, // LATIN SMALL LETTER A WITH TILDE
|
||||||
|
{"a0304", "\xc4\x81"}, // LATIN SMALL LETTER A WITH MACRON
|
||||||
|
{"a0308", "\xc3\xa4"}, // LATIN SMALL LETTER A WITH DIAERESIS
|
||||||
|
{"a0306", "\xc4\x83"}, // LATIN SMALL LETTER A WITH BREVE
|
||||||
|
{"a0307", "\xc8\xa7"}, // LATIN SMALL LETTER A WITH DOT ABOVE
|
||||||
|
{"a030A", "\xc3\xa5"}, // LATIN SMALL LETTER A WITH RING ABOVE
|
||||||
|
{"a030C", "\xc7\x8e"}, // LATIN SMALL LETTER A WITH CARON
|
||||||
|
{"b0307", "\xe1\xb8\x83"}, // LATIN SMALL LETTER B WITH DOT ABOVE
|
||||||
|
{"c0301", "\xc4\x87"}, // LATIN SMALL LETTER C WITH ACUTE
|
||||||
|
{"c0302", "\xc4\x89"}, // LATIN SMALL LETTER C WITH CIRCUMFLEX
|
||||||
|
{"c0307", "\xc4\x8b"}, // LATIN SMALL LETTER C WITH DOT ABOVE
|
||||||
|
{"c030C", "\xc4\x8d"}, // LATIN SMALL LETTER C WITH CARON
|
||||||
|
{"c0327", "\xc3\xa7"}, // LATIN SMALL LETTER C WITH CEDILLA
|
||||||
|
{"d0307", "\xe1\xb8\x8b"}, // LATIN SMALL LETTER D WITH DOT ABOVE
|
||||||
|
{"d030C", "\xc4\x8f"}, // LATIN SMALL LETTER D WITH CARON
|
||||||
|
{"d0327", "\xe1\xb8\x91"}, // LATIN SMALL LETTER D WITH CEDILLA
|
||||||
|
{"e0300", "\xc3\xa8"}, // LATIN SMALL LETTER E WITH GRAVE
|
||||||
|
{"e0301", "\xc3\xa9"}, // LATIN SMALL LETTER E WITH ACUTE
|
||||||
|
{"e0302", "\xc3\xaa"}, // LATIN SMALL LETTER E WITH CIRCUMFLEX
|
||||||
|
{"e0303", "\xe1\xba\xbd"}, // LATIN SMALL LETTER E WITH TILDE
|
||||||
|
{"e0304", "\xc4\x93"}, // LATIN SMALL LETTER E WITH MACRON
|
||||||
|
{"e0308", "\xc3\xab"}, // LATIN SMALL LETTER E WITH DIAERESIS
|
||||||
|
{"e0306", "\xc4\x95"}, // LATIN SMALL LETTER E WITH BREVE
|
||||||
|
{"e0307", "\xc4\x97"}, // LATIN SMALL LETTER E WITH DOT ABOVE
|
||||||
|
{"e030C", "\xc4\x9b"}, // LATIN SMALL LETTER E WITH CARON
|
||||||
|
{"e0327", "\xc8\xa9"}, // LATIN SMALL LETTER E WITH CEDILLA
|
||||||
|
{"f0307", "\xe1\xb8\x9f"}, // LATIN SMALL LETTER F WITH DOT ABOVE
|
||||||
|
{"g0301", "\xc7\xb5"}, // LATIN SMALL LETTER G WITH ACUTE
|
||||||
|
{"g0302", "\xc4\x9d"}, // LATIN SMALL LETTER G WITH CIRCUMFLEX
|
||||||
|
{"g0304", "\xe1\xb8\xa1"}, // LATIN SMALL LETTER G WITH MACRON
|
||||||
|
{"g0306", "\xc4\x9f"}, // LATIN SMALL LETTER G WITH BREVE
|
||||||
|
{"g0307", "\xc4\xa1"}, // LATIN SMALL LETTER G WITH DOT ABOVE
|
||||||
|
{"g030C", "\xc7\xa7"}, // LATIN SMALL LETTER G WITH CARON
|
||||||
|
{"g0327", "\xc4\xa3"}, // LATIN SMALL LETTER G WITH CEDILLA
|
||||||
|
{"h0302", "\xc4\xa5"}, // LATIN SMALL LETTER H WITH CIRCUMFLEX
|
||||||
|
{"h0308", "\xe1\xb8\xa7"}, // LATIN SMALL LETTER H WITH DIAERESIS
|
||||||
|
{"h0307", "\xe1\xb8\xa3"}, // LATIN SMALL LETTER H WITH DOT ABOVE
|
||||||
|
{"h030C", "\xc8\x9f"}, // LATIN SMALL LETTER H WITH CARON
|
||||||
|
{"h0327", "\xe1\xb8\xa9"}, // LATIN SMALL LETTER H WITH CEDILLA
|
||||||
|
{"i0300", "\xc3\xac"}, // LATIN SMALL LETTER I WITH GRAVE
|
||||||
|
{"i0301", "\xc3\xad"}, // LATIN SMALL LETTER I WITH ACUTE
|
||||||
|
{"i0302", "\xc3\xae"}, // LATIN SMALL LETTER I WITH CIRCUMFLEX
|
||||||
|
{"i0303", "\xc4\xa9"}, // LATIN SMALL LETTER I WITH TILDE
|
||||||
|
{"i0304", "\xc4\xab"}, // LATIN SMALL LETTER I WITH MACRON
|
||||||
|
{"i0308", "\xc3\xaf"}, // LATIN SMALL LETTER I WITH DIAERESIS
|
||||||
|
{"i0306", "\xc4\xad"}, // LATIN SMALL LETTER I WITH BREVE
|
||||||
|
{"i030C", "\xc7\x90"}, // LATIN SMALL LETTER I WITH CARON
|
||||||
|
{"j0302", "\xc4\xb5"}, // LATIN SMALL LETTER J WITH CIRCUMFLEX
|
||||||
|
{"j030C", "\xc7\xb0"}, // LATIN SMALL LETTER J WITH CARON
|
||||||
|
{"k0301", "\xe1\xb8\xb1"}, // LATIN SMALL LETTER K WITH ACUTE
|
||||||
|
{"k030C", "\xc7\xa9"}, // LATIN SMALL LETTER K WITH CARON
|
||||||
|
{"k0327", "\xc4\xb7"}, // LATIN SMALL LETTER K WITH CEDILLA
|
||||||
|
{"l0301", "\xc4\xba"}, // LATIN SMALL LETTER L WITH ACUTE
|
||||||
|
{"l030C", "\xc4\xbe"}, // LATIN SMALL LETTER L WITH CARON
|
||||||
|
{"l0327", "\xc4\xbc"}, // LATIN SMALL LETTER L WITH CEDILLA
|
||||||
|
{"m0301", "\xe1\xb8\xbf"}, // LATIN SMALL LETTER M WITH ACUTE
|
||||||
|
{"m0307", "\xe1\xb9\x81"}, // LATIN SMALL LETTER M WITH DOT ABOVE
|
||||||
|
{"n0300", "\xc7\xb9"}, // LATIN SMALL LETTER N WITH GRAVE
|
||||||
|
{"n0301", "\xc5\x84"}, // LATIN SMALL LETTER N WITH ACUTE
|
||||||
|
{"n0303", "\xc3\xb1"}, // LATIN SMALL LETTER N WITH TILDE
|
||||||
|
{"n0307", "\xe1\xb9\x85"}, // LATIN SMALL LETTER N WITH DOT ABOVE
|
||||||
|
{"n030C", "\xc5\x88"}, // LATIN SMALL LETTER N WITH CARON
|
||||||
|
{"n0327", "\xc5\x86"}, // LATIN SMALL LETTER N WITH CEDILLA
|
||||||
|
{"o0300", "\xc3\xb2"}, // LATIN SMALL LETTER O WITH GRAVE
|
||||||
|
{"o0301", "\xc3\xb3"}, // LATIN SMALL LETTER O WITH ACUTE
|
||||||
|
{"o0302", "\xc3\xb4"}, // LATIN SMALL LETTER O WITH CIRCUMFLEX
|
||||||
|
{"o0303", "\xc3\xb5"}, // LATIN SMALL LETTER O WITH TILDE
|
||||||
|
{"o0304", "\xc5\x8d"}, // LATIN SMALL LETTER O WITH MACRON
|
||||||
|
{"o0308", "\xc3\xb6"}, // LATIN SMALL LETTER O WITH DIAERESIS
|
||||||
|
{"o0306", "\xc5\x8f"}, // LATIN SMALL LETTER O WITH BREVE
|
||||||
|
{"o0307", "\xc8\xaf"}, // LATIN SMALL LETTER O WITH DOT ABOVE
|
||||||
|
{"o030C", "\xc7\x92"}, // LATIN SMALL LETTER O WITH CARON
|
||||||
|
{"o030B", "\xc5\x91"}, // LATIN SMALL LETTER O WITH DOUBLE ACUTE
|
||||||
|
{"p0301", "\xe1\xb9\x95"}, // LATIN SMALL LETTER P WITH ACUTE
|
||||||
|
{"p0307", "\xe1\xb9\x97"}, // LATIN SMALL LETTER P WITH DOT ABOVE
|
||||||
|
{"r0301", "\xc5\x95"}, // LATIN SMALL LETTER R WITH ACUTE
|
||||||
|
{"r0307", "\xe1\xb9\x99"}, // LATIN SMALL LETTER R WITH DOT ABOVE
|
||||||
|
{"r030C", "\xc5\x99"}, // LATIN SMALL LETTER R WITH CARON
|
||||||
|
{"r0327", "\xc5\x97"}, // LATIN SMALL LETTER R WITH CEDILLA
|
||||||
|
{"s0301", "\xc5\x9b"}, // LATIN SMALL LETTER S WITH ACUTE
|
||||||
|
{"s0302", "\xc5\x9d"}, // LATIN SMALL LETTER S WITH CIRCUMFLEX
|
||||||
|
{"s0307", "\xe1\xb9\xa1"}, // LATIN SMALL LETTER S WITH DOT ABOVE
|
||||||
|
{"s030C", "\xc5\xa1"}, // LATIN SMALL LETTER S WITH CARON
|
||||||
|
{"s0327", "\xc5\x9f"}, // LATIN SMALL LETTER S WITH CEDILLA
|
||||||
|
{"t0308", "\xe1\xba\x97"}, // LATIN SMALL LETTER T WITH DIAERESIS
|
||||||
|
{"t0307", "\xe1\xb9\xab"}, // LATIN SMALL LETTER T WITH DOT ABOVE
|
||||||
|
{"t030C", "\xc5\xa5"}, // LATIN SMALL LETTER T WITH CARON
|
||||||
|
{"t0327", "\xc5\xa3"}, // LATIN SMALL LETTER T WITH CEDILLA
|
||||||
|
{"u0300", "\xc3\xb9"}, // LATIN SMALL LETTER U WITH GRAVE
|
||||||
|
{"u0301", "\xc3\xba"}, // LATIN SMALL LETTER U WITH ACUTE
|
||||||
|
{"u0302", "\xc3\xbb"}, // LATIN SMALL LETTER U WITH CIRCUMFLEX
|
||||||
|
{"u0303", "\xc5\xa9"}, // LATIN SMALL LETTER U WITH TILDE
|
||||||
|
{"u0304", "\xc5\xab"}, // LATIN SMALL LETTER U WITH MACRON
|
||||||
|
{"u0308", "\xc3\xbc"}, // LATIN SMALL LETTER U WITH DIAERESIS
|
||||||
|
{"u0306", "\xc5\xad"}, // LATIN SMALL LETTER U WITH BREVE
|
||||||
|
{"u030A", "\xc5\xaf"}, // LATIN SMALL LETTER U WITH RING ABOVE
|
||||||
|
{"u030C", "\xc7\x94"}, // LATIN SMALL LETTER U WITH CARON
|
||||||
|
{"u030B", "\xc5\xb1"}, // LATIN SMALL LETTER U WITH DOUBLE ACUTE
|
||||||
|
{"v0303", "\xe1\xb9\xbd"}, // LATIN SMALL LETTER V WITH TILDE
|
||||||
|
{"w0300", "\xe1\xba\x81"}, // LATIN SMALL LETTER W WITH GRAVE
|
||||||
|
{"w0301", "\xe1\xba\x83"}, // LATIN SMALL LETTER W WITH ACUTE
|
||||||
|
{"w0302", "\xc5\xb5"}, // LATIN SMALL LETTER W WITH CIRCUMFLEX
|
||||||
|
{"w0308", "\xe1\xba\x85"}, // LATIN SMALL LETTER W WITH DIAERESIS
|
||||||
|
{"w0307", "\xe1\xba\x87"}, // LATIN SMALL LETTER W WITH DOT ABOVE
|
||||||
|
{"w030A", "\xe1\xba\x98"}, // LATIN SMALL LETTER W WITH RING ABOVE
|
||||||
|
{"x0308", "\xe1\xba\x8d"}, // LATIN SMALL LETTER X WITH DIAERESIS
|
||||||
|
{"x0307", "\xe1\xba\x8b"}, // LATIN SMALL LETTER X WITH DOT ABOVE
|
||||||
|
{"y0300", "\xe1\xbb\xb3"}, // LATIN SMALL LETTER Y WITH GRAVE
|
||||||
|
{"y0301", "\xc3\xbd"}, // LATIN SMALL LETTER Y WITH ACUTE
|
||||||
|
{"y0302", "\xc5\xb7"}, // LATIN SMALL LETTER Y WITH CIRCUMFLEX
|
||||||
|
{"y0303", "\xe1\xbb\xb9"}, // LATIN SMALL LETTER Y WITH TILDE
|
||||||
|
{"y0304", "\xc8\xb3"}, // LATIN SMALL LETTER Y WITH MACRON
|
||||||
|
{"y0308", "\xc3\xbf"}, // LATIN SMALL LETTER Y WITH DIAERESIS
|
||||||
|
{"y0307", "\xe1\xba\x8f"}, // LATIN SMALL LETTER Y WITH DOT ABOVE
|
||||||
|
{"y030A", "\xe1\xba\x99"}, // LATIN SMALL LETTER Y WITH RING ABOVE
|
||||||
|
{"z0301", "\xc5\xba"}, // LATIN SMALL LETTER Z WITH ACUTE
|
||||||
|
{"z0302", "\xe1\xba\x91"}, // LATIN SMALL LETTER Z WITH CIRCUMFLEX
|
||||||
|
{"z0307", "\xc5\xbc"}, // LATIN SMALL LETTER Z WITH DOT ABOVE
|
||||||
|
{"z030C", "\xc5\xbe"}, // LATIN SMALL LETTER Z WITH CARON
|
||||||
|
{"A0300", "\xc3\x80"}, // LATIN CAPITAL LETTER A WITH GRAVE
|
||||||
|
{"A0301", "\xc3\x81"}, // LATIN CAPITAL LETTER A WITH ACUTE
|
||||||
|
{"A0302", "\xc3\x82"}, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
||||||
|
{"A0303", "\xc3\x83"}, // LATIN CAPITAL LETTER A WITH TILDE
|
||||||
|
{"A0304", "\xc4\x80"}, // LATIN CAPITAL LETTER A WITH MACRON
|
||||||
|
{"A0308", "\xc3\x84"}, // LATIN CAPITAL LETTER A WITH DIAERESIS
|
||||||
|
{"A0306", "\xc4\x82"}, // LATIN CAPITAL LETTER A WITH BREVE
|
||||||
|
{"A0307", "\xc8\xa6"}, // LATIN CAPITAL LETTER A WITH DOT ABOVE
|
||||||
|
{"A030A", "\xc3\x85"}, // LATIN CAPITAL LETTER A WITH RING ABOVE
|
||||||
|
{"A030C", "\xc7\x8d"}, // LATIN CAPITAL LETTER A WITH CARON
|
||||||
|
{"B0307", "\xe1\xb8\x82"}, // LATIN CAPITAL LETTER B WITH DOT ABOVE
|
||||||
|
{"C0301", "\xc4\x86"}, // LATIN CAPITAL LETTER C WITH ACUTE
|
||||||
|
{"C0302", "\xc4\x88"}, // LATIN CAPITAL LETTER C WITH CIRCUMFLEX
|
||||||
|
{"C0307", "\xc4\x8a"}, // LATIN CAPITAL LETTER C WITH DOT ABOVE
|
||||||
|
{"C030C", "\xc4\x8c"}, // LATIN CAPITAL LETTER C WITH CARON
|
||||||
|
{"C0327", "\xc3\x87"}, // LATIN CAPITAL LETTER C WITH CEDILLA
|
||||||
|
{"D0307", "\xe1\xb8\x8a"}, // LATIN CAPITAL LETTER D WITH DOT ABOVE
|
||||||
|
{"D030C", "\xc4\x8e"}, // LATIN CAPITAL LETTER D WITH CARON
|
||||||
|
{"D0327", "\xe1\xb8\x90"}, // LATIN CAPITAL LETTER D WITH CEDILLA
|
||||||
|
{"E0300", "\xc3\x88"}, // LATIN CAPITAL LETTER E WITH GRAVE
|
||||||
|
{"E0301", "\xc3\x89"}, // LATIN CAPITAL LETTER E WITH ACUTE
|
||||||
|
{"E0302", "\xc3\x8a"}, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
||||||
|
{"E0303", "\xe1\xba\xbc"}, // LATIN CAPITAL LETTER E WITH TILDE
|
||||||
|
{"E0304", "\xc4\x92"}, // LATIN CAPITAL LETTER E WITH MACRON
|
||||||
|
{"E0308", "\xc3\x8b"}, // LATIN CAPITAL LETTER E WITH DIAERESIS
|
||||||
|
{"E0306", "\xc4\x94"}, // LATIN CAPITAL LETTER E WITH BREVE
|
||||||
|
{"E0307", "\xc4\x96"}, // LATIN CAPITAL LETTER E WITH DOT ABOVE
|
||||||
|
{"E030C", "\xc4\x9a"}, // LATIN CAPITAL LETTER E WITH CARON
|
||||||
|
{"E0327", "\xc8\xa8"}, // LATIN CAPITAL LETTER E WITH CEDILLA
|
||||||
|
{"F0307", "\xe1\xb8\x9e"}, // LATIN CAPITAL LETTER F WITH DOT ABOVE
|
||||||
|
{"G0301", "\xc7\xb4"}, // LATIN CAPITAL LETTER G WITH ACUTE
|
||||||
|
{"G0302", "\xc4\x9c"}, // LATIN CAPITAL LETTER G WITH CIRCUMFLEX
|
||||||
|
{"G0304", "\xe1\xb8\xa0"}, // LATIN CAPITAL LETTER G WITH MACRON
|
||||||
|
{"G0306", "\xc4\x9e"}, // LATIN CAPITAL LETTER G WITH BREVE
|
||||||
|
{"G0307", "\xc4\xa0"}, // LATIN CAPITAL LETTER G WITH DOT ABOVE
|
||||||
|
{"G030C", "\xc7\xa6"}, // LATIN CAPITAL LETTER G WITH CARON
|
||||||
|
{"G0327", "\xc4\xa2"}, // LATIN CAPITAL LETTER G WITH CEDILLA
|
||||||
|
{"H0302", "\xc4\xa4"}, // LATIN CAPITAL LETTER H WITH CIRCUMFLEX
|
||||||
|
{"H0308", "\xe1\xb8\xa6"}, // LATIN CAPITAL LETTER H WITH DIAERESIS
|
||||||
|
{"H0307", "\xe1\xb8\xa2"}, // LATIN CAPITAL LETTER H WITH DOT ABOVE
|
||||||
|
{"H030C", "\xc8\x9e"}, // LATIN CAPITAL LETTER H WITH CARON
|
||||||
|
{"H0327", "\xe1\xb8\xa8"}, // LATIN CAPITAL LETTER H WITH CEDILLA
|
||||||
|
{"I0300", "\xc3\x8c"}, // LATIN CAPITAL LETTER I WITH GRAVE
|
||||||
|
{"I0301", "\xc3\x8d"}, // LATIN CAPITAL LETTER I WITH ACUTE
|
||||||
|
{"I0302", "\xc3\x8e"}, // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
||||||
|
{"I0303", "\xc4\xa8"}, // LATIN CAPITAL LETTER I WITH TILDE
|
||||||
|
{"I0304", "\xc4\xaa"}, // LATIN CAPITAL LETTER I WITH MACRON
|
||||||
|
{"I0308", "\xc3\x8f"}, // LATIN CAPITAL LETTER I WITH DIAERESIS
|
||||||
|
{"I0306", "\xc4\xac"}, // LATIN CAPITAL LETTER I WITH BREVE
|
||||||
|
{"I0307", "\xc4\xb0"}, // LATIN CAPITAL LETTER I WITH DOT ABOVE
|
||||||
|
{"I030C", "\xc7\x8f"}, // LATIN CAPITAL LETTER I WITH CARON
|
||||||
|
{"J0302", "\xc4\xb4"}, // LATIN CAPITAL LETTER J WITH CIRCUMFLEX
|
||||||
|
{"K0301", "\xe1\xb8\xb0"}, // LATIN CAPITAL LETTER K WITH ACUTE
|
||||||
|
{"K030C", "\xc7\xa8"}, // LATIN CAPITAL LETTER K WITH CARON
|
||||||
|
{"K0327", "\xc4\xb6"}, // LATIN CAPITAL LETTER K WITH CEDILLA
|
||||||
|
{"L0301", "\xc4\xb9"}, // LATIN CAPITAL LETTER L WITH ACUTE
|
||||||
|
{"L030C", "\xc4\xbd"}, // LATIN CAPITAL LETTER L WITH CARON
|
||||||
|
{"L0327", "\xc4\xbb"}, // LATIN CAPITAL LETTER L WITH CEDILLA
|
||||||
|
{"M0301", "\xe1\xb8\xbe"}, // LATIN CAPITAL LETTER M WITH ACUTE
|
||||||
|
{"M0307", "\xe1\xb9\x80"}, // LATIN CAPITAL LETTER M WITH DOT ABOVE
|
||||||
|
{"N0300", "\xc7\xb8"}, // LATIN CAPITAL LETTER N WITH GRAVE
|
||||||
|
{"N0301", "\xc5\x83"}, // LATIN CAPITAL LETTER N WITH ACUTE
|
||||||
|
{"N0303", "\xc3\x91"}, // LATIN CAPITAL LETTER N WITH TILDE
|
||||||
|
{"N0307", "\xe1\xb9\x84"}, // LATIN CAPITAL LETTER N WITH DOT ABOVE
|
||||||
|
{"N030C", "\xc5\x87"}, // LATIN CAPITAL LETTER N WITH CARON
|
||||||
|
{"N0327", "\xc5\x85"}, // LATIN CAPITAL LETTER N WITH CEDILLA
|
||||||
|
{"O0300", "\xc3\x92"}, // LATIN CAPITAL LETTER O WITH GRAVE
|
||||||
|
{"O0301", "\xc3\x93"}, // LATIN CAPITAL LETTER O WITH ACUTE
|
||||||
|
{"O0302", "\xc3\x94"}, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
||||||
|
{"O0303", "\xc3\x95"}, // LATIN CAPITAL LETTER O WITH TILDE
|
||||||
|
{"O0304", "\xc5\x8c"}, // LATIN CAPITAL LETTER O WITH MACRON
|
||||||
|
{"O0308", "\xc3\x96"}, // LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||||
|
{"O0306", "\xc5\x8e"}, // LATIN CAPITAL LETTER O WITH BREVE
|
||||||
|
{"O0307", "\xc8\xae"}, // LATIN CAPITAL LETTER O WITH DOT ABOVE
|
||||||
|
{"O030C", "\xc7\x91"}, // LATIN CAPITAL LETTER O WITH CARON
|
||||||
|
{"O030B", "\xc5\x90"}, // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
|
||||||
|
{"P0301", "\xe1\xb9\x94"}, // LATIN CAPITAL LETTER P WITH ACUTE
|
||||||
|
{"P0307", "\xe1\xb9\x96"}, // LATIN CAPITAL LETTER P WITH DOT ABOVE
|
||||||
|
{"R0301", "\xc5\x94"}, // LATIN CAPITAL LETTER R WITH ACUTE
|
||||||
|
{"R0307", "\xe1\xb9\x98"}, // LATIN CAPITAL LETTER R WITH DOT ABOVE
|
||||||
|
{"R030C", "\xc5\x98"}, // LATIN CAPITAL LETTER R WITH CARON
|
||||||
|
{"R0327", "\xc5\x96"}, // LATIN CAPITAL LETTER R WITH CEDILLA
|
||||||
|
{"S0301", "\xc5\x9a"}, // LATIN CAPITAL LETTER S WITH ACUTE
|
||||||
|
{"S0302", "\xc5\x9c"}, // LATIN CAPITAL LETTER S WITH CIRCUMFLEX
|
||||||
|
{"S0307", "\xe1\xb9\xa0"}, // LATIN CAPITAL LETTER S WITH DOT ABOVE
|
||||||
|
{"S030C", "\xc5\xa0"}, // LATIN CAPITAL LETTER S WITH CARON
|
||||||
|
{"S0327", "\xc5\x9e"}, // LATIN CAPITAL LETTER S WITH CEDILLA
|
||||||
|
{"T0307", "\xe1\xb9\xaa"}, // LATIN CAPITAL LETTER T WITH DOT ABOVE
|
||||||
|
{"T030C", "\xc5\xa4"}, // LATIN CAPITAL LETTER T WITH CARON
|
||||||
|
{"T0327", "\xc5\xa2"}, // LATIN CAPITAL LETTER T WITH CEDILLA
|
||||||
|
{"U0300", "\xc3\x99"}, // LATIN CAPITAL LETTER U WITH GRAVE
|
||||||
|
{"U0301", "\xc3\x9a"}, // LATIN CAPITAL LETTER U WITH ACUTE
|
||||||
|
{"U0302", "\xc3\x9b"}, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
||||||
|
{"U0303", "\xc5\xa8"}, // LATIN CAPITAL LETTER U WITH TILDE
|
||||||
|
{"U0304", "\xc5\xaa"}, // LATIN CAPITAL LETTER U WITH MACRON
|
||||||
|
{"U0308", "\xc3\x9c"}, // LATIN CAPITAL LETTER U WITH DIAERESIS
|
||||||
|
{"U0306", "\xc5\xac"}, // LATIN CAPITAL LETTER U WITH BREVE
|
||||||
|
{"U030A", "\xc5\xae"}, // LATIN CAPITAL LETTER U WITH RING ABOVE
|
||||||
|
{"U030C", "\xc7\x93"}, // LATIN CAPITAL LETTER U WITH CARON
|
||||||
|
{"U030B", "\xc5\xb0"}, // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
|
||||||
|
{"V0303", "\xe1\xb9\xbc"}, // LATIN CAPITAL LETTER V WITH TILDE
|
||||||
|
{"W0300", "\xe1\xba\x80"}, // LATIN CAPITAL LETTER W WITH GRAVE
|
||||||
|
{"W0301", "\xe1\xba\x82"}, // LATIN CAPITAL LETTER W WITH ACUTE
|
||||||
|
{"W0302", "\xc5\xb4"}, // LATIN CAPITAL LETTER W WITH CIRCUMFLEX
|
||||||
|
{"W0308", "\xe1\xba\x84"}, // LATIN CAPITAL LETTER W WITH DIAERESIS
|
||||||
|
{"W0307", "\xe1\xba\x86"}, // LATIN CAPITAL LETTER W WITH DOT ABOVE
|
||||||
|
{"X0308", "\xe1\xba\x8c"}, // LATIN CAPITAL LETTER X WITH DIAERESIS
|
||||||
|
{"X0307", "\xe1\xba\x8a"}, // LATIN CAPITAL LETTER X WITH DOT ABOVE
|
||||||
|
{"Y0300", "\xe1\xbb\xb2"}, // LATIN CAPITAL LETTER Y WITH GRAVE
|
||||||
|
{"Y0301", "\xc3\x9d"}, // LATIN CAPITAL LETTER Y WITH ACUTE
|
||||||
|
{"Y0302", "\xc5\xb6"}, // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
|
||||||
|
{"Y0303", "\xe1\xbb\xb8"}, // LATIN CAPITAL LETTER Y WITH TILDE
|
||||||
|
{"Y0304", "\xc8\xb2"}, // LATIN CAPITAL LETTER Y WITH MACRON
|
||||||
|
{"Y0308", "\xc5\xb8"}, // LATIN CAPITAL LETTER Y WITH DIAERESIS
|
||||||
|
{"Y0307", "\xe1\xba\x8e"}, // LATIN CAPITAL LETTER Y WITH DOT ABOVE
|
||||||
|
{"Z0301", "\xc5\xb9"}, // LATIN CAPITAL LETTER Z WITH ACUTE
|
||||||
|
{"Z0302", "\xe1\xba\x90"}, // LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
|
||||||
|
{"Z0307", "\xc5\xbb"}, // LATIN CAPITAL LETTER Z WITH DOT ABOVE
|
||||||
|
{"Z030C", "\xc5\xbd"}, // LATIN CAPITAL LETTER Z WITH CARON
|
||||||
|
};
|
||||||
@@ -278,8 +278,8 @@ class Code(klammer_base.Klammer_base):
|
|||||||
return measure + L.add_caption(
|
return measure + L.add_caption(
|
||||||
boxed, "Listing", self.number, self.caption, width,
|
boxed, "Listing", self.number, self.caption, width,
|
||||||
hpos=self.hpos, side=self.caption_side,
|
hpos=self.hpos, side=self.caption_side,
|
||||||
font_symbol=self.caption_font,
|
font_symbol=self.caption_style,
|
||||||
font_size=self.caption_font_size, offset=self.offset)
|
font_size=self.caption_size, offset=self.offset)
|
||||||
return measure + L.caption_wrapper(boxed, self.hpos,
|
return measure + L.caption_wrapper(boxed, self.hpos,
|
||||||
offset=self.offset)
|
offset=self.offset)
|
||||||
|
|
||||||
@@ -298,7 +298,7 @@ class Code(klammer_base.Klammer_base):
|
|||||||
if captioned:
|
if captioned:
|
||||||
caption = L.make_caption_text(
|
caption = L.make_caption_text(
|
||||||
self.number, "Listing", self.caption,
|
self.number, "Listing", self.caption,
|
||||||
self.caption_font, self.caption_font_size)
|
self.caption_style, self.caption_size)
|
||||||
# \nobreak: a caption must not be separated from its listing by
|
# \nobreak: a caption must not be separated from its listing by
|
||||||
# a page break, even though the listing itself may break.
|
# a page break, even though the listing itself may break.
|
||||||
block = (f"\\noindent\\hspace*{{{shift}}}"
|
block = (f"\\noindent\\hspace*{{{shift}}}"
|
||||||
@@ -327,8 +327,8 @@ class Code(klammer_base.Klammer_base):
|
|||||||
if self.number or self.caption:
|
if self.number or self.caption:
|
||||||
return html_util.add_caption(
|
return html_util.add_caption(
|
||||||
listing, "Listing", self.number, self.caption,
|
listing, "Listing", self.number, self.caption,
|
||||||
self.caption_font, self.hpos, self.caption_side, True,
|
self.caption_style, self.hpos, self.caption_side, True,
|
||||||
self.caption_font_size, offset=self.offset)
|
self.caption_size, offset=self.offset)
|
||||||
return html_util.hpos_container(listing, self.hpos, self.offset).str()
|
return html_util.hpos_container(listing, self.hpos, self.offset).str()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -40,10 +40,10 @@
|
|||||||
:include_sks_js.bool true
|
:include_sks_js.bool true
|
||||||
:include_fonts.bool true
|
:include_fonts.bool true
|
||||||
|
|
||||||
:serif_font Crimson Pro
|
:serif_typeface Crimson Pro
|
||||||
:sans_font Open Sans
|
:sans_typeface Open Sans
|
||||||
:mono_font Inconsolata
|
:mono_typeface Inconsolata
|
||||||
:font_scale 1.0
|
:text_scale 1.0
|
||||||
|
|
||||||
:landscape.bool.tex false
|
:landscape.bool.tex false
|
||||||
:paper_size..tex a4paper
|
:paper_size..tex a4paper
|
||||||
|
|||||||
+143
-10
@@ -31,6 +31,10 @@ Document_class::Document_class(Machine& machine) : Klammer_base(machine)
|
|||||||
// show("document in main SKS");
|
// show("document in main SKS");
|
||||||
m_machine = machine;
|
m_machine = machine;
|
||||||
sloc = get("K_loc");
|
sloc = get("K_loc");
|
||||||
|
// The klammer's own position, so an argument error points at the
|
||||||
|
// @document application rather than at document_class.cpp: a
|
||||||
|
// default-constructed Locator captures the C++ source location.
|
||||||
|
loc = Locator::from_string(sloc);
|
||||||
m_title = get("title");
|
m_title = get("title");
|
||||||
m_subtitle = get("subtitle");
|
m_subtitle = get("subtitle");
|
||||||
m_page_title = get("page_title");
|
m_page_title = get("page_title");
|
||||||
@@ -77,17 +81,17 @@ Document_class::Document_class(Machine& machine) : Klammer_base(machine)
|
|||||||
s = s.substr(1, s.size() - 2);
|
s = s.substr(1, s.size() - 2);
|
||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
m_serif_font = strip_quotes(get("serif_font"));
|
m_serif_typeface = strip_quotes(get("serif_typeface"));
|
||||||
m_sans_font = strip_quotes(get("sans_font"));
|
m_sans_typeface = strip_quotes(get("sans_typeface"));
|
||||||
m_mono_font = strip_quotes(get("mono_font"));
|
m_mono_typeface = strip_quotes(get("mono_typeface"));
|
||||||
m_font_scale = stof(get("font_scale"));
|
m_text_scale = stof(get("text_scale"));
|
||||||
|
|
||||||
if (!m_serif_font.empty())
|
if (!m_serif_typeface.empty())
|
||||||
m_resolved_serif = resolve_font(m_serif_font);
|
m_resolved_serif = resolve_font(m_serif_typeface, loc);
|
||||||
if (!m_sans_font.empty())
|
if (!m_sans_typeface.empty())
|
||||||
m_resolved_sans = resolve_font(m_sans_font);
|
m_resolved_sans = resolve_font(m_sans_typeface, loc);
|
||||||
if (!m_mono_font.empty())
|
if (!m_mono_typeface.empty())
|
||||||
m_resolved_mono = resolve_font(m_mono_font);
|
m_resolved_mono = resolve_font(m_mono_typeface, loc);
|
||||||
paper_size = get("paper_size");
|
paper_size = get("paper_size");
|
||||||
landscape = strbool(get("landscape"), loc);
|
landscape = strbool(get("landscape"), loc);
|
||||||
leading = stof(get("leading"));
|
leading = stof(get("leading"));
|
||||||
@@ -207,6 +211,135 @@ void write_file(const std::string& filename, const std::string& contents, bool w
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// Typeface markers (@typeface; see the marker note in sks/font/font.py)
|
||||||
|
//
|
||||||
|
// Hand-rolled scanning, no std::regex: these run over the whole assembled
|
||||||
|
// document and libstdc++'s regex executor recurses per character (the
|
||||||
|
// documented SIGSEGV hazard).
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const std::string typeface_tag { "__TYPEFACE__" };
|
||||||
|
|
||||||
|
// The next marker at or after `from`. Returns false when there is none.
|
||||||
|
// A marker is __TYPEFACE__<name>__<scale>__ : the two fields are taken up
|
||||||
|
// to the next "__", so neither may contain one (a typeface name with a
|
||||||
|
// double underscore is not a thing, and the scale is a number).
|
||||||
|
bool next_typeface_marker(const std::string& text, size_t from,
|
||||||
|
size_t& start, size_t& end,
|
||||||
|
std::string& name, std::string& scale)
|
||||||
|
{
|
||||||
|
start = text.find(typeface_tag, from);
|
||||||
|
if (start == std::string::npos) return false;
|
||||||
|
size_t name_at = start + typeface_tag.size();
|
||||||
|
size_t name_end = text.find("__", name_at);
|
||||||
|
if (name_end == std::string::npos) return false;
|
||||||
|
size_t scale_at = name_end + 2;
|
||||||
|
size_t scale_end = text.find("__", scale_at);
|
||||||
|
if (scale_end == std::string::npos) return false;
|
||||||
|
name = text.substr(name_at, name_end - name_at);
|
||||||
|
scale = text.substr(scale_at, scale_end - scale_at);
|
||||||
|
end = scale_end + 2;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The fontspec command name for the nth distinct (typeface, scale) pair.
|
||||||
|
// A TeX command name may hold only letters, and a typeface name may hold
|
||||||
|
// anything -- so the pairs are NUMBERED rather than transliterated, and
|
||||||
|
// the number is turned into letters. Nothing outside this file needs to
|
||||||
|
// know the rule: the klammer leaves a marker and this replaces it, so
|
||||||
|
// there is no second implementation to keep in step.
|
||||||
|
std::string typeface_command(size_t index)
|
||||||
|
{
|
||||||
|
std::string suffix {};
|
||||||
|
do {
|
||||||
|
suffix = char('a' + (index % 26)) + suffix;
|
||||||
|
index /= 26;
|
||||||
|
} while (index > 0);
|
||||||
|
return "\\ktface" + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void Document_class::collect_typefaces(const std::string& text)
|
||||||
|
{
|
||||||
|
size_t pos = 0, start = 0, end = 0;
|
||||||
|
std::string name {}, scale {};
|
||||||
|
while (next_typeface_marker(text, pos, start, end, name, scale)) {
|
||||||
|
std::pair<std::string, std::string> entry { name, scale };
|
||||||
|
if (std::find(m_extra_typefaces.begin(), m_extra_typefaces.end(), entry)
|
||||||
|
== m_extra_typefaces.end()) {
|
||||||
|
m_extra_typefaces.push_back(entry);
|
||||||
|
// Resolve ONCE per distinct typeface: resolve_font() throws a
|
||||||
|
// located error naming the available typefaces if the store
|
||||||
|
// does not have it, which is the whole error path for a
|
||||||
|
// misspelled or uninstalled typeface.
|
||||||
|
bool seen = false;
|
||||||
|
for (const auto& rf : m_resolved_extra)
|
||||||
|
if (rf.family_name == name) seen = true;
|
||||||
|
if (!seen) {
|
||||||
|
// What a @typeface klammer asked for, and what the store
|
||||||
|
// resolved it to: a decision the user cannot read off
|
||||||
|
// their own input, so "-v 1".
|
||||||
|
Resolved_font rf = resolve_font(name, loc);
|
||||||
|
(void)K::log(1, "Typeface \"" + name + "\" resolved to:",
|
||||||
|
rf.font_dir);
|
||||||
|
m_resolved_extra.push_back(rf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pos = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Document_class::strip_typeface_markers(const std::string& text)
|
||||||
|
{
|
||||||
|
std::string result {};
|
||||||
|
size_t pos = 0, start = 0, end = 0;
|
||||||
|
std::string name {}, scale {};
|
||||||
|
while (next_typeface_marker(text, pos, start, end, name, scale)) {
|
||||||
|
result += text.substr(pos, start - pos);
|
||||||
|
pos = end;
|
||||||
|
}
|
||||||
|
result += text.substr(pos);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Document_class::resolve_typeface_markers(const std::string& text)
|
||||||
|
{
|
||||||
|
std::string result {};
|
||||||
|
size_t pos = 0, start = 0, end = 0;
|
||||||
|
std::string name {}, scale {};
|
||||||
|
while (next_typeface_marker(text, pos, start, end, name, scale)) {
|
||||||
|
result += text.substr(pos, start - pos);
|
||||||
|
auto entry = std::make_pair(name, scale);
|
||||||
|
auto it = std::find(m_extra_typefaces.begin(), m_extra_typefaces.end(), entry);
|
||||||
|
if (it != m_extra_typefaces.end())
|
||||||
|
result += typeface_command(it - m_extra_typefaces.begin());
|
||||||
|
pos = end;
|
||||||
|
}
|
||||||
|
result += text.substr(pos);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Document_class::typeface_preamble()
|
||||||
|
{
|
||||||
|
std::stringstream ss {};
|
||||||
|
for (size_t i = 0; i < m_extra_typefaces.size(); i++) {
|
||||||
|
const auto& [name, scale] = m_extra_typefaces[i];
|
||||||
|
const Resolved_font* rf = nullptr;
|
||||||
|
for (const auto& f : m_resolved_extra)
|
||||||
|
if (f.family_name == name) rf = &f;
|
||||||
|
if (!rf) continue;
|
||||||
|
// \newfontfamily declares a switch command, unlike \setmainfont,
|
||||||
|
// which changes the document's font permanently.
|
||||||
|
ss << latex::font_command("newfontfamily" + typeface_command(i),
|
||||||
|
*rf, stof(scale));
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void output_msg(const std::string& msg)
|
void output_msg(const std::string& msg)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -121,14 +121,35 @@ public:
|
|||||||
|
|
||||||
strings_t m_font_dirs {};
|
strings_t m_font_dirs {};
|
||||||
|
|
||||||
std::string m_serif_font {};
|
std::string m_serif_typeface {};
|
||||||
std::string m_sans_font {};
|
std::string m_sans_typeface {};
|
||||||
std::string m_mono_font {};
|
std::string m_mono_typeface {};
|
||||||
float m_font_scale = 1.0f;
|
float m_text_scale = 1.0f;
|
||||||
Resolved_font m_resolved_serif {};
|
Resolved_font m_resolved_serif {};
|
||||||
Resolved_font m_resolved_sans {};
|
Resolved_font m_resolved_sans {};
|
||||||
Resolved_font m_resolved_mono {};
|
Resolved_font m_resolved_mono {};
|
||||||
|
|
||||||
|
// Typefaces requested by @typeface klammers inside the document, in
|
||||||
|
// first-appearance order, each with the scale it was asked for. A
|
||||||
|
// klammer cannot declare a typeface itself (see font.py's
|
||||||
|
// typeface_marker), so it leaves a marker and @document collects them
|
||||||
|
// here, resolves and localizes each, declares it, and replaces every
|
||||||
|
// marker with the target's inline switch.
|
||||||
|
// SYNC: typeface_marker() in sks/font/font.py builds this marker.
|
||||||
|
std::vector<std::pair<std::string, std::string>> m_extra_typefaces {};
|
||||||
|
std::vector<Resolved_font> m_resolved_extra {};
|
||||||
|
// Collect the (typeface, scale) pairs of `text` into
|
||||||
|
// m_extra_typefaces, resolving each typeface once. Returns nothing;
|
||||||
|
// the markers are replaced by the per-target functions below.
|
||||||
|
void collect_typefaces(const std::string& text);
|
||||||
|
// html: the marker carries no inline switch (the span holds the family
|
||||||
|
// name), so each is replaced by nothing.
|
||||||
|
std::string strip_typeface_markers(const std::string& text);
|
||||||
|
// tex: each distinct (typeface, scale) gets a \newfontfamily command in
|
||||||
|
// the preamble; the marker is replaced by that command.
|
||||||
|
std::string resolve_typeface_markers(const std::string& text);
|
||||||
|
std::string typeface_preamble();
|
||||||
|
|
||||||
std::string prolog {};
|
std::string prolog {};
|
||||||
std::string paper_size {};
|
std::string paper_size {};
|
||||||
bool m_two_column = false;
|
bool m_two_column = false;
|
||||||
|
|||||||
@@ -93,24 +93,28 @@ strings_t Document_class::resolved_font_names()
|
|||||||
add(m_resolved_serif);
|
add(m_resolved_serif);
|
||||||
add(m_resolved_sans);
|
add(m_resolved_sans);
|
||||||
add(m_resolved_mono);
|
add(m_resolved_mono);
|
||||||
|
// Typefaces a @typeface klammer asked for: each needs its own <link>
|
||||||
|
// to the localized css, which is what carries the @font-face.
|
||||||
|
for (const auto& rf : m_resolved_extra)
|
||||||
|
add(rf);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Document_class::font_definitions()
|
std::string Document_class::font_definitions()
|
||||||
{
|
{
|
||||||
std::stringstream ss {};
|
std::stringstream ss {};
|
||||||
if (!m_serif_font.empty() || !m_sans_font.empty() || !m_mono_font.empty()) {
|
if (!m_serif_typeface.empty() || !m_sans_typeface.empty() || !m_mono_typeface.empty()) {
|
||||||
// Family names are quoted: an unquoted name with a digit-initial
|
// Family names are quoted: an unquoted name with a digit-initial
|
||||||
// word ("Source Sans 3") is invalid CSS, and a font-family using
|
// word ("Source Sans 3") is invalid CSS, and a font-family using
|
||||||
// var() with such a value computes to inherit, silently losing
|
// var() with such a value computes to inherit, silently losing
|
||||||
// the font.
|
// the font.
|
||||||
ss << ":root {\n";
|
ss << ":root {\n";
|
||||||
if (!m_serif_font.empty())
|
if (!m_serif_typeface.empty())
|
||||||
ss << " --serif: \"" << m_serif_font << "\", serif;\n";
|
ss << " --serif: \"" << m_serif_typeface << "\", serif;\n";
|
||||||
if (!m_sans_font.empty())
|
if (!m_sans_typeface.empty())
|
||||||
ss << " --sans-serif: \"" << m_sans_font << "\", sans-serif;\n";
|
ss << " --sans-serif: \"" << m_sans_typeface << "\", sans-serif;\n";
|
||||||
if (!m_mono_font.empty())
|
if (!m_mono_typeface.empty())
|
||||||
ss << " --monospace: \"" << m_mono_font << "\", monospace;\n";
|
ss << " --monospace: \"" << m_mono_typeface << "\", monospace;\n";
|
||||||
ss << "}\n";
|
ss << "}\n";
|
||||||
}
|
}
|
||||||
// Font-size normalization across families is no longer emitted from
|
// Font-size normalization across families is no longer emitted from
|
||||||
@@ -120,11 +124,11 @@ std::string Document_class::font_definitions()
|
|||||||
// factors did from build-time OS/2 metrics, but applied to EVERY family
|
// factors did from build-time OS/2 metrics, but applied to EVERY family
|
||||||
// switch instead of the four CSS sites that remembered to multiply.
|
// switch instead of the four CSS sites that remembered to multiply.
|
||||||
// The metric extraction in the font store remains (the tex path and
|
// The metric extraction in the font store remains (the tex path and
|
||||||
// kdesc --font still use it).
|
// kdesc --typeface still use it).
|
||||||
// Global font scale: applied to body font-size
|
// Global font scale: applied to body font-size
|
||||||
if (m_font_scale != 1.0f) {
|
if (m_text_scale != 1.0f) {
|
||||||
char buf[16];
|
char buf[16];
|
||||||
std::snprintf(buf, sizeof(buf), "%.4f", m_font_scale);
|
std::snprintf(buf, sizeof(buf), "%.4f", m_text_scale);
|
||||||
ss << "body { font-size: " << buf << "rem; }\n";
|
ss << "body { font-size: " << buf << "rem; }\n";
|
||||||
}
|
}
|
||||||
return ss.str();
|
return ss.str();
|
||||||
@@ -743,6 +747,22 @@ std::string Document_class::html()
|
|||||||
std::string output_directory = create_html_output_directories();
|
std::string output_directory = create_html_output_directories();
|
||||||
save_string_input_as_file();
|
save_string_input_as_file();
|
||||||
process_input_files();
|
process_input_files();
|
||||||
|
// @typeface markers are collected AFTER processing (a klammer cannot
|
||||||
|
// declare a typeface itself) but BEFORE the page is assembled, so the
|
||||||
|
// localized files and the <link> to each typeface's css are in place
|
||||||
|
// when make_*_html_page() runs. The markers survive into the page
|
||||||
|
// CACHE deliberately: a cached file must still declare its typefaces
|
||||||
|
// on a later run, so the stripping happens here, on the assembled
|
||||||
|
// components, not before write_to_cache().
|
||||||
|
for (auto& [basename, text] : m_file_components) {
|
||||||
|
collect_typefaces(text);
|
||||||
|
}
|
||||||
|
for (const auto& rf : m_resolved_extra) {
|
||||||
|
install_resolved_font(rf, output_directory);
|
||||||
|
}
|
||||||
|
for (auto& [basename, text] : m_file_components) {
|
||||||
|
text = strip_typeface_markers(text);
|
||||||
|
}
|
||||||
auto headings = insert_section_numbers();
|
auto headings = insert_section_numbers();
|
||||||
insert_section_numbers("___NUM2___", false);
|
insert_section_numbers("___NUM2___", false);
|
||||||
insert_html_caption_numbers();
|
insert_html_caption_numbers();
|
||||||
|
|||||||
@@ -72,6 +72,14 @@ std::string Document_class::tex()
|
|||||||
}
|
}
|
||||||
latex_text = join(lines, "\n");
|
latex_text = join(lines, "\n");
|
||||||
latex_text = string_replace(latex_text, "___AT___", "^@");
|
latex_text = string_replace(latex_text, "___AT___", "^@");
|
||||||
|
// @typeface: collect what the document asked for, declare each as a
|
||||||
|
// \newfontfamily switch command in the preamble, and replace every
|
||||||
|
// marker with its command. The declarations are appended to the
|
||||||
|
// prolog, which latex::page emits AFTER \setmainfont -- so fontspec is
|
||||||
|
// loaded and \newfontfamily is valid there.
|
||||||
|
collect_typefaces(latex_text);
|
||||||
|
latex_text = resolve_typeface_markers(latex_text);
|
||||||
|
prolog += typeface_preamble();
|
||||||
std::string structure_name =
|
std::string structure_name =
|
||||||
m_structure == docstruct_t::book ? "book" :
|
m_structure == docstruct_t::book ? "book" :
|
||||||
m_structure == docstruct_t::article ? "article" : "plain";
|
m_structure == docstruct_t::article ? "article" : "plain";
|
||||||
@@ -81,5 +89,5 @@ std::string Document_class::tex()
|
|||||||
point_size, ragged_right,
|
point_size, ragged_right,
|
||||||
cover, landscape, latex_text,
|
cover, landscape, latex_text,
|
||||||
m_resolved_serif, m_resolved_sans, m_resolved_mono,
|
m_resolved_serif, m_resolved_sans, m_resolved_mono,
|
||||||
m_font_scale);
|
m_text_scale);
|
||||||
}
|
}
|
||||||
+43
-16
@@ -2,28 +2,44 @@
|
|||||||
@@@state font_dirs :desc Directories containing local fonts @@@
|
@@@state font_dirs :desc Directories containing local fonts @@@
|
||||||
|
|
||||||
|
|
||||||
@@@argtype font |
|
@@@argtype style_code |
|
||||||
an abbreivation for a font
|
a style code: one letter naming a type style
|
||||||
:pattern r^|i^|b^|s^|t^|c
|
:pattern r^|i^|b^|s^|t^|c
|
||||||
@@@
|
@@@
|
||||||
|
|
||||||
@@@argtype font_list |
|
@@@argtype style_code_list |
|
||||||
a list of font symbols. One or more of 'r' (roman), 'i' (italic),
|
a list of style codes. One or more of 'r' (roman), 'i' (italic),
|
||||||
'b' (bold), 's' (sans-serif), 't' (typewriter or monospace) or 'c'
|
'b' (bold), 's' (sans-serif), 't' (typewriter or monospace) or 'c'
|
||||||
(code) for each cell in a row. If there are fewer font symbols than
|
(code) for each cell in a row. If there are fewer style codes than
|
||||||
cells in a row, the last symbol is repeated. Extra symbols are
|
cells in a row, the last code is repeated. Extra codes are
|
||||||
ignored.
|
ignored.
|
||||||
:pattern ('font'^|\s)+
|
:pattern ('style_code'^|\s)+
|
||||||
:python_cast (lambda s : s.split())
|
:python_cast (lambda s : s.split())
|
||||||
:default r
|
:default r
|
||||||
@@@
|
@@@
|
||||||
|
|
||||||
@@font.k fontname : Switch to an available font for PDF output. @@
|
#[
|
||||||
|
@font was retired 2026-08-25 and replaced by @typeface. It switched the
|
||||||
|
main font PERMANENTLY (a bare \setmainfont, no group) for tex, and for
|
||||||
|
html and txt its body was "*fontname*" -- so it printed the NAME of the
|
||||||
|
font as document text instead of setting anything. @typeface is the
|
||||||
|
temporary, all-target replacement.
|
||||||
|
]#
|
||||||
|
|
||||||
@@font.html :: *fontname* @@
|
@@typeface.k name | text :scale.float 1.0 :
|
||||||
@@font.tex :: \setmainfont[Ligatures=TeX]{*fontname*} @@
|
A temporary change of typeface for *text*: the typeface *name* is
|
||||||
# @@font.tex : \setmainfont[Ligatures=TeX,Numbers=Lining]{*fontname*} @@
|
resolved in the Klammertext font store (the directories of
|
||||||
@@font.txt :: *fontname* @@
|
KLAMMERTEXT_FONTS, then the distribution's own), and the document
|
||||||
|
declares and localizes it automatically -- writing this klammer is the
|
||||||
|
only declaration needed. *scale* multiplies the surrounding text size,
|
||||||
|
which a script whose glyphs are drawn small usually wants.
|
||||||
|
|
||||||
|
The change ends with *text*: nothing after it is affected. Under the
|
||||||
|
txt target a typeface cannot be expressed at all, so *text* is emitted
|
||||||
|
unchanged.
|
||||||
|
@@
|
||||||
|
|
||||||
|
@@typeface.html,tex,txt :: @eval font.Typeface(K) @ @@
|
||||||
|
|
||||||
@@r.k text : Use the current Roman font for *text* @@
|
@@r.k text : Use the current Roman font for *text* @@
|
||||||
@@r.html :: <span class="plain">*text*</span> @@
|
@@r.html :: <span class="plain">*text*</span> @@
|
||||||
@@ -74,10 +90,21 @@
|
|||||||
\setmainfont{Garamond Libre}
|
\setmainfont{Garamond Libre}
|
||||||
@@
|
@@
|
||||||
|
|
||||||
@@cjk.k text : Switch to font that supports CJK for *text* @@
|
#[
|
||||||
@@cjk.html :: *cjk* @@
|
Before 2026-08-25 every one of these bodies substituted "*cjk*" while the
|
||||||
@@cjk.tex :: { #- @font Noto Sans CJK SC @ *cjk* #- } @@
|
declaration named the parameter "text", so @cjk raised "Variable "cjk" not
|
||||||
@@cjk.txt :: *cjk* @@
|
defined" under EVERY target -- it had never worked. Rewritten on
|
||||||
|
@typeface, which is what it was reaching for.
|
||||||
|
|
||||||
|
The typeface it names is NOT part of the distribution (a usable Noto Sans
|
||||||
|
CJK is some 16-20 MB per weight, and Chinese line breaking needs more
|
||||||
|
than a typeface -- xeCJK for the tex path), so this klammer errors with
|
||||||
|
the list of available typefaces until one is installed with
|
||||||
|
"kdesc --typeface install". That is the honest behaviour: the klammer
|
||||||
|
states what it needs and the store reports what it has.
|
||||||
|
]#
|
||||||
|
@@cjk.k text : Set *text* in a typeface that supports CJK @@
|
||||||
|
@@cjk.html,tex,txt :: @typeface Noto Sans CJK SC | *text* @ @@
|
||||||
|
|
||||||
@@fraktur.k s : Set text *s* in Fraktur @@
|
@@fraktur.k s : Set text *s* in Fraktur @@
|
||||||
@@fraktur.tex :: \textfrak{*s*} @@
|
@@fraktur.tex :: \textfrak{*s*} @@
|
||||||
|
|||||||
@@ -23,6 +23,63 @@ class Subsuper(klammer_base.Klammer_base):
|
|||||||
else:
|
else:
|
||||||
return f"${self.base}^{self.script}$"
|
return f"${self.base}^{self.script}$"
|
||||||
|
|
||||||
|
# The typeface-declaration marker. A klammer cannot declare a typeface
|
||||||
|
# itself: in html the @font-face must be in the page's css and the files
|
||||||
|
# localized into <output>/fonts/, and in tex the \newfontfamily must be in
|
||||||
|
# the preamble -- both are @document's, and @document runs AFTER the
|
||||||
|
# klammers it contains (application is post-order). So @typeface leaves
|
||||||
|
# this marker where the typeface is needed, and @document collects the
|
||||||
|
# markers, resolves and localizes each typeface, declares it, and replaces
|
||||||
|
# the marker with whatever inline switch the target needs (a font-switch
|
||||||
|
# command for tex, nothing for html, which carries the family name in the
|
||||||
|
# span's own style). Same shape as the __CAPTION__ markers.
|
||||||
|
#
|
||||||
|
# SYNC: typeface_marker_rgx in sks/document/document_class.h -- a C++/Python
|
||||||
|
# pair, so the constant cannot be single-sourced the way a .k/.py pair can
|
||||||
|
# (TODO #47); change both or neither.
|
||||||
|
def typeface_marker(name, scale):
|
||||||
|
return f"__TYPEFACE__{name}__{scale}__"
|
||||||
|
|
||||||
|
class Typeface(klammer_base.Klammer_base):
|
||||||
|
"""A temporary typeface change (@typeface). See sks/font/font.k."""
|
||||||
|
|
||||||
|
def __init__(self, K):
|
||||||
|
super().__init__(K)
|
||||||
|
|
||||||
|
def html(self):
|
||||||
|
# font-size-adjust is switched OFF for the span: the document
|
||||||
|
# normalizes families to a common x-height (font.css), which is
|
||||||
|
# meaningless for a script whose glyphs have no x-height at all --
|
||||||
|
# hieroglyphs, cuneiform -- and would resize them unpredictably.
|
||||||
|
# The family name is quoted -- an unquoted digit-initial word
|
||||||
|
# ("Source Sans 3") is invalid CSS -- with SINGLE quotes, because
|
||||||
|
# this sits inside a double-quoted html attribute.
|
||||||
|
style = (f"font-family: '{self.name}', serif; "
|
||||||
|
f"font-size-adjust: none")
|
||||||
|
if float(self.scale) != 1.0:
|
||||||
|
style += f"; font-size: {float(self.scale)}em"
|
||||||
|
# The STYLE is markup, so its typographically active characters are
|
||||||
|
# hidden: the html target's transforms turn a single quote into a
|
||||||
|
# curly one, which broke the css font-family value. The TEXT is
|
||||||
|
# writer content and is deliberately left alone -- its quotes and
|
||||||
|
# dashes should be transformed.
|
||||||
|
return (typeface_marker(self.name, self.scale)
|
||||||
|
+ f'<span style="{klammer_base.hide_typographic(style)}">'
|
||||||
|
+ f'{self.text}</span>')
|
||||||
|
|
||||||
|
def tex(self):
|
||||||
|
# The marker becomes the font-switch command; the group is what
|
||||||
|
# makes the change temporary (the retired @font emitted a bare
|
||||||
|
# \setmainfont, which changed the font for the rest of the
|
||||||
|
# document).
|
||||||
|
return "{" + typeface_marker(self.name, self.scale) + " " + self.text + "}"
|
||||||
|
|
||||||
|
def txt(self):
|
||||||
|
# A typeface cannot be expressed in plain text. Declared in the
|
||||||
|
# .k description, so this is documented behaviour rather than a
|
||||||
|
# silent per-target divergence.
|
||||||
|
return self.text
|
||||||
|
|
||||||
def html_fontify(text, font_symbol, font_size):
|
def html_fontify(text, font_symbol, font_size):
|
||||||
cls = {"r" : "",
|
cls = {"r" : "",
|
||||||
"i" :"ritalic",
|
"i" :"ritalic",
|
||||||
|
|||||||
+2
-2
@@ -102,8 +102,8 @@ class Image(klammer_base.Klammer_base):
|
|||||||
self.caption += self.file_error_message
|
self.caption += self.file_error_message
|
||||||
|
|
||||||
result = html_util.add_caption(
|
result = html_util.add_caption(
|
||||||
result, "Figure", self.number, self.caption, self.caption_font,
|
result, "Figure", self.number, self.caption, self.caption_style,
|
||||||
self.hpos, self.caption_side, False, self.caption_font_size,
|
self.hpos, self.caption_side, False, self.caption_size,
|
||||||
offset=self.offset)
|
offset=self.offset)
|
||||||
|
|
||||||
result = E("div").body(result).cls("image_margin")
|
result = E("div").body(result).cls("image_margin")
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class Kargs:
|
|||||||
def __init__(self, target, K, **kwargs):
|
def __init__(self, target, K, **kwargs):
|
||||||
self.__dict__ = kwargs
|
self.__dict__ = kwargs
|
||||||
self.center = False
|
self.center = False
|
||||||
self.caption_font = "i"
|
self.caption_style = "i"
|
||||||
self.caption_side = "bottom"
|
self.caption_side = "bottom"
|
||||||
self.caption_side_center = False
|
self.caption_side_center = False
|
||||||
self.Image_search_path = K.Image_search_path
|
self.Image_search_path = K.Image_search_path
|
||||||
@@ -40,7 +40,7 @@ class Kargs:
|
|||||||
self.border = False
|
self.border = False
|
||||||
self.vmargin = False
|
self.vmargin = False
|
||||||
self.abswidth = 0.0
|
self.abswidth = 0.0
|
||||||
self.caption_font_size = .9
|
self.caption_size = .9
|
||||||
|
|
||||||
def img(K, target, basename, caption, width):
|
def img(K, target, basename, caption, width):
|
||||||
result = image.Image(
|
result = image.Image(
|
||||||
|
|||||||
+2
-2
@@ -163,8 +163,8 @@ other structures. The ^:offset is used only if the ^:hpos value is "left" or
|
|||||||
:caption
|
:caption
|
||||||
:number.bool true
|
:number.bool true
|
||||||
:caption_side.side
|
:caption_side.side
|
||||||
:caption_font.font i
|
:caption_style.style_code i
|
||||||
:caption_font_size.float .9
|
:caption_size.float .9
|
||||||
: Arguments that define a caption for a block element.
|
: Arguments that define a caption for a block element.
|
||||||
@@
|
@@
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
@@ol.k list_items.rest :cmp.bool false :initial.int 1 : Ordered list, with numbered list elements. @@
|
@@ol.k list_items.rest :cmp.bool false :initial.int 1 : Ordered list, with numbered list elements. @@
|
||||||
@@ol.html,tex,txt :: @eval list.List(K, "ol") eval@ @@
|
@@ol.html,tex,txt :: @eval list.List(K, "ol") eval@ @@
|
||||||
|
|
||||||
@@define.k descriptions.rest(2) :font i : A list of words or phrases and their definitions or descriptions @@
|
@@define.k descriptions.rest(2) :style.style_code i : A list of words or phrases and their definitions or descriptions @@
|
||||||
@@define.html,tex :: @eval list.Define(K) eval@ @@
|
@@define.html,tex :: @eval list.Define(K) eval@ @@
|
||||||
|
|
||||||
@@columns.k items :n.int 2 : Create two or more columns from the text @@
|
@@columns.k items :n.int 2 : Create two or more columns from the text @@
|
||||||
|
|||||||
+2
-2
@@ -66,7 +66,7 @@ class Define(klammer_base.Klammer_base):
|
|||||||
"b" : f"<b>{s}</b>",
|
"b" : f"<b>{s}</b>",
|
||||||
"t" : f'<span class="monospace">{s}</span>',
|
"t" : f'<span class="monospace">{s}</span>',
|
||||||
"c" : f'<span class="monospace">{s}</span>',
|
"c" : f'<span class="monospace">{s}</span>',
|
||||||
"s" : f'<span class="sansserif">{s}</span>'}[self.font]
|
"s" : f'<span class="sansserif">{s}</span>'}[self.style]
|
||||||
result = "\n\n".join([f"<dt>{fontify(term)}</dt>\n<dd>{definition}</dd>"
|
result = "\n\n".join([f"<dt>{fontify(term)}</dt>\n<dd>{definition}</dd>"
|
||||||
for term,definition in self.items])
|
for term,definition in self.items])
|
||||||
result = f"<dl>\n{result}\n</dl>"
|
result = f"<dl>\n{result}\n</dl>"
|
||||||
@@ -79,7 +79,7 @@ class Define(klammer_base.Klammer_base):
|
|||||||
'b' : r'\normalfont\bfseries',
|
'b' : r'\normalfont\bfseries',
|
||||||
't' : r'\normalfont\ttfamily',
|
't' : r'\normalfont\ttfamily',
|
||||||
'c' : r'\normalfont\ttfamily',
|
'c' : r'\normalfont\ttfamily',
|
||||||
's' : r'\normalfont\sffamily'}[self.font]
|
's' : r'\normalfont\sffamily'}[self.style]
|
||||||
return f"{font} {s}"
|
return f"{font} {s}"
|
||||||
# The "\hfill\newline" was to force the description to the next line even if the item was small:
|
# The "\hfill\newline" was to force the description to the next line even if the item was small:
|
||||||
# result = "\n\n".join([f"\\item[{{{fontify(term)}}}]\\hfill\n\\newline {definition}"
|
# result = "\n\n".join([f"\\item[{{{fontify(term)}}}]\\hfill\n\\newline {definition}"
|
||||||
|
|||||||
+2
-2
@@ -206,8 +206,8 @@
|
|||||||
:grid.bool false
|
:grid.bool false
|
||||||
:cell_hpos.cell_hpos
|
:cell_hpos.cell_hpos
|
||||||
:justify.table_justify
|
:justify.table_justify
|
||||||
:header_font.font i
|
:header_style.style_code i
|
||||||
:font.font_list
|
:style.style_code_list
|
||||||
:colspan.table_span
|
:colspan.table_span
|
||||||
:rowspan.table_span
|
:rowspan.table_span
|
||||||
:calc.table_calc
|
:calc.table_calc
|
||||||
|
|||||||
+14
-14
@@ -84,7 +84,7 @@ class Table(klammer_base.Klammer_base):
|
|||||||
self.apply_formats()
|
self.apply_formats()
|
||||||
self.cell_hpos = extend(parse_hpos(self.K_target, self.cell_hpos), self.row_size)
|
self.cell_hpos = extend(parse_hpos(self.K_target, self.cell_hpos), self.row_size)
|
||||||
#self.cell_hpos = self.cell_hpos.split(";")
|
#self.cell_hpos = self.cell_hpos.split(";")
|
||||||
self.font = extend(self.font, self.row_size)
|
self.style = extend(self.style, self.row_size)
|
||||||
# In html, a 'fit' column mixed with sized columns must be clamped
|
# In html, a 'fit' column mixed with sized columns must be clamped
|
||||||
# to its widest entry (tex's \widthof semantics) or it absorbs the
|
# to its widest entry (tex's \widthof semantics) or it absorbs the
|
||||||
# window width: its cells get nowrap (class Wfit; see table.css).
|
# window width: its cells get nowrap (class Wfit; see table.css).
|
||||||
@@ -445,7 +445,7 @@ class Table(klammer_base.Klammer_base):
|
|||||||
self.column_widths = []
|
self.column_widths = []
|
||||||
for col_i in range(len(self.cells[0])):
|
for col_i in range(len(self.cells[0])):
|
||||||
longest = ""
|
longest = ""
|
||||||
longest_font = "r"
|
longest_style = "r"
|
||||||
for row_i in range(len(self.cells)):
|
for row_i in range(len(self.cells)):
|
||||||
cell = self.cells[row_i][col_i]
|
cell = self.cells[row_i][col_i]
|
||||||
# A colspan anchor's text spans several columns and must
|
# A colspan anchor's text spans several columns and must
|
||||||
@@ -456,9 +456,9 @@ class Table(klammer_base.Klammer_base):
|
|||||||
longest_in_line = lines[-1]
|
longest_in_line = lines[-1]
|
||||||
if len(longest_in_line) > len(longest):
|
if len(longest_in_line) > len(longest):
|
||||||
longest = longest_in_line
|
longest = longest_in_line
|
||||||
longest_font = cell.font
|
longest_style = cell.font
|
||||||
if longest_font != "r":
|
if longest_style != "r":
|
||||||
longest = font.tex_fontify(longest, longest_font, 1.0)
|
longest = font.tex_fontify(longest, longest_style, 1.0)
|
||||||
self.column_widths.append(longest)
|
self.column_widths.append(longest)
|
||||||
|
|
||||||
# ---- :hpos -------------------------------------------------------------
|
# ---- :hpos -------------------------------------------------------------
|
||||||
@@ -500,9 +500,9 @@ class Table(klammer_base.Klammer_base):
|
|||||||
for cell_i, cell in enumerate(row):
|
for cell_i, cell in enumerate(row):
|
||||||
rspan = self.span_count(self.s_rowspan, cell_i, row_i)
|
rspan = self.span_count(self.s_rowspan, cell_i, row_i)
|
||||||
cspan = self.span_count(self.s_colspan, row_i, cell_i)
|
cspan = self.span_count(self.s_colspan, row_i, cell_i)
|
||||||
font = self.font[cell_i]
|
font = self.style[cell_i]
|
||||||
if row_i == 0 and self.header:
|
if row_i == 0 and self.header:
|
||||||
font = self.header_font
|
font = self.header_style
|
||||||
# A span anchor's right and bottom borders come from the
|
# A span anchor's right and bottom borders come from the
|
||||||
# boundary at the END of the merged region.
|
# boundary at the END of the merged region.
|
||||||
right_i = cell_i + max(cspan, 1)
|
right_i = cell_i + max(cspan, 1)
|
||||||
@@ -589,9 +589,9 @@ class Table(klammer_base.Klammer_base):
|
|||||||
if self.number or self.caption:
|
if self.number or self.caption:
|
||||||
result = html_util.add_caption(
|
result = html_util.add_caption(
|
||||||
result, "Table", self.number, self.caption,
|
result, "Table", self.number, self.caption,
|
||||||
self.caption_font, hpos=self.hpos,
|
self.caption_style, hpos=self.hpos,
|
||||||
side=self.caption_side,
|
side=self.caption_side,
|
||||||
font_size=self.caption_font_size, max_width="100%",
|
font_size=self.caption_size, max_width="100%",
|
||||||
offset=self.offset)
|
offset=self.offset)
|
||||||
else:
|
else:
|
||||||
result.attr("style", "max-width: 100%")
|
result.attr("style", "max-width: 100%")
|
||||||
@@ -606,9 +606,9 @@ class Table(klammer_base.Klammer_base):
|
|||||||
if table_width:
|
if table_width:
|
||||||
result.attr("style", f"{layout}width: 100%")
|
result.attr("style", f"{layout}width: 100%")
|
||||||
result = html_util.add_caption(
|
result = html_util.add_caption(
|
||||||
result, "Table", self.number, self.caption, self.caption_font,
|
result, "Table", self.number, self.caption, self.caption_style,
|
||||||
hpos=self.hpos, side=self.caption_side,
|
hpos=self.hpos, side=self.caption_side,
|
||||||
font_size=self.caption_font_size, width=table_width,
|
font_size=self.caption_size, width=table_width,
|
||||||
offset=self.offset)
|
offset=self.offset)
|
||||||
else:
|
else:
|
||||||
# An uncaptioned table still gets the position container, so
|
# An uncaptioned table still gets the position container, so
|
||||||
@@ -757,7 +757,7 @@ class Table(klammer_base.Klammer_base):
|
|||||||
def make_caption(self):
|
def make_caption(self):
|
||||||
column_count = str(len(self.rows[0]))
|
column_count = str(len(self.rows[0]))
|
||||||
caption = latex_util.make_caption_text(
|
caption = latex_util.make_caption_text(
|
||||||
self.number, "Table", self.caption, self.caption_font, self.caption_font_size)
|
self.number, "Table", self.caption, self.caption_style, self.caption_size)
|
||||||
result = "\\multicolumn{" + column_count + "}{c}{\\parbox{\\tableboxwidth}{"
|
result = "\\multicolumn{" + column_count + "}{c}{\\parbox{\\tableboxwidth}{"
|
||||||
result += "\\vspace*{8pt}\\centering\\small\\em "
|
result += "\\vspace*{8pt}\\centering\\small\\em "
|
||||||
result += caption
|
result += caption
|
||||||
@@ -836,8 +836,8 @@ class Table(klammer_base.Klammer_base):
|
|||||||
result = latex_util.add_caption(
|
result = latex_util.add_caption(
|
||||||
result, "Table", self.number, self.caption, "\\tableboxwidth",
|
result, "Table", self.number, self.caption, "\\tableboxwidth",
|
||||||
hpos=self.hpos, side=self.caption_side,
|
hpos=self.hpos, side=self.caption_side,
|
||||||
font_symbol=self.caption_font,
|
font_symbol=self.caption_style,
|
||||||
font_size=self.caption_font_size, offset=self.offset)
|
font_size=self.caption_size, offset=self.offset)
|
||||||
else:
|
else:
|
||||||
result = latex_util.caption_wrapper(result, self.hpos, offset=self.offset)
|
result = latex_util.caption_wrapper(result, self.hpos, offset=self.offset)
|
||||||
result = measure + result
|
result = measure + result
|
||||||
|
|||||||
+18
-18
@@ -163,10 +163,10 @@ namespace latex {
|
|||||||
const std::string& cover,
|
const std::string& cover,
|
||||||
bool landscape,
|
bool landscape,
|
||||||
const std::string& body,
|
const std::string& body,
|
||||||
Resolved_font serif_font,
|
Resolved_font serif_typeface,
|
||||||
Resolved_font sans_font,
|
Resolved_font sans_typeface,
|
||||||
Resolved_font mono_font,
|
Resolved_font mono_typeface,
|
||||||
float font_scale)
|
float text_scale)
|
||||||
{
|
{
|
||||||
(void)K::log(3);
|
(void)K::log(3);
|
||||||
bool book_format = (structure == "book");
|
bool book_format = (structure == "book");
|
||||||
@@ -202,10 +202,10 @@ namespace latex {
|
|||||||
// x-height: serif_xh / other_xh (matches lowercase)
|
// x-height: serif_xh / other_xh (matches lowercase)
|
||||||
// cap-height: serif_ch / other_ch (matches capitals)
|
// cap-height: serif_ch / other_ch (matches capitals)
|
||||||
// average: mean(serif_xh,serif_ch) / mean(other_xh,other_ch)
|
// average: mean(serif_xh,serif_ch) / mean(other_xh,other_ch)
|
||||||
float serif_xh = serif_font.xheight_ratio;
|
float serif_xh = serif_typeface.xheight_ratio;
|
||||||
float serif_ch = serif_font.capheight_ratio;
|
float serif_ch = serif_typeface.capheight_ratio;
|
||||||
float serif_avg = (serif_xh + serif_ch) / 2.0f;
|
float serif_avg = (serif_xh + serif_ch) / 2.0f;
|
||||||
auto font_scale_fn = [&](const Resolved_font& other) -> float {
|
auto text_scale_fn = [&](const Resolved_font& other) -> float {
|
||||||
float other_avg = (other.xheight_ratio + other.capheight_ratio) / 2.0f;
|
float other_avg = (other.xheight_ratio + other.capheight_ratio) / 2.0f;
|
||||||
if (serif_avg > 0.0f && other_avg > 0.0f)
|
if (serif_avg > 0.0f && other_avg > 0.0f)
|
||||||
// return serif_xh / other.xheight_ratio; // x-height
|
// return serif_xh / other.xheight_ratio; // x-height
|
||||||
@@ -213,21 +213,21 @@ namespace latex {
|
|||||||
return serif_avg / other_avg; // average
|
return serif_avg / other_avg; // average
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
};
|
};
|
||||||
// Global font_scale multiplies all font sizes uniformly
|
// Global text_scale multiplies all font sizes uniformly
|
||||||
float gs = (font_scale != 1.0f) ? font_scale : 0.0f;
|
float gs = (text_scale != 1.0f) ? text_scale : 0.0f;
|
||||||
float sans_s = font_scale_fn(sans_font);
|
float sans_s = text_scale_fn(sans_typeface);
|
||||||
float mono_s = font_scale_fn(mono_font);
|
float mono_s = text_scale_fn(mono_typeface);
|
||||||
// Apply global scale: multiply into per-font scale, or use alone
|
// Apply global scale: multiply into per-font scale, or use alone
|
||||||
if (gs > 0.0f) {
|
if (gs > 0.0f) {
|
||||||
sans_s = (sans_s > 0.0f) ? sans_s * font_scale : font_scale;
|
sans_s = (sans_s > 0.0f) ? sans_s * text_scale : text_scale;
|
||||||
mono_s = (mono_s > 0.0f) ? mono_s * font_scale : font_scale;
|
mono_s = (mono_s > 0.0f) ? mono_s * text_scale : text_scale;
|
||||||
}
|
}
|
||||||
ss << font_command("setmainfont", serif_font, gs);
|
ss << font_command("setmainfont", serif_typeface, gs);
|
||||||
ss << font_command("setsansfont", sans_font, sans_s);
|
ss << font_command("setsansfont", sans_typeface, sans_s);
|
||||||
ss << font_command("setmonofont", mono_font, mono_s);
|
ss << font_command("setmonofont", mono_typeface, mono_s);
|
||||||
|
|
||||||
// Scale leading proportionally with font_scale
|
// Scale leading proportionally with text_scale
|
||||||
float effective_leading = leading * ((font_scale != 1.0f) ? font_scale : 1.0f);
|
float effective_leading = leading * ((text_scale != 1.0f) ? text_scale : 1.0f);
|
||||||
ss << "\n\\setstretch{" << effective_leading << "}\n";
|
ss << "\n\\setstretch{" << effective_leading << "}\n";
|
||||||
if (ragged_right)
|
if (ragged_right)
|
||||||
ss << "\\raggedright\n";
|
ss << "\\raggedright\n";
|
||||||
|
|||||||
+12
-4
@@ -6,6 +6,14 @@
|
|||||||
|
|
||||||
namespace latex {
|
namespace latex {
|
||||||
|
|
||||||
|
// A fontspec declaration: "\<command>[Path=...,Scale=...]{<regular>}".
|
||||||
|
// The command is "setmainfont"/"setsansfont"/"setmonofont" for the
|
||||||
|
// document's three role typefaces, and "newfontfamily\ktface<n>" for a
|
||||||
|
// typeface a @typeface klammer asked for (a switch command rather than a
|
||||||
|
// permanent change).
|
||||||
|
std::string font_command(const std::string& command, const Resolved_font& font,
|
||||||
|
float scale);
|
||||||
|
|
||||||
std::string page(const std::string& structure,
|
std::string page(const std::string& structure,
|
||||||
const std::string& title,
|
const std::string& title,
|
||||||
const std::string& subtitle,
|
const std::string& subtitle,
|
||||||
@@ -23,10 +31,10 @@ std::string page(const std::string& structure,
|
|||||||
const std::string& cover,
|
const std::string& cover,
|
||||||
bool landscape,
|
bool landscape,
|
||||||
const std::string& body,
|
const std::string& body,
|
||||||
Resolved_font serif_font = {},
|
Resolved_font serif_typeface = {},
|
||||||
Resolved_font sans_font = {},
|
Resolved_font sans_typeface = {},
|
||||||
Resolved_font mono_font = {},
|
Resolved_font mono_typeface = {},
|
||||||
float font_scale = 1.0f);
|
float text_scale = 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_for_xelatex();
|
void check_for_xelatex();
|
||||||
|
|||||||
+59
-7
@@ -2,8 +2,12 @@
|
|||||||
#
|
#
|
||||||
# character_test.sh — Regression tests for the ^-character forms the engine
|
# character_test.sh — Regression tests for the ^-character forms the engine
|
||||||
# resolves at read time: the ^UUUU^ Unicode code point (4-6 hex digits,
|
# resolves at read time: the ^UUUU^ Unicode code point (4-6 hex digits,
|
||||||
# since 2026-08-23 covering the full range to U+10FFFF), and the character
|
# since 2026-08-23 covering the full range to U+10FFFF), the
|
||||||
# tables (mnemonics, diacritics) it must not disturb.
|
# ^UUUU UUUU ...^ SEQUENCE form (added 2026-08-25: one caret pair around
|
||||||
|
# whitespace-delimited tokens, assembled at katom level by
|
||||||
|
# process_unicode_sequences — so, unlike the string-level single form, it
|
||||||
|
# is skipped inside @eval/@read/@cond spans and for literal content), and
|
||||||
|
# the character tables (mnemonics, diacritics) it must not disturb.
|
||||||
#
|
#
|
||||||
# SKS-independent: character handling is katomizer/engine machinery
|
# SKS-independent: character handling is katomizer/engine machinery
|
||||||
# (mac/ktype.h nonascii katom, mac/character.cpp), so everything runs with
|
# (mac/ktype.h nonascii katom, mac/character.cpp), so everything runs with
|
||||||
@@ -39,6 +43,26 @@ reset=$'\033[0m'
|
|||||||
|
|
||||||
trim() { awk '{ sub(/[ \t\r]+$/, "") } { line[NR]=$0 } END { f=1; while (f<=NR && line[f]=="") f++; l=NR; while (l>=1 && line[l]=="") l--; for (i=f;i<=l;i++) print line[i] }'; }
|
trim() { awk '{ sub(/[ \t\r]+$/, "") } { line[NR]=$0 } END { f=1; while (f<=NR && line[f]=="") f++; l=NR; while (l>=1 && line[l]=="") l--; for (i=f;i<=l;i++) print line[i] }'; }
|
||||||
|
|
||||||
|
# check_err NAME PHRASE INPUT — the render must FAIL (nonzero exit) with
|
||||||
|
# PHRASE on stderr. Matched wrap-insensitively: error messages are
|
||||||
|
# justified to 80 columns and may wrap anywhere.
|
||||||
|
check_err() {
|
||||||
|
local name="$1" phrase="$2" input="$3"
|
||||||
|
local err status
|
||||||
|
err=$("$KTEXT" --klammersets none -s "$input" -d 2>&1 >/dev/null); status=$?
|
||||||
|
err=$(printf '%s' "$err" | tr '\n' ' ' | tr -s ' ')
|
||||||
|
if [ $status -eq 0 ]; then
|
||||||
|
echo "${red}FAIL${reset} $name — expected an error, got exit 0"
|
||||||
|
FAIL=$((FAIL+1)); return
|
||||||
|
fi
|
||||||
|
case "$err" in
|
||||||
|
*"$phrase"*) echo "${green}PASS${reset} $name"; PASS=$((PASS+1));;
|
||||||
|
*) echo "${red}FAIL${reset} $name"
|
||||||
|
echo " wanted phrase: [$phrase]"
|
||||||
|
echo " stderr: $(echo "$err" | head -c 200)"; FAIL=$((FAIL+1));;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
# check NAME EXPECTED INPUT — render INPUT (no klammer set, default
|
# check NAME EXPECTED INPUT — render INPUT (no klammer set, default
|
||||||
# target); exit 0 and stdout == EXPECTED.
|
# target); exit 0 and stdout == EXPECTED.
|
||||||
check() {
|
check() {
|
||||||
@@ -66,14 +90,42 @@ check " 1. 4-digit BMP code point" $'A ☺ B' 'A ^263A^ B'
|
|||||||
check " 2. 5-digit code point, whole" $'A \xf0\x93\x80\x80 B' 'A ^13000^ B'
|
check " 2. 5-digit code point, whole" $'A \xf0\x93\x80\x80 B' 'A ^13000^ B'
|
||||||
check " 3. 5-digit emoji" $'\xf0\x9f\x98\x80' '^1F600^'
|
check " 3. 5-digit emoji" $'\xf0\x9f\x98\x80' '^1F600^'
|
||||||
check " 4. 6-digit top of the range" $'\xf4\x8f\xbf\xbd' '^10FFFD^'
|
check " 4. 6-digit top of the range" $'\xf4\x8f\xbf\xbd' '^10FFFD^'
|
||||||
check " 5. above U+10FFFF is invalid" 'Invalid Unicode: 16777215' '^FFFFFF^'
|
# An invalid code point is a located ERROR (2026-08-25, the
|
||||||
check " 6. surrogate is invalid" 'Invalid Unicode: 55296' '^D800^'
|
# no-warn-and-continue policy) -- it was in-band "Invalid Unicode" text in
|
||||||
|
# the document before, which is the wrong channel for a generator's typo.
|
||||||
|
check_err " 5. above U+10FFFF is an error" 'beyond U+10FFFF' '^FFFFFF^'
|
||||||
|
check_err " 6. surrogate is an error" 'a surrogate' '^D800^'
|
||||||
|
check_err " 6a. noncharacter is an error" 'a noncharacter' '^FDD0^'
|
||||||
check " 7. mnemonic undisturbed" 'ß' '^s^'
|
check " 7. mnemonic undisturbed" 'ß' '^s^'
|
||||||
# The diacritic tables compose base + COMBINING mark (a U+0308), not the
|
# The tables emit the PRECOMPOSED (NFC) character where one exists (since
|
||||||
# precomposed letter -- the expected string is built the same way.
|
# 2026-08-25; they formerly emitted base + combining mark) -- the same
|
||||||
check " 8. diacritic undisturbed" $'Ma\xcc\x88dchen' 'M^a"dchen'
|
# bytes an editor's direct entry produces, so ^a" and a typed ä compare
|
||||||
|
# equal in search and copy-paste. The literal ä below is precomposed.
|
||||||
|
check " 8. diacritic is the precomposed character" 'Mädchen' 'M^a"dchen'
|
||||||
check " 9. code point beside quoted punctuation" $'☺ --' '^263A^ ^-^-'
|
check " 9. code point beside quoted punctuation" $'☺ --' '^263A^ ^-^-'
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "-- sequences: ^UUUU UUUU ...^ (one caret pair, tokens 4-6 hex digits,"
|
||||||
|
echo " no space at the elbows, one line; process_unicode_sequences)"
|
||||||
|
check "10. CJK sequence" $'X \xe9\x81\x93\xe5\x8f\xaf\xe9\x81\x93\xe9\x9d\x9e\xe5\xb8\xb8\xe9\x81\x93 Y' 'X ^9053 53EF 9053 975E 5E38 9053^ Y'
|
||||||
|
check "11. mixed widths" $'\xe2\x98\xba\xf0\x93\x80\x80\xf0\x9f\x98\x80' '^263A 13000 1F600^'
|
||||||
|
check "12. space after opening caret: not a sequence" 'A ^ 263A 263A^ B' 'A ^ 263A 263A^ B'
|
||||||
|
check "13. space before closing caret: not a sequence" 'A ^263A 263A ^ B' 'A ^263A 263A ^ B'
|
||||||
|
check "14. newline aborts (one line only)" $'A ^263A\n263A^ B' $'A ^263A\n263A^ B'
|
||||||
|
check "15. short token aborts whole sequence" 'A ^263A 263^ B' 'A ^263A 263^ B'
|
||||||
|
check "16. @eval code keeps its carets" '11' '@eval len("^263A 263A^") @'
|
||||||
|
check "17. literal span: sequence stays verbatim" 'x ^263A 263A^ y' "^'x ^263A 263A^ y'^"
|
||||||
|
check "17a. single-character token stands for itself" $'\xe9\x81\x93x\xe5\x8f\xaf' '^9053 x 53EF^'
|
||||||
|
check "17b. non-alnum single token behaves as quoted" '☺-☺' '^263A - 263A^'
|
||||||
|
check "17c. structural code points are re-read-safe" '@@' '^0040 0040^'
|
||||||
|
check_err "17d. invalid code point in a CLOSED sequence" 'in a ^...^ sequence' '^263A FFFFFF^'
|
||||||
|
check "17e. unclosed hex-like prose is untouched" 'about ^263A FFFFFF prose' 'about ^263A FFFFFF prose'
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "-- direct entry and NFC convergence"
|
||||||
|
check "18. pinyin tone is precomposed" 'ā' '^a1'
|
||||||
|
check "19. typed UTF-8 passes through byte-identical" 'Mädchen naïveté ü — done' 'Mädchen naïveté ü — done'
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "================================================================="
|
echo "================================================================="
|
||||||
echo "${bold}Results: $PASS passed, $FAIL failed${reset}"
|
echo "${bold}Results: $PASS passed, $FAIL failed${reset}"
|
||||||
|
|||||||
@@ -83,6 +83,18 @@ shows " 1. -k lists klammers" '@table' "$KDESC" -k
|
|||||||
shows " 2. -t lists targets" 'html' "$KDESC" -t
|
shows " 2. -t lists targets" 'html' "$KDESC" -t
|
||||||
shows " 3. -c lists character codes" '.' "$KDESC" -c
|
shows " 3. -c lists character codes" '.' "$KDESC" -c
|
||||||
shows " 4. -i reads the named input" '@x' "$KDESC" -i "$DIR/split.k" -k
|
shows " 4. -i reads the named input" '@x' "$KDESC" -i "$DIR/split.k" -k
|
||||||
|
# -u describes how to write a Unicode character. Asserted by OUTCOME, on
|
||||||
|
# the two things the section must carry however its prose is rewritten:
|
||||||
|
# the ^...^ notation it teaches, and a rendered character beside its code
|
||||||
|
# point -- the whole point of the section is that a reader sees the glyph
|
||||||
|
# they are about to write. It does NOT pin the prose, which is meant to
|
||||||
|
# grow (as of 2026-08-25 the section predates the sequence form and the
|
||||||
|
# typeface klammer, and does not yet mention either).
|
||||||
|
shows " 4a. -u describes the Unicode syntax" '\^0418\^' "$KDESC" -u
|
||||||
|
# The rendered glyph, as UTF-8 BYTE escapes: macOS ships bash 3.2, which
|
||||||
|
# expands $'\xHH' but not $'\U...' (that difference failed this suite's
|
||||||
|
# sibling on Olion, 2026-08-23).
|
||||||
|
shows " 4b. ... and shows the characters" $'\xf0\x93\x8a\xaa' "$KDESC" -u
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "-- the multi-letter topics --"
|
echo "-- the multi-letter topics --"
|
||||||
|
|||||||
+3
-1
@@ -281,7 +281,9 @@ shows "35. --ws applies whitespace operators" 'ab' --ws 'a#- b'
|
|||||||
# DIAERESIS, not the precomposed U+00FC. The diacritic FOLLOWS the base
|
# DIAERESIS, not the precomposed U+00FC. The diacritic FOLLOWS the base
|
||||||
# letter -- that is the design of the ^ codes -- so the two spellings look
|
# letter -- that is the design of the ^ codes -- so the two spellings look
|
||||||
# identical in an editor and only one of them matches.
|
# identical in an editor and only one of them matches.
|
||||||
shows "36. --nonascii decodes to a combining sequence" 'ü' --nonascii '^u"'
|
# Precomposed since 2026-08-25: the tables emit NFC, the same bytes as
|
||||||
|
# direct entry (formerly base + combining mark).
|
||||||
|
shows "36. --nonascii decodes to the precomposed character" 'ü' --nonascii '^u"'
|
||||||
shows "37. --literal marks a literal span" 'x' --literal "^'x'^"
|
shows "37. --literal marks a literal span" 'x' --literal "^'x'^"
|
||||||
# Evaluating needs a target: Eval::eval re-reads its result under K_target, and
|
# Evaluating needs a target: Eval::eval re-reads its result under K_target, and
|
||||||
# kdiag has no target argument, so with the variable unset EVERY @eval died
|
# kdiag has no target argument, so with the variable unset EVERY @eval died
|
||||||
|
|||||||
Reference in new issue
Block a user