summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2020-02-16 10:59:14 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2020-02-16 10:59:14 +0100
commit8e11d447440b44990432ac838953a8cde4ef914f (patch)
treef30b2ff2d8a10f1aff50e1522d968618a97f067c /tex
parent43fc66771a0c9d27cc0b7fe7a69392ea313bd0ca (diff)
downloadcontext-8e11d447440b44990432ac838953a8cde4ef914f.tar.gz
2020-02-11 16:39:00
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/char-emj.lua375
-rw-r--r--tex/context/base/mkiv/cont-fil.mkiv269
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkxl2
-rw-r--r--tex/context/base/mkiv/data-tmp.lua2
-rw-r--r--tex/context/base/mkiv/driv-shp.lua6
-rw-r--r--tex/context/base/mkiv/file-job.lua2
-rw-r--r--tex/context/base/mkiv/font-con.lua1
-rw-r--r--tex/context/base/mkiv/font-ctx.lua65
-rw-r--r--tex/context/base/mkiv/font-dsp.lua57
-rw-r--r--tex/context/base/mkiv/font-mis.lua2
-rw-r--r--tex/context/base/mkiv/font-ocl.lua2
-rw-r--r--tex/context/base/mkiv/font-otl.lua5
-rw-r--r--tex/context/base/mkiv/l-os.lua8
-rw-r--r--tex/context/base/mkiv/l-table.lua106
-rw-r--r--tex/context/base/mkiv/libs-imp-mujs.lua126
-rw-r--r--tex/context/base/mkiv/libs-imp-mujs.mkxl121
-rw-r--r--tex/context/base/mkiv/libs-imp-mysql.lua36
-rw-r--r--tex/context/base/mkiv/libs-imp-postgress.lua6
-rw-r--r--tex/context/base/mkiv/libs-imp-sqlite.lua4
-rw-r--r--tex/context/base/mkiv/libs-imp-zint.lua15
-rw-r--r--tex/context/base/mkiv/libs-imp-zint.mkxl5
-rw-r--r--tex/context/base/mkiv/libs-ini.lua17
-rw-r--r--tex/context/base/mkiv/lpdf-emb.lua48
-rw-r--r--tex/context/base/mkiv/lpdf-lmt.lua170
-rw-r--r--tex/context/base/mkiv/lpdf-wid.lua16
-rw-r--r--tex/context/base/mkiv/luat-cod.lua4
-rw-r--r--tex/context/base/mkiv/luat-ini.lua2
-rw-r--r--tex/context/base/mkiv/luat-lib.mkiv6
-rw-r--r--tex/context/base/mkiv/m-gnuplot.mkxl97
-rw-r--r--tex/context/base/mkiv/m-zint.mkxl7
-rw-r--r--tex/context/base/mkiv/meta-imp-threesix.mkxl253
-rw-r--r--tex/context/base/mkiv/meta-tex.mkiv3
-rw-r--r--tex/context/base/mkiv/mlib-svg.lua280
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin26743 -> 26747 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin269677 -> 269549 bytes
-rw-r--r--tex/context/base/mkiv/tabl-xtb.lua32
-rw-r--r--tex/context/base/mkiv/util-pck.lua10
-rw-r--r--tex/context/base/mkiv/util-sql.lua6
-rw-r--r--tex/context/base/mkiv/util-str.lua6
-rw-r--r--tex/context/base/mkiv/util-tab.lua255
-rw-r--r--tex/context/modules/common/s-abbreviations-logos.tex1
-rw-r--r--tex/context/modules/mkiv/m-zint.mkiv112
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua95
-rw-r--r--tex/generic/context/luatex/luatex-fonts.lua4
48 files changed, 1899 insertions, 748 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index 9e0025e0f..8570ac7a9 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2020.01.26 18:34}
+\newcontextversion{2020.02.11 16:36}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index aa7c02cf4..e02bc12dd 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.01.26 18:34}
+\edef\contextversion{2020.02.11 16:36}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/char-emj.lua b/tex/context/base/mkiv/char-emj.lua
index b00e9ebf8..e6c059174 100644
--- a/tex/context/base/mkiv/char-emj.lua
+++ b/tex/context/base/mkiv/char-emj.lua
@@ -16,6 +16,7 @@ return {
["a button (blood type)"]={ 0x1F170, 0xFE0F },
["ab button (blood type)"]={ 0x1F18E },
["abacus"]={ 0x1F9EE },
+ ["accordion"]={ 0x1FA97 },
["adhesive bandage"]={ 0x1FA79 },
["admission tickets"]={ 0x1F39F, 0xFE0F },
["aerial tramway"]={ 0x1F6A1 },
@@ -29,6 +30,7 @@ return {
["ambulance"]={ 0x1F691 },
["american football"]={ 0x1F3C8 },
["amphora"]={ 0x1F3FA },
+ ["anatomical heart"]={ 0x1FAC0 },
["anchor"]={ 0x2693 },
["anger symbol"]={ 0x1F4A2 },
["angry face"]={ 0x1F620 },
@@ -40,8 +42,20 @@ return {
["aquarius"]={ 0x2652 },
["aries"]={ 0x2648 },
["articulated lorry"]={ 0x1F69B },
+ ["artist"]={ 0x1F9D1, 0x200D, 0x1F3A8 },
["artist palette"]={ 0x1F3A8 },
+ ["artist: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F3A8 },
+ ["artist: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F3A8 },
+ ["artist: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F3A8 },
+ ["artist: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F3A8 },
+ ["artist: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F3A8 },
["astonished face"]={ 0x1F632 },
+ ["astronaut"]={ 0x1F9D1, 0x200D, 0x1F680 },
+ ["astronaut: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F680 },
+ ["astronaut: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F680 },
+ ["astronaut: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F680 },
+ ["astronaut: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F680 },
+ ["astronaut: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F680 },
["atm sign"]={ 0x1F3E7 },
["atom symbol"]={ 0x269B, 0xFE0F },
["auto rickshaw"]={ 0x1F6FA },
@@ -115,9 +129,12 @@ return {
["beaming face with smiling eyes"]={ 0x1F601 },
["bear"]={ 0x1F43B },
["beating heart"]={ 0x1F493 },
+ ["beaver"]={ 0x1F9AB },
["bed"]={ 0x1F6CF, 0xFE0F },
["beer mug"]={ 0x1F37A },
+ ["beetle"]={ 0x1FAB2 },
["bell"]={ 0x1F514 },
+ ["bell pepper"]={ 0x1FAD1 },
["bell with slash"]={ 0x1F515 },
["bellhop bell"]={ 0x1F6CE, 0xFE0F },
["bento box"]={ 0x1F371 },
@@ -128,6 +145,8 @@ return {
["biohazard"]={ 0x2623, 0xFE0F },
["bird"]={ 0x1F426 },
["birthday cake"]={ 0x1F382 },
+ ["bison"]={ 0x1F9AC },
+ ["black cat"]={ 0x1F408, 0x200D, 0x2B1B },
["black circle"]={ 0x26AB },
["black flag"]={ 0x1F3F4 },
["black heart"]={ 0x1F5A4 },
@@ -143,12 +162,14 @@ return {
["blue circle"]={ 0x1F535 },
["blue heart"]={ 0x1F499 },
["blue square"]={ 0x1F7E6 },
+ ["blueberries"]={ 0x1FAD0 },
["boar"]={ 0x1F417 },
["bomb"]={ 0x1F4A3 },
["bone"]={ 0x1F9B4 },
["bookmark"]={ 0x1F516 },
["bookmark tabs"]={ 0x1F4D1 },
["books"]={ 0x1F4DA },
+ ["boomerang"]={ 0x1FA83 },
["bottle with popping cork"]={ 0x1F37E },
["bouquet"]={ 0x1F490 },
["bow and arrow"]={ 0x1F3F9 },
@@ -170,14 +191,9 @@ return {
["breast-feeding: medium-dark skin tone"]={ 0x1F931, 0x1F3FE },
["breast-feeding: medium-light skin tone"]={ 0x1F931, 0x1F3FC },
["brick"]={ 0x1F9F1 },
- ["bride with veil"]={ 0x1F470 },
- ["bride with veil: dark skin tone"]={ 0x1F470, 0x1F3FF },
- ["bride with veil: light skin tone"]={ 0x1F470, 0x1F3FB },
- ["bride with veil: medium skin tone"]={ 0x1F470, 0x1F3FD },
- ["bride with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE },
- ["bride with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC },
["bridge at night"]={ 0x1F309 },
["briefcase"]={ 0x1F4BC },
+ ["briefs"]={ 0x1FA72 },
["bright button"]={ 0x1F506 },
["broccoli"]={ 0x1F966 },
["broken heart"]={ 0x1F494 },
@@ -185,6 +201,8 @@ return {
["brown circle"]={ 0x1F7E4 },
["brown heart"]={ 0x1F90E },
["brown square"]={ 0x1F7EB },
+ ["bubble tea"]={ 0x1F9CB },
+ ["bucket"]={ 0x1FAA3 },
["bug"]={ 0x1F41B },
["building construction"]={ 0x1F3D7, 0xFE0F },
["bullet train"]={ 0x1F685 },
@@ -218,6 +236,7 @@ return {
["card index dividers"]={ 0x1F5C2, 0xFE0F },
["carousel horse"]={ 0x1F3A0 },
["carp streamer"]={ 0x1F38F },
+ ["carpentry saw"]={ 0x1FA9A },
["carrot"]={ 0x1F955 },
["castle"]={ 0x1F3F0 },
["cat"]={ 0x1F408 },
@@ -284,9 +303,11 @@ return {
["club suit"]={ 0x2663, 0xFE0F },
["clutch bag"]={ 0x1F45D },
["coat"]={ 0x1F9E5 },
+ ["cockroach"]={ 0x1FAB3 },
["cocktail glass"]={ 0x1F378 },
["coconut"]={ 0x1F965 },
["coffin"]={ 0x26B0, 0xFE0F },
+ ["coin"]={ 0x1FA99 },
["cold face"]={ 0x1F976 },
["collision"]={ 0x1F4A5 },
["comet"]={ 0x2604, 0xFE0F },
@@ -305,6 +326,12 @@ return {
["construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC },
["control knobs"]={ 0x1F39B, 0xFE0F },
["convenience store"]={ 0x1F3EA },
+ ["cook"]={ 0x1F9D1, 0x200D, 0x1F373 },
+ ["cook: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F373 },
+ ["cook: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F373 },
+ ["cook: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F373 },
+ ["cook: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F373 },
+ ["cook: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F373 },
["cooked rice"]={ 0x1F35A },
["cookie"]={ 0x1F36A },
["cooking"]={ 0x1F373 },
@@ -392,12 +419,14 @@ return {
["dim button"]={ 0x1F505 },
["direct hit"]={ 0x1F3AF },
["disappointed face"]={ 0x1F61E },
+ ["disguised face"]={ 0x1F978 },
+ ["divide"]={ 0x2797 },
["diving mask"]={ 0x1F93F },
- ["division sign"]={ 0x2797 },
["diya lamp"]={ 0x1FA94 },
["dizzy"]={ 0x1F4AB },
["dizzy face"]={ 0x1F635 },
["dna"]={ 0x1F9EC },
+ ["dodo"]={ 0x1F9A4 },
["dog"]={ 0x1F415 },
["dog face"]={ 0x1F436 },
["dollar banknote"]={ 0x1F4B5 },
@@ -447,6 +476,7 @@ return {
["eject button"]={ 0x23CF, 0xFE0F },
["electric plug"]={ 0x1F50C },
["elephant"]={ 0x1F418 },
+ ["elevator"]={ 0x1F6D7 },
["eleven o’clock"]={ 0x1F55A },
["eleven-thirty"]={ 0x1F566 },
["elf"]={ 0x1F9DD },
@@ -486,6 +516,12 @@ return {
["face with tongue"]={ 0x1F61B },
["face without mouth"]={ 0x1F636 },
["factory"]={ 0x1F3ED },
+ ["factory worker"]={ 0x1F9D1, 0x200D, 0x1F3ED },
+ ["factory worker: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F3ED },
+ ["factory worker: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F3ED },
+ ["factory worker: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F3ED },
+ ["factory worker: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F3ED },
+ ["factory worker: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F3ED },
["fairy"]={ 0x1F9DA },
["fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF },
["fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB },
@@ -520,12 +556,19 @@ return {
["family: woman, woman, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467 },
["family: woman, woman, girl, boy"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F466 },
["family: woman, woman, girl, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F467 },
+ ["farmer"]={ 0x1F9D1, 0x200D, 0x1F33E },
+ ["farmer: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F33E },
+ ["farmer: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F33E },
+ ["farmer: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F33E },
+ ["farmer: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F33E },
+ ["farmer: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F33E },
["fast down button"]={ 0x23EC },
["fast reverse button"]={ 0x23EA },
["fast up button"]={ 0x23EB },
["fast-forward button"]={ 0x23E9 },
["fax machine"]={ 0x1F4E0 },
["fearful face"]={ 0x1F628 },
+ ["feather"]={ 0x1FAB6 },
["female sign"]={ 0x2640, 0xFE0F },
["ferris wheel"]={ 0x1F3A1 },
["ferry"]={ 0x26F4, 0xFE0F },
@@ -538,6 +581,12 @@ return {
["fire engine"]={ 0x1F692 },
["fire extinguisher"]={ 0x1F9EF },
["firecracker"]={ 0x1F9E8 },
+ ["firefighter"]={ 0x1F9D1, 0x200D, 0x1F692 },
+ ["firefighter: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F692 },
+ ["firefighter: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F692 },
+ ["firefighter: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F692 },
+ ["firefighter: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F692 },
+ ["firefighter: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F692 },
["fireworks"]={ 0x1F386 },
["first quarter moon"]={ 0x1F313 },
["first quarter moon face"]={ 0x1F31B },
@@ -684,7 +733,6 @@ return {
["flag: lithuania"]={ 0x1F1F1, 0x1F1F9 },
["flag: luxembourg"]={ 0x1F1F1, 0x1F1FA },
["flag: macao sar china"]={ 0x1F1F2, 0x1F1F4 },
- ["flag: macedonia"]={ 0x1F1F2, 0x1F1F0 },
["flag: madagascar"]={ 0x1F1F2, 0x1F1EC },
["flag: malawi"]={ 0x1F1F2, 0x1F1FC },
["flag: malaysia"]={ 0x1F1F2, 0x1F1FE },
@@ -718,6 +766,7 @@ return {
["flag: niue"]={ 0x1F1F3, 0x1F1FA },
["flag: norfolk island"]={ 0x1F1F3, 0x1F1EB },
["flag: north korea"]={ 0x1F1F0, 0x1F1F5 },
+ ["flag: north macedonia"]={ 0x1F1F2, 0x1F1F0 },
["flag: northern mariana islands"]={ 0x1F1F2, 0x1F1F5 },
["flag: norway"]={ 0x1F1F3, 0x1F1F4 },
["flag: oman"]={ 0x1F1F4, 0x1F1F2 },
@@ -811,6 +860,7 @@ return {
["flamingo"]={ 0x1F9A9 },
["flashlight"]={ 0x1F526 },
["flat shoe"]={ 0x1F97F },
+ ["flatbread"]={ 0x1FAD3 },
["fleur-de-lis"]={ 0x269C, 0xFE0F },
["flexed biceps"]={ 0x1F4AA },
["flexed biceps: dark skin tone"]={ 0x1F4AA, 0x1F3FF },
@@ -821,6 +871,7 @@ return {
["floppy disk"]={ 0x1F4BE },
["flower playing cards"]={ 0x1F3B4 },
["flushed face"]={ 0x1F633 },
+ ["fly"]={ 0x1FAB0 },
["flying disc"]={ 0x1F94F },
["flying saucer"]={ 0x1F6F8 },
["fog"]={ 0x1F32B, 0xFE0F },
@@ -831,6 +882,7 @@ return {
["folded hands: medium skin tone"]={ 0x1F64F, 0x1F3FD },
["folded hands: medium-dark skin tone"]={ 0x1F64F, 0x1F3FE },
["folded hands: medium-light skin tone"]={ 0x1F64F, 0x1F3FC },
+ ["fondue"]={ 0x1FAD5 },
["foot"]={ 0x1F9B6 },
["foot: dark skin tone"]={ 0x1F9B6, 0x1F3FF },
["foot: light skin tone"]={ 0x1F9B6, 0x1F3FB },
@@ -926,6 +978,13 @@ return {
["handshake"]={ 0x1F91D },
["hatching chick"]={ 0x1F423 },
["headphone"]={ 0x1F3A7 },
+ ["headstone"]={ 0x1FAA6 },
+ ["health worker"]={ 0x1F9D1, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x2695, 0xFE0F },
+ ["health worker: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x2695, 0xFE0F },
["hear-no-evil monkey"]={ 0x1F649 },
["heart decoration"]={ 0x1F49F },
["heart exclamation"]={ 0x2763, 0xFE0F },
@@ -947,6 +1006,7 @@ return {
["hollow red circle"]={ 0x2B55 },
["honey pot"]={ 0x1F36F },
["honeybee"]={ 0x1F41D },
+ ["hook"]={ 0x1FA9D },
["horizontal traffic light"]={ 0x1F6A5 },
["horse"]={ 0x1F40E },
["horse face"]={ 0x1F434 },
@@ -971,8 +1031,9 @@ return {
["hugging face"]={ 0x1F917 },
["hundred points"]={ 0x1F4AF },
["hushed face"]={ 0x1F62F },
+ ["hut"]={ 0x1F6D6 },
+ ["ice"]={ 0x1F9CA },
["ice cream"]={ 0x1F368 },
- ["ice cube"]={ 0x1F9CA },
["ice hockey"]={ 0x1F3D2 },
["ice skate"]={ 0x26F8, 0xFE0F },
["id button"]={ 0x1F194 },
@@ -1016,6 +1077,12 @@ return {
["jeans"]={ 0x1F456 },
["joker"]={ 0x1F0CF },
["joystick"]={ 0x1F579, 0xFE0F },
+ ["judge"]={ 0x1F9D1, 0x200D, 0x2696, 0xFE0F },
+ ["judge: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x2696, 0xFE0F },
+ ["judge: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x2696, 0xFE0F },
+ ["judge: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x2696, 0xFE0F },
+ ["judge: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x2696, 0xFE0F },
+ ["judge: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x2696, 0xFE0F },
["kaaba"]={ 0x1F54B },
["kangaroo"]={ 0x1F998 },
["key"]={ 0x1F511 },
@@ -1047,12 +1114,14 @@ return {
["kitchen knife"]={ 0x1F52A },
["kite"]={ 0x1FA81 },
["kiwi fruit"]={ 0x1F95D },
+ ["knot"]={ 0x1FAA2 },
["koala"]={ 0x1F428 },
["lab coat"]={ 0x1F97C },
["label"]={ 0x1F3F7, 0xFE0F },
["lacrosse"]={ 0x1F94D },
+ ["ladder"]={ 0x1FA9C },
["lady beetle"]={ 0x1F41E },
- ["laptop computer"]={ 0x1F4BB },
+ ["laptop"]={ 0x1F4BB },
["large blue diamond"]={ 0x1F537 },
["large orange diamond"]={ 0x1F536 },
["last quarter moon"]={ 0x1F317 },
@@ -1099,6 +1168,7 @@ return {
["locked with pen"]={ 0x1F50F },
["locomotive"]={ 0x1F682 },
["lollipop"]={ 0x1F36D },
+ ["long drum"]={ 0x1FA98 },
["lotion bottle"]={ 0x1F9F4 },
["loudly crying face"]={ 0x1F62D },
["loudspeaker"]={ 0x1F4E2 },
@@ -1111,6 +1181,7 @@ return {
["love-you gesture: medium-dark skin tone"]={ 0x1F91F, 0x1F3FE },
["love-you gesture: medium-light skin tone"]={ 0x1F91F, 0x1F3FC },
["luggage"]={ 0x1F9F3 },
+ ["lungs"]={ 0x1FAC1 },
["lying face"]={ 0x1F925 },
["mage"]={ 0x1F9D9 },
["mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF },
@@ -1118,11 +1189,13 @@ return {
["mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD },
["mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE },
["mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC },
+ ["magic wand"]={ 0x1FA84 },
["magnet"]={ 0x1F9F2 },
["magnifying glass tilted left"]={ 0x1F50D },
["magnifying glass tilted right"]={ 0x1F50E },
["mahjong red dragon"]={ 0x1F004 },
["male sign"]={ 0x2642, 0xFE0F },
+ ["mammoth"]={ 0x1F9A3 },
["man"]={ 0x1F468 },
["man artist"]={ 0x1F468, 0x200D, 0x1F3A8 },
["man artist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3A8 },
@@ -1220,6 +1293,12 @@ return {
["man farmer: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F33E },
["man farmer: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F33E },
["man farmer: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F33E },
+ ["man feeding baby"]={ 0x1F468, 0x200D, 0x1F37C },
+ ["man feeding baby: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F37C },
+ ["man feeding baby: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F37C },
+ ["man feeding baby: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F37C },
+ ["man feeding baby: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F37C },
+ ["man feeding baby: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F37C },
["man firefighter"]={ 0x1F468, 0x200D, 0x1F692 },
["man firefighter: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F692 },
["man firefighter: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F692 },
@@ -1299,18 +1378,12 @@ return {
["man in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2642, 0xFE0F },
["man in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2642, 0xFE0F },
["man in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2642, 0xFE0F },
- ["man in suit levitating"]={ 0x1F574, 0xFE0F },
- ["man in suit levitating: dark skin tone"]={ 0x1F574, 0x1F3FF },
- ["man in suit levitating: light skin tone"]={ 0x1F574, 0x1F3FB },
- ["man in suit levitating: medium skin tone"]={ 0x1F574, 0x1F3FD },
- ["man in suit levitating: medium-dark skin tone"]={ 0x1F574, 0x1F3FE },
- ["man in suit levitating: medium-light skin tone"]={ 0x1F574, 0x1F3FC },
- ["man in tuxedo"]={ 0x1F935 },
- ["man in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF },
- ["man in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB },
- ["man in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD },
- ["man in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE },
- ["man in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC },
+ ["man in tuxedo"]={ 0x1F935, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE, 0x200D, 0x2642, 0xFE0F },
+ ["man in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC, 0x200D, 0x2642, 0xFE0F },
["man judge"]={ 0x1F468, 0x200D, 0x2696, 0xFE0F },
["man judge: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2696, 0xFE0F },
["man judge: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2696, 0xFE0F },
@@ -1497,18 +1570,18 @@ return {
["man wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2642, 0xFE0F },
["man wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2642, 0xFE0F },
["man wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2642, 0xFE0F },
- ["man with chinese cap"]={ 0x1F472 },
- ["man with chinese cap: dark skin tone"]={ 0x1F472, 0x1F3FF },
- ["man with chinese cap: light skin tone"]={ 0x1F472, 0x1F3FB },
- ["man with chinese cap: medium skin tone"]={ 0x1F472, 0x1F3FD },
- ["man with chinese cap: medium-dark skin tone"]={ 0x1F472, 0x1F3FE },
- ["man with chinese cap: medium-light skin tone"]={ 0x1F472, 0x1F3FC },
- ["man with probing cane"]={ 0x1F468, 0x200D, 0x1F9AF },
- ["man with probing cane: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9AF },
- ["man with probing cane: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9AF },
- ["man with probing cane: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9AF },
- ["man with probing cane: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9AF },
- ["man with probing cane: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9AF },
+ ["man with veil"]={ 0x1F470, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: dark skin tone"]={ 0x1F470, 0x1F3FF, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: light skin tone"]={ 0x1F470, 0x1F3FB, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: medium skin tone"]={ 0x1F470, 0x1F3FD, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE, 0x200D, 0x2642, 0xFE0F },
+ ["man with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC, 0x200D, 0x2642, 0xFE0F },
+ ["man with white cane"]={ 0x1F468, 0x200D, 0x1F9AF },
+ ["man with white cane: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9AF },
+ ["man with white cane: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9AF },
+ ["man with white cane: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9AF },
+ ["man with white cane: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9AF },
+ ["man with white cane: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9AF },
["man zombie"]={ 0x1F9DF, 0x200D, 0x2642, 0xFE0F },
["man: bald"]={ 0x1F468, 0x200D, 0x1F9B2 },
["man: beard"]={ 0x1F9D4 },
@@ -1560,6 +1633,12 @@ return {
["martial arts uniform"]={ 0x1F94B },
["mate"]={ 0x1F9C9 },
["meat on bone"]={ 0x1F356 },
+ ["mechanic"]={ 0x1F9D1, 0x200D, 0x1F527 },
+ ["mechanic: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F527 },
+ ["mechanic: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F527 },
+ ["mechanic: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F527 },
+ ["mechanic: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F527 },
+ ["mechanic: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F527 },
["mechanical arm"]={ 0x1F9BE },
["mechanical leg"]={ 0x1F9BF },
["medical symbol"]={ 0x2695, 0xFE0F },
@@ -1573,15 +1652,25 @@ return {
["men holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE },
["men holding hands: dark skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC },
["men holding hands: light skin tone"]={ 0x1F46C, 0x1F3FB },
+ ["men holding hands: light skin tone, dark skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF },
+ ["men holding hands: light skin tone, medium skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD },
+ ["men holding hands: light skin tone, medium-dark skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE },
+ ["men holding hands: light skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC },
["men holding hands: medium skin tone"]={ 0x1F46C, 0x1F3FD },
+ ["men holding hands: medium skin tone, dark skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF },
["men holding hands: medium skin tone, light skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB },
+ ["men holding hands: medium skin tone, medium-dark skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE },
["men holding hands: medium skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC },
["men holding hands: medium-dark skin tone"]={ 0x1F46C, 0x1F3FE },
+ ["men holding hands: medium-dark skin tone, dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF },
["men holding hands: medium-dark skin tone, light skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB },
["men holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD },
["men holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC },
["men holding hands: medium-light skin tone"]={ 0x1F46C, 0x1F3FC },
+ ["men holding hands: medium-light skin tone, dark skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF },
["men holding hands: medium-light skin tone, light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB },
+ ["men holding hands: medium-light skin tone, medium skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD },
+ ["men holding hands: medium-light skin tone, medium-dark skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE },
["men with bunny ears"]={ 0x1F46F, 0x200D, 0x2642, 0xFE0F },
["men wrestling"]={ 0x1F93C, 0x200D, 0x2642, 0xFE0F },
["menorah"]={ 0x1F54E },
@@ -1614,10 +1703,12 @@ return {
["middle finger: medium skin tone"]={ 0x1F595, 0x1F3FD },
["middle finger: medium-dark skin tone"]={ 0x1F595, 0x1F3FE },
["middle finger: medium-light skin tone"]={ 0x1F595, 0x1F3FC },
+ ["military helmet"]={ 0x1FA96 },
["military medal"]={ 0x1F396, 0xFE0F },
["milky way"]={ 0x1F30C },
["minibus"]={ 0x1F690 },
- ["minus sign"]={ 0x2796 },
+ ["minus"]={ 0x2796 },
+ ["mirror"]={ 0x1FA9E },
["moai"]={ 0x1F5FF },
["mobile phone"]={ 0x1F4F1 },
["mobile phone off"]={ 0x1F4F4 },
@@ -1643,6 +1734,7 @@ return {
["mountain railway"]={ 0x1F69E },
["mouse"]={ 0x1F401 },
["mouse face"]={ 0x1F42D },
+ ["mouse trap"]={ 0x1FAA4 },
["mouth"]={ 0x1F444 },
["movie camera"]={ 0x1F3A5 },
["mrs. claus"]={ 0x1F936 },
@@ -1651,13 +1743,19 @@ return {
["mrs. claus: medium skin tone"]={ 0x1F936, 0x1F3FD },
["mrs. claus: medium-dark skin tone"]={ 0x1F936, 0x1F3FE },
["mrs. claus: medium-light skin tone"]={ 0x1F936, 0x1F3FC },
- ["multiplication sign"]={ 0x2716, 0xFE0F },
+ ["multiply"]={ 0x2716, 0xFE0F },
["mushroom"]={ 0x1F344 },
["musical keyboard"]={ 0x1F3B9 },
["musical note"]={ 0x1F3B5 },
["musical notes"]={ 0x1F3B6 },
["musical score"]={ 0x1F3BC },
["muted speaker"]={ 0x1F507 },
+ ["mx claus"]={ 0x1F9D1, 0x200D, 0x1F384 },
+ ["mx claus: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F384 },
+ ["mx claus: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F384 },
+ ["mx claus: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F384 },
+ ["mx claus: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F384 },
+ ["mx claus: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F384 },
["nail polish"]={ 0x1F485 },
["nail polish: dark skin tone"]={ 0x1F485, 0x1F3FF },
["nail polish: light skin tone"]={ 0x1F485, 0x1F3FB },
@@ -1670,6 +1768,7 @@ return {
["nazar amulet"]={ 0x1F9FF },
["necktie"]={ 0x1F454 },
["nerd face"]={ 0x1F913 },
+ ["nesting dolls"]={ 0x1FA86 },
["neutral face"]={ 0x1F610 },
["new button"]={ 0x1F195 },
["new moon"]={ 0x1F311 },
@@ -1680,6 +1779,12 @@ return {
["night with stars"]={ 0x1F303 },
["nine o’clock"]={ 0x1F558 },
["nine-thirty"]={ 0x1F564 },
+ ["ninja"]={ 0x1F977 },
+ ["ninja: dark skin tone"]={ 0x1F977, 0x1F3FF },
+ ["ninja: light skin tone"]={ 0x1F977, 0x1F3FB },
+ ["ninja: medium skin tone"]={ 0x1F977, 0x1F3FD },
+ ["ninja: medium-dark skin tone"]={ 0x1F977, 0x1F3FE },
+ ["ninja: medium-light skin tone"]={ 0x1F977, 0x1F3FC },
["no bicycles"]={ 0x1F6B3 },
["no entry"]={ 0x26D4 },
["no littering"]={ 0x1F6AF },
@@ -1701,6 +1806,12 @@ return {
["octopus"]={ 0x1F419 },
["oden"]={ 0x1F362 },
["office building"]={ 0x1F3E2 },
+ ["office worker"]={ 0x1F9D1, 0x200D, 0x1F4BC },
+ ["office worker: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F4BC },
+ ["office worker: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F4BC },
+ ["office worker: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F4BC },
+ ["office worker: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F4BC },
+ ["office worker: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F4BC },
["ogre"]={ 0x1F479 },
["oil drum"]={ 0x1F6E2, 0xFE0F },
["ok button"]={ 0x1F197 },
@@ -1729,6 +1840,7 @@ return {
["older person: medium skin tone"]={ 0x1F9D3, 0x1F3FD },
["older person: medium-dark skin tone"]={ 0x1F9D3, 0x1F3FE },
["older person: medium-light skin tone"]={ 0x1F9D3, 0x1F3FC },
+ ["olive"]={ 0x1FAD2 },
["om"]={ 0x1F549, 0xFE0F },
["on! arrow"]={ 0x1F51B },
["oncoming automobile"]={ 0x1F698 },
@@ -1809,15 +1921,26 @@ return {
["people holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
["people holding hands: dark skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
["people holding hands: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB },
+ ["people holding hands: light skin tone, dark skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FF },
+ ["people holding hands: light skin tone, medium skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD },
+ ["people holding hands: light skin tone, medium-dark skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
+ ["people holding hands: light skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
["people holding hands: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD },
+ ["people holding hands: medium skin tone, dark skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FF },
["people holding hands: medium skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB },
+ ["people holding hands: medium skin tone, medium-dark skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
["people holding hands: medium skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
["people holding hands: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
+ ["people holding hands: medium-dark skin tone, dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FF },
["people holding hands: medium-dark skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB },
["people holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD },
["people holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
["people holding hands: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC },
+ ["people holding hands: medium-light skin tone, dark skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FF },
["people holding hands: medium-light skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB },
+ ["people holding hands: medium-light skin tone, medium skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD },
+ ["people holding hands: medium-light skin tone, medium-dark skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE },
+ ["people hugging"]={ 0x1FAC2 },
["people with bunny ears"]={ 0x1F46F },
["people wrestling"]={ 0x1F93C },
["performing arts"]={ 0x1F3AD },
@@ -1859,6 +1982,12 @@ return {
["person facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD },
["person facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE },
["person facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC },
+ ["person feeding baby"]={ 0x1F9D1, 0x200D, 0x1F37C },
+ ["person feeding baby: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F37C },
+ ["person feeding baby: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F37C },
+ ["person feeding baby: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F37C },
+ ["person feeding baby: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F37C },
+ ["person feeding baby: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F37C },
["person fencing"]={ 0x1F93A },
["person frowning"]={ 0x1F64D },
["person frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF },
@@ -1908,12 +2037,36 @@ return {
["person in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD },
["person in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE },
["person in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC },
+ ["person in manual wheelchair"]={ 0x1F9D1, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9BD },
+ ["person in manual wheelchair: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9BD },
+ ["person in motorized wheelchair"]={ 0x1F9D1, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9BC },
+ ["person in motorized wheelchair: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9BC },
["person in steamy room"]={ 0x1F9D6 },
["person in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF },
["person in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB },
["person in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD },
["person in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE },
["person in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC },
+ ["person in suit levitating"]={ 0x1F574, 0xFE0F },
+ ["person in suit levitating: dark skin tone"]={ 0x1F574, 0x1F3FF },
+ ["person in suit levitating: light skin tone"]={ 0x1F574, 0x1F3FB },
+ ["person in suit levitating: medium skin tone"]={ 0x1F574, 0x1F3FD },
+ ["person in suit levitating: medium-dark skin tone"]={ 0x1F574, 0x1F3FE },
+ ["person in suit levitating: medium-light skin tone"]={ 0x1F574, 0x1F3FC },
+ ["person in tuxedo"]={ 0x1F935 },
+ ["person in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF },
+ ["person in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB },
+ ["person in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD },
+ ["person in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE },
+ ["person in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC },
["person juggling"]={ 0x1F939 },
["person juggling: dark skin tone"]={ 0x1F939, 0x1F3FF },
["person juggling: light skin tone"]={ 0x1F939, 0x1F3FB },
@@ -2022,25 +2175,80 @@ return {
["person wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD },
["person wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE },
["person wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC },
+ ["person with skullcap"]={ 0x1F472 },
+ ["person with skullcap: dark skin tone"]={ 0x1F472, 0x1F3FF },
+ ["person with skullcap: light skin tone"]={ 0x1F472, 0x1F3FB },
+ ["person with skullcap: medium skin tone"]={ 0x1F472, 0x1F3FD },
+ ["person with skullcap: medium-dark skin tone"]={ 0x1F472, 0x1F3FE },
+ ["person with skullcap: medium-light skin tone"]={ 0x1F472, 0x1F3FC },
+ ["person with veil"]={ 0x1F470 },
+ ["person with veil: dark skin tone"]={ 0x1F470, 0x1F3FF },
+ ["person with veil: light skin tone"]={ 0x1F470, 0x1F3FB },
+ ["person with veil: medium skin tone"]={ 0x1F470, 0x1F3FD },
+ ["person with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE },
+ ["person with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC },
+ ["person with white cane"]={ 0x1F9D1, 0x200D, 0x1F9AF },
+ ["person with white cane: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9AF },
+ ["person with white cane: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9AF },
+ ["person with white cane: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9AF },
+ ["person with white cane: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9AF },
+ ["person with white cane: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9AF },
+ ["person: bald"]={ 0x1F9D1, 0x200D, 0x1F9B2 },
["person: blond hair"]={ 0x1F471 },
+ ["person: curly hair"]={ 0x1F9D1, 0x200D, 0x1F9B1 },
["person: dark skin tone"]={ 0x1F9D1, 0x1F3FF },
+ ["person: dark skin tone, bald"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9B2 },
["person: dark skin tone, blond hair"]={ 0x1F471, 0x1F3FF },
+ ["person: dark skin tone, curly hair"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9B1 },
+ ["person: dark skin tone, red hair"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9B0 },
+ ["person: dark skin tone, white hair"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F9B3 },
["person: light skin tone"]={ 0x1F9D1, 0x1F3FB },
+ ["person: light skin tone, bald"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9B2 },
["person: light skin tone, blond hair"]={ 0x1F471, 0x1F3FB },
+ ["person: light skin tone, curly hair"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9B1 },
+ ["person: light skin tone, red hair"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9B0 },
+ ["person: light skin tone, white hair"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F9B3 },
["person: medium skin tone"]={ 0x1F9D1, 0x1F3FD },
+ ["person: medium skin tone, bald"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9B2 },
["person: medium skin tone, blond hair"]={ 0x1F471, 0x1F3FD },
+ ["person: medium skin tone, curly hair"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9B1 },
+ ["person: medium skin tone, red hair"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9B0 },
+ ["person: medium skin tone, white hair"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F9B3 },
["person: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE },
+ ["person: medium-dark skin tone, bald"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9B2 },
["person: medium-dark skin tone, blond hair"]={ 0x1F471, 0x1F3FE },
+ ["person: medium-dark skin tone, curly hair"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9B1 },
+ ["person: medium-dark skin tone, red hair"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9B0 },
+ ["person: medium-dark skin tone, white hair"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F9B3 },
["person: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC },
+ ["person: medium-light skin tone, bald"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9B2 },
["person: medium-light skin tone, blond hair"]={ 0x1F471, 0x1F3FC },
+ ["person: medium-light skin tone, curly hair"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9B1 },
+ ["person: medium-light skin tone, red hair"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9B0 },
+ ["person: medium-light skin tone, white hair"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F9B3 },
+ ["person: red hair"]={ 0x1F9D1, 0x200D, 0x1F9B0 },
+ ["person: white hair"]={ 0x1F9D1, 0x200D, 0x1F9B3 },
["petri dish"]={ 0x1F9EB },
["pick"]={ 0x26CF, 0xFE0F },
+ ["pickup truck"]={ 0x1F6FB },
["pie"]={ 0x1F967 },
["pig"]={ 0x1F416 },
["pig face"]={ 0x1F437 },
["pig nose"]={ 0x1F43D },
["pile of poo"]={ 0x1F4A9 },
["pill"]={ 0x1F48A },
+ ["pilot"]={ 0x1F9D1, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x2708, 0xFE0F },
+ ["pilot: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x2708, 0xFE0F },
+ ["pinched fingers"]={ 0x1F90C },
+ ["pinched fingers: dark skin tone"]={ 0x1F90C, 0x1F3FF },
+ ["pinched fingers: light skin tone"]={ 0x1F90C, 0x1F3FB },
+ ["pinched fingers: medium skin tone"]={ 0x1F90C, 0x1F3FD },
+ ["pinched fingers: medium-dark skin tone"]={ 0x1F90C, 0x1F3FE },
+ ["pinched fingers: medium-light skin tone"]={ 0x1F90C, 0x1F3FC },
["pinching hand"]={ 0x1F90F },
["pinching hand: dark skin tone"]={ 0x1F90F, 0x1F3FF },
["pinching hand: light skin tone"]={ 0x1F90F, 0x1F3FB },
@@ -2054,11 +2262,15 @@ return {
["pisces"]={ 0x2653 },
["pistol"]={ 0x1F52B },
["pizza"]={ 0x1F355 },
+ ["piñata"]={ 0x1FA85 },
+ ["placard"]={ 0x1FAA7 },
["place of worship"]={ 0x1F6D0 },
["play button"]={ 0x25B6, 0xFE0F },
["play or pause button"]={ 0x23EF, 0xFE0F },
["pleading face"]={ 0x1F97A },
- ["plus sign"]={ 0x2795 },
+ ["plunger"]={ 0x1FAA0 },
+ ["plus"]={ 0x2795 },
+ ["polar bear"]={ 0x1F43B, 0x200D, 0x2744, 0xFE0F },
["police car"]={ 0x1F693 },
["police car light"]={ 0x1F6A8 },
["police officer"]={ 0x1F46E },
@@ -2076,6 +2288,7 @@ return {
["pot of food"]={ 0x1F372 },
["potable water"]={ 0x1F6B0 },
["potato"]={ 0x1F954 },
+ ["potted plant"]={ 0x1FAB4 },
["poultry leg"]={ 0x1F357 },
["pound banknote"]={ 0x1F4B7 },
["pouting cat"]={ 0x1F63E },
@@ -2101,7 +2314,6 @@ return {
["princess: medium-dark skin tone"]={ 0x1F478, 0x1F3FE },
["princess: medium-light skin tone"]={ 0x1F478, 0x1F3FC },
["printer"]={ 0x1F5A8, 0xFE0F },
- ["probing cane"]={ 0x1F9AF },
["prohibited"]={ 0x1F6AB },
["purple circle"]={ 0x1F7E3 },
["purple heart"]={ 0x1F49C },
@@ -2187,10 +2399,12 @@ return {
["ringed planet"]={ 0x1FA90 },
["roasted sweet potato"]={ 0x1F360 },
["robot"]={ 0x1F916 },
+ ["rock"]={ 0x1FAA8 },
["rocket"]={ 0x1F680 },
["roll of paper"]={ 0x1F9FB },
["rolled-up newspaper"]={ 0x1F5DE, 0xFE0F },
["roller coaster"]={ 0x1F3A2 },
+ ["roller skate"]={ 0x1F6FC },
["rolling on the floor laughing"]={ 0x1F923 },
["rooster"]={ 0x1F413 },
["rose"]={ 0x1F339 },
@@ -2220,10 +2434,18 @@ return {
["saxophone"]={ 0x1F3B7 },
["scarf"]={ 0x1F9E3 },
["school"]={ 0x1F3EB },
+ ["scientist"]={ 0x1F9D1, 0x200D, 0x1F52C },
+ ["scientist: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F52C },
+ ["scientist: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F52C },
+ ["scientist: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F52C },
+ ["scientist: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F52C },
+ ["scientist: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F52C },
["scissors"]={ 0x2702, 0xFE0F },
["scorpio"]={ 0x264F },
["scorpion"]={ 0x1F982 },
+ ["screwdriver"]={ 0x1FA9B },
["scroll"]={ 0x1F4DC },
+ ["seal"]={ 0x1F9AD },
["seat"]={ 0x1F4BA },
["see-no-evil monkey"]={ 0x1F648 },
["seedling"]={ 0x1F331 },
@@ -2236,6 +2458,7 @@ return {
["service dog"]={ 0x1F415, 0x200D, 0x1F9BA },
["seven o’clock"]={ 0x1F556 },
["seven-thirty"]={ 0x1F562 },
+ ["sewing needle"]={ 0x1FAA1 },
["shallow pan of food"]={ 0x1F958 },
["shamrock"]={ 0x2618, 0xFE0F },
["shark"]={ 0x1F988 },
@@ -2259,6 +2482,12 @@ return {
["sign of the horns: medium skin tone"]={ 0x1F918, 0x1F3FD },
["sign of the horns: medium-dark skin tone"]={ 0x1F918, 0x1F3FE },
["sign of the horns: medium-light skin tone"]={ 0x1F918, 0x1F3FC },
+ ["singer"]={ 0x1F9D1, 0x200D, 0x1F3A4 },
+ ["singer: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F3A4 },
+ ["singer: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F3A4 },
+ ["singer: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F3A4 },
+ ["singer: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F3A4 },
+ ["singer: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F3A4 },
["six o’clock"]={ 0x1F555 },
["six-thirty"]={ 0x1F561 },
["skateboard"]={ 0x1F6F9 },
@@ -2285,6 +2514,7 @@ return {
["smiling face with horns"]={ 0x1F608 },
["smiling face with smiling eyes"]={ 0x1F60A },
["smiling face with sunglasses"]={ 0x1F60E },
+ ["smiling face with tear"]={ 0x1F972 },
["smirking face"]={ 0x1F60F },
["snail"]={ 0x1F40C },
["snake"]={ 0x1F40D },
@@ -2345,6 +2575,12 @@ return {
["stopwatch"]={ 0x23F1, 0xFE0F },
["straight ruler"]={ 0x1F4CF },
["strawberry"]={ 0x1F353 },
+ ["student"]={ 0x1F9D1, 0x200D, 0x1F393 },
+ ["student: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F393 },
+ ["student: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F393 },
+ ["student: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F393 },
+ ["student: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F393 },
+ ["student: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F393 },
["studio microphone"]={ 0x1F399, 0xFE0F },
["stuffed flatbread"]={ 0x1F959 },
["sun"]={ 0x2600, 0xFE0F },
@@ -2374,19 +2610,32 @@ return {
["suspension railway"]={ 0x1F69F },
["swan"]={ 0x1F9A2 },
["sweat droplets"]={ 0x1F4A6 },
- ["swim brief"]={ 0x1FA72 },
["synagogue"]={ 0x1F54D },
["syringe"]={ 0x1F489 },
["t-rex"]={ 0x1F996 },
["t-shirt"]={ 0x1F455 },
["taco"]={ 0x1F32E },
["takeout box"]={ 0x1F961 },
+ ["tamale"]={ 0x1FAD4 },
["tanabata tree"]={ 0x1F38B },
["tangerine"]={ 0x1F34A },
["taurus"]={ 0x2649 },
["taxi"]={ 0x1F695 },
+ ["teacher"]={ 0x1F9D1, 0x200D, 0x1F3EB },
+ ["teacher: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F3EB },
+ ["teacher: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F3EB },
+ ["teacher: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F3EB },
+ ["teacher: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F3EB },
+ ["teacher: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F3EB },
["teacup without handle"]={ 0x1F375 },
+ ["teapot"]={ 0x1FAD6 },
["tear-off calendar"]={ 0x1F4C6 },
+ ["technologist"]={ 0x1F9D1, 0x200D, 0x1F4BB },
+ ["technologist: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F4BB },
+ ["technologist: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F4BB },
+ ["technologist: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F4BB },
+ ["technologist: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F4BB },
+ ["technologist: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F4BB },
["teddy bear"]={ 0x1F9F8 },
["telephone"]={ 0x260E, 0xFE0F },
["telephone receiver"]={ 0x1F4DE },
@@ -2399,6 +2648,7 @@ return {
["test tube"]={ 0x1F9EA },
["thermometer"]={ 0x1F321, 0xFE0F },
["thinking face"]={ 0x1F914 },
+ ["thong sandal"]={ 0x1FA74 },
["thought balloon"]={ 0x1F4AD },
["thread"]={ 0x1F9F5 },
["three o’clock"]={ 0x1F552 },
@@ -2426,6 +2676,7 @@ return {
["tongue"]={ 0x1F445 },
["toolbox"]={ 0x1F9F0 },
["tooth"]={ 0x1F9B7 },
+ ["toothbrush"]={ 0x1FAA5 },
["top arrow"]={ 0x1F51D },
["top hat"]={ 0x1F3A9 },
["tornado"]={ 0x1F32A, 0xFE0F },
@@ -2435,6 +2686,8 @@ return {
["train"]={ 0x1F686 },
["tram"]={ 0x1F68A },
["tram car"]={ 0x1F68B },
+ ["transgender flag"]={ 0x1F3F3, 0xFE0F, 0x200D, 0x26A7, 0xFE0F },
+ ["transgender symbol"]={ 0x26A7, 0xFE0F },
["triangular flag"]={ 0x1F6A9 },
["triangular ruler"]={ 0x1F4D0 },
["trident emblem"]={ 0x1F531 },
@@ -2519,6 +2772,7 @@ return {
["whale"]={ 0x1F40B },
["wheel of dharma"]={ 0x2638, 0xFE0F },
["wheelchair symbol"]={ 0x267F },
+ ["white cane"]={ 0x1F9AF },
["white circle"]={ 0x26AA },
["white exclamation mark"]={ 0x2755 },
["white flag"]={ 0x1F3F3, 0xFE0F },
@@ -2533,6 +2787,7 @@ return {
["wilted flower"]={ 0x1F940 },
["wind chime"]={ 0x1F390 },
["wind face"]={ 0x1F32C, 0xFE0F },
+ ["window"]={ 0x1FA9F },
["wine glass"]={ 0x1F377 },
["winking face"]={ 0x1F609 },
["winking face with tongue"]={ 0x1F61C },
@@ -2660,6 +2915,12 @@ return {
["woman farmer: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F33E },
["woman farmer: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F33E },
["woman farmer: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F33E },
+ ["woman feeding baby"]={ 0x1F469, 0x200D, 0x1F37C },
+ ["woman feeding baby: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F37C },
+ ["woman feeding baby: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F37C },
+ ["woman feeding baby: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F37C },
+ ["woman feeding baby: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F37C },
+ ["woman feeding baby: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F37C },
["woman firefighter"]={ 0x1F469, 0x200D, 0x1F692 },
["woman firefighter: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F692 },
["woman firefighter: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F692 },
@@ -2739,6 +3000,12 @@ return {
["woman in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2640, 0xFE0F },
["woman in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2640, 0xFE0F },
["woman in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo"]={ 0x1F935, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE, 0x200D, 0x2640, 0xFE0F },
+ ["woman in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC, 0x200D, 0x2640, 0xFE0F },
["woman judge"]={ 0x1F469, 0x200D, 0x2696, 0xFE0F },
["woman judge: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2696, 0xFE0F },
["woman judge: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2696, 0xFE0F },
@@ -2931,12 +3198,18 @@ return {
["woman with headscarf: medium skin tone"]={ 0x1F9D5, 0x1F3FD },
["woman with headscarf: medium-dark skin tone"]={ 0x1F9D5, 0x1F3FE },
["woman with headscarf: medium-light skin tone"]={ 0x1F9D5, 0x1F3FC },
- ["woman with probing cane"]={ 0x1F469, 0x200D, 0x1F9AF },
- ["woman with probing cane: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9AF },
- ["woman with probing cane: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9AF },
- ["woman with probing cane: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9AF },
- ["woman with probing cane: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9AF },
- ["woman with probing cane: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9AF },
+ ["woman with veil"]={ 0x1F470, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: dark skin tone"]={ 0x1F470, 0x1F3FF, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: light skin tone"]={ 0x1F470, 0x1F3FB, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: medium skin tone"]={ 0x1F470, 0x1F3FD, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: medium-dark skin tone"]={ 0x1F470, 0x1F3FE, 0x200D, 0x2640, 0xFE0F },
+ ["woman with veil: medium-light skin tone"]={ 0x1F470, 0x1F3FC, 0x200D, 0x2640, 0xFE0F },
+ ["woman with white cane"]={ 0x1F469, 0x200D, 0x1F9AF },
+ ["woman with white cane: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9AF },
+ ["woman with white cane: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9AF },
+ ["woman with white cane: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9AF },
+ ["woman with white cane: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9AF },
+ ["woman with white cane: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9AF },
["woman zombie"]={ 0x1F9DF, 0x200D, 0x2640, 0xFE0F },
["woman: bald"]={ 0x1F469, 0x200D, 0x1F9B2 },
["woman: blond hair"]={ 0x1F471, 0x200D, 0x2640, 0xFE0F },
@@ -2984,20 +3257,32 @@ return {
["women holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FE },
["women holding hands: dark skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC },
["women holding hands: light skin tone"]={ 0x1F46D, 0x1F3FB },
+ ["women holding hands: light skin tone, dark skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FF },
+ ["women holding hands: light skin tone, medium skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FD },
+ ["women holding hands: light skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FE },
+ ["women holding hands: light skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC },
["women holding hands: medium skin tone"]={ 0x1F46D, 0x1F3FD },
+ ["women holding hands: medium skin tone, dark skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FF },
["women holding hands: medium skin tone, light skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB },
+ ["women holding hands: medium skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FE },
["women holding hands: medium skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC },
["women holding hands: medium-dark skin tone"]={ 0x1F46D, 0x1F3FE },
+ ["women holding hands: medium-dark skin tone, dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FF },
["women holding hands: medium-dark skin tone, light skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB },
["women holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FD },
["women holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC },
["women holding hands: medium-light skin tone"]={ 0x1F46D, 0x1F3FC },
+ ["women holding hands: medium-light skin tone, dark skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FF },
["women holding hands: medium-light skin tone, light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB },
+ ["women holding hands: medium-light skin tone, medium skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FD },
+ ["women holding hands: medium-light skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FE },
["women with bunny ears"]={ 0x1F46F, 0x200D, 0x2640, 0xFE0F },
["women wrestling"]={ 0x1F93C, 0x200D, 0x2640, 0xFE0F },
["women’s room"]={ 0x1F6BA },
+ ["wood"]={ 0x1FAB5 },
["woozy face"]={ 0x1F974 },
["world map"]={ 0x1F5FA, 0xFE0F },
+ ["worm"]={ 0x1FAB1 },
["worried face"]={ 0x1F61F },
["wrapped gift"]={ 0x1F381 },
["wrench"]={ 0x1F527 },
diff --git a/tex/context/base/mkiv/cont-fil.mkiv b/tex/context/base/mkiv/cont-fil.mkiv
index 9257e2e1e..aa7d9ddb3 100644
--- a/tex/context/base/mkiv/cont-fil.mkiv
+++ b/tex/context/base/mkiv/cont-fil.mkiv
@@ -16,137 +16,142 @@
\writestatus{loading}{ConTeXt File Synonyms}
-\definefilesynonym [chemics] [chemic]
-
-\definefilesynonym [unit] [units]
-
-\definefilesynonym [pstric] [pstricks]
-\definefilesynonym [pstrick] [pstricks]
-
-\definefilesynonym [finance] [financ]
-
-\definefilesynonym [dir-make] [dir-01]
-\definefilesynonym [dir-identify] [dir-05]
-
-\definefilesynonym [int-load] [set-11]
-\definefilesynonym [int-make] [set-12]
-
- \definefilesynonym [fig-base] [fig-00]
- \definefilesynonym [fig-make] [fig-01]
- \definefilesynonym [fig-fake] [fig-02]
- \definefilesynonym [fig-missing] [fig-06]
-
-\definefilesynonym [exi-interface] [exi-21]
-
- \definefilesynonym [res-make] [res-01]
- \definefilesynonym [res-base] [res-04]
- \definefilesynonym [res-crop] [res-07]
- \definefilesynonym [res-trace] [res-08]
- \definefilesynonym [res-log] [res-09]
- \definefilesynonym [res-identify] [res-12]
-
- \definefilesynonym [med-show] [res-50]
-
-\definefilesynonym [pre-general] [pre-00]
-\definefilesynonym [pre-01] [present-original]
-\definefilesynonym [pre-original] [present-original]
-\definefilesynonym [pre-02] [present-green]
-\definefilesynonym [pre-green] [present-green]
-\definefilesynonym [pre-03] [present-funny]
-\definefilesynonym [pre-funny] [present-funny]
-\definefilesynonym [pre-04] [present-colorful]
-\definefilesynonym [pre-colorful] [present-colorful]
-\definefilesynonym [pre-05] [present-fuzzy]
-\definefilesynonym [pre-fuzzy] [present-fuzzy]
-\definefilesynonym [pre-polish] [pre-06]
-\definefilesynonym [pre-spider] [pre-07]
-\definefilesynonym [pre-wonder] [pre-08]
-\definefilesynonym [pre-09] [present-windows]
-\definefilesynonym [pre-windows] [present-windows]
-\definefilesynonym [pre-10] [present-grow]
-\definefilesynonym [pre-grow] [present-grow]
-\definefilesynonym [pre-11] [present-stack]
-\definefilesynonym [pre-stack] [present-stack]
-\definefilesynonym [pre-arrows] [pre-12]
-\definefilesynonym [pre-writing] [pre-13]
-\definefilesynonym [pre-split] [present-split]
-\definefilesynonym [pre-14] [present-split]
-\definefilesynonym [pre-balls] [present-balls]
-\definefilesynonym [pre-15] [present-balls]
-\definefilesynonym [pre-knot] [pre-16]
-\definefilesynonym [pre-17] [present-weird]
-\definefilesynonym [pre-weird] [present-weird]
-\definefilesynonym [pre-shade] [pre-18]
-\definefilesynonym [pre-organic] [pre-19]
-\definefilesynonym [pre-speckle] [pre-20]
-\definefilesynonym [pre-zoom] [pre-21]
-\definefilesynonym [pre-cycle] [pre-22]
-\definefilesynonym [pre-super] [pre-23]
-%definefilesynonym [pre-more] [pre-24]
-%definefilesynonym [pre-more] [pre-25]
-\definefilesynonym [pre-more] [pre-26]
-%definefilesynonym [pre-more] [pre-27]
-%definefilesynonym [pre-more] [pre-28]
-%definefilesynonym [pre-more] [pre-29]
-%definefilesynonym [pre-more] [pre-30]
-\definefilesynonym [pre-41] [present-tiles]
-\definefilesynonym [pre-60] [present-stepwise]
-\definefilesynonym [pre-stepwise] [present-stepwise]
-\definefilesynonym [pre-61] [present-stepper]
-\definefilesynonym [pre-stepper] [present-stepper]
-\definefilesynonym [pre-62] [present-overlap]
-\definefilesynonym [pre-69] [present-wobbling]
-\definefilesynonym [pre-punk] [present-punk]
-\definefilesynonym [pre-70] [present-punk]
-\definefilesynonym [pre-random] [present-random]
-\definefilesynonym [pre-71] [present-random]
-
-\definefilesynonym [abr-01] [abbreviations-pseudocaps]
-\definefilesynonym [abr-02] [abbreviations-smallcaps]
-\definefilesynonym [abr-03] [abbreviations-words]
-\definefilesynonym [abr-04] [abbreviations-mixed]
-
-\definefilesynonym [art-01] [article-basic]
-\definefilesynonym [article] [article-basic]
-\definefilesynonym [mag-01] [magazine-basic]
-\definefilesynonym [magazine] [magazine-basic]
-\definefilesynonym [mod-01] [module-basic]
-\definefilesynonym [module] [module-basic]
-
-\definefilesynonym [map-10] [maps] % for a while
-
-\definefilesynonym [mml] [mathml]
-\definefilesynonym [cml] [chemml]
-
-\definefilesynonym [letter] [cor-01]
-\definefilesynonym [memo] [cor-02]
-\definefilesynonym [resume] [cor-03]
-
-\definefilesynonym [fnt-10] [fonts-complete]
-\definefilesynonym [fnt-11] [fonts-system]
-\definefilesynonym [fnt-20] [fonts-steps]
-\definefilesynonym [fnt-21] [fonts-steps]
-\definefilesynonym [fnt-22] [fonts-engines]
-\definefilesynonym [fnt-23] [fonts-shapes]
-\definefilesynonym [fnt-24] [fonts-cjk]
-\definefilesynonym [fnt-25] [math-characters]
-\definefilesynonym [fnt-28] [fonts-goodies]
-\definefilesynonym [fnt-29] [fonts-shapes]
-\definefilesynonym [fnt-31] [fonts-coverage]
-\definefilesynonym [fnt-33] [math-coverage]
-
-\definefilesynonym [mat-10] [math-characters]
-\definefilesynonym [mat-11] [math-characters]
-\definefilesynonym [mat-12] [math-parameters]
-\definefilesynonym [mat-20] [math-parameters]
-
-\definefilesynonym [syn-01] [syntax]
-
-\definefilesynonym [reg-01] [regimes-list]
-
-\definefilesynonym [set-11] [setups-basics]
-\definefilesynonym [set-12] [setups-overview]
-%definefilesynonym [set-13] [setups-proofing]
-%definefilesynonym [set-15] [setups-generate]
+\definefilesynonym [chemics] [chemic]
+
+\definefilesynonym [unit] [units]
+
+\definefilesynonym [pstric] [pstricks]
+\definefilesynonym [pstrick] [pstricks]
+
+\definefilesynonym [finance] [financ]
+
+\definefilesynonym [dir-make] [dir-01]
+\definefilesynonym [dir-identify] [dir-05]
+
+\definefilesynonym [int-load] [set-11]
+\definefilesynonym [int-make] [set-12]
+
+ \definefilesynonym [fig-base] [fig-00]
+ \definefilesynonym [fig-make] [fig-01]
+ \definefilesynonym [fig-fake] [fig-02]
+ \definefilesynonym [fig-missing] [fig-06]
+
+ \definefilesynonym [exi-interface] [exi-21]
+
+ \definefilesynonym [res-make] [res-01]
+ \definefilesynonym [res-base] [res-04]
+ \definefilesynonym [res-crop] [res-07]
+ \definefilesynonym [res-trace] [res-08]
+ \definefilesynonym [res-log] [res-09]
+ \definefilesynonym [res-identify] [res-12]
+
+ \definefilesynonym [med-show] [res-50]
+
+\definefilesynonym [pre-general] [pre-00]
+\definefilesynonym [pre-01] [present-original]
+\definefilesynonym [pre-original] [present-original]
+\definefilesynonym [pre-02] [present-green]
+\definefilesynonym [pre-green] [present-green]
+\definefilesynonym [pre-03] [present-funny]
+\definefilesynonym [pre-funny] [present-funny]
+\definefilesynonym [pre-04] [present-colorful]
+\definefilesynonym [pre-colorful] [present-colorful]
+\definefilesynonym [pre-05] [present-fuzzy]
+\definefilesynonym [pre-fuzzy] [present-fuzzy]
+\definefilesynonym [pre-polish] [pre-06]
+\definefilesynonym [pre-spider] [pre-07]
+\definefilesynonym [pre-wonder] [pre-08]
+\definefilesynonym [pre-09] [present-windows]
+\definefilesynonym [pre-windows] [present-windows]
+\definefilesynonym [pre-10] [present-grow]
+\definefilesynonym [pre-grow] [present-grow]
+\definefilesynonym [pre-11] [present-stack]
+\definefilesynonym [pre-stack] [present-stack]
+\definefilesynonym [pre-arrows] [pre-12]
+\definefilesynonym [pre-writing] [pre-13]
+\definefilesynonym [pre-split] [present-split]
+\definefilesynonym [pre-14] [present-split]
+\definefilesynonym [pre-balls] [present-balls]
+\definefilesynonym [pre-15] [present-balls]
+\definefilesynonym [pre-knot] [pre-16]
+\definefilesynonym [pre-17] [present-weird]
+\definefilesynonym [pre-weird] [present-weird]
+\definefilesynonym [pre-shade] [pre-18]
+\definefilesynonym [pre-organic] [pre-19]
+\definefilesynonym [pre-speckle] [pre-20]
+\definefilesynonym [pre-zoom] [pre-21]
+\definefilesynonym [pre-cycle] [pre-22]
+\definefilesynonym [pre-super] [pre-23]
+%definefilesynonym [pre-more] [pre-24]
+%definefilesynonym [pre-more] [pre-25]
+\definefilesynonym [pre-more] [pre-26]
+%definefilesynonym [pre-more] [pre-27]
+%definefilesynonym [pre-more] [pre-28]
+%definefilesynonym [pre-more] [pre-29]
+%definefilesynonym [pre-more] [pre-30]
+\definefilesynonym [pre-41] [present-tiles]
+\definefilesynonym [pre-60] [present-stepwise]
+\definefilesynonym [pre-stepwise] [present-stepwise]
+\definefilesynonym [pre-61] [present-stepper]
+\definefilesynonym [pre-stepper] [present-stepper]
+\definefilesynonym [pre-62] [present-overlap]
+\definefilesynonym [pre-69] [present-wobbling]
+\definefilesynonym [pre-punk] [present-punk]
+\definefilesynonym [pre-70] [present-punk]
+\definefilesynonym [pre-random] [present-random]
+\definefilesynonym [pre-71] [present-random]
+
+\definefilesynonym [abr-01] [abbreviations-pseudocaps]
+\definefilesynonym [abr-02] [abbreviations-smallcaps]
+\definefilesynonym [abr-03] [abbreviations-words]
+\definefilesynonym [abr-04] [abbreviations-mixed]
+
+\definefilesynonym [art-01] [article-basic]
+\definefilesynonym [article] [article-basic]
+\definefilesynonym [mag-01] [magazine-basic]
+\definefilesynonym [magazine] [magazine-basic]
+\definefilesynonym [mod-01] [module-basic]
+\definefilesynonym [module] [module-basic]
+
+\definefilesynonym [map-10] [maps] % for a while
+
+\definefilesynonym [mml] [mathml]
+\definefilesynonym [cml] [chemml]
+
+\definefilesynonym [letter] [cor-01]
+\definefilesynonym [memo] [cor-02]
+\definefilesynonym [resume] [cor-03]
+
+\definefilesynonym [fnt-10] [fonts-complete]
+\definefilesynonym [fnt-11] [fonts-system]
+\definefilesynonym [fnt-20] [fonts-steps]
+\definefilesynonym [fnt-21] [fonts-steps]
+\definefilesynonym [fnt-22] [fonts-engines]
+\definefilesynonym [fnt-23] [fonts-shapes]
+\definefilesynonym [fnt-24] [fonts-cjk]
+\definefilesynonym [fnt-25] [math-characters]
+\definefilesynonym [fnt-28] [fonts-goodies]
+\definefilesynonym [fnt-29] [fonts-shapes]
+\definefilesynonym [fnt-31] [fonts-coverage]
+\definefilesynonym [fnt-33] [math-coverage]
+
+\definefilesynonym [mat-10] [math-characters]
+\definefilesynonym [mat-11] [math-characters]
+\definefilesynonym [mat-12] [math-parameters]
+\definefilesynonym [mat-20] [math-parameters]
+
+\definefilesynonym [syn-01] [syntax]
+
+\definefilesynonym [reg-01] [regimes-list]
+
+\definefilesynonym [set-11] [setups-basics]
+\definefilesynonym [set-12] [setups-overview]
+%definefilesynonym [set-13] [setups-proofing]
+%definefilesynonym [set-15] [setups-generate]
+
+\ifcase\contextlmtxmode \else
+ \definefilesynonym [ecmascript] [libs-imp-mujs]
+ \definefilesynonym [zint] [libs-imp-zint]
+\fi
\endinput
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 2cc2a1098..cd700391a 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2020.01.26 18:34}
+\newcontextversion{2020.02.11 16:36}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index d4206a4e8..30389e598 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.01.26 18:34}
+\edef\contextversion{2020.02.11 16:36}
\edef\contextkind {beta}
%D Kind of special:
diff --git a/tex/context/base/mkiv/context.mkxl b/tex/context/base/mkiv/context.mkxl
index 1b4da4e96..ef3fddc3d 100644
--- a/tex/context/base/mkiv/context.mkxl
+++ b/tex/context/base/mkiv/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2020.01.26 18:34}
+\edef\contextversion{2020.02.11 16:36}
\edef\contextkind {beta}
%D Kind of special:
diff --git a/tex/context/base/mkiv/data-tmp.lua b/tex/context/base/mkiv/data-tmp.lua
index bfced1e64..9b0117c15 100644
--- a/tex/context/base/mkiv/data-tmp.lua
+++ b/tex/context/base/mkiv/data-tmp.lua
@@ -364,7 +364,7 @@ function caches.is_writable(filepath,filename)
return is_writable(tmaname)
end
-local saveoptions = { compact = true }
+local saveoptions = { compact = true, accurate = not JITSUPPORTED }
function caches.savedata(filepath,filename,data,fast)
local tmaname, tmcname = setluanames(filepath,filename)
diff --git a/tex/context/base/mkiv/driv-shp.lua b/tex/context/base/mkiv/driv-shp.lua
index cc8b6bdbe..a4e36105d 100644
--- a/tex/context/base/mkiv/driv-shp.lua
+++ b/tex/context/base/mkiv/driv-shp.lua
@@ -381,6 +381,7 @@ flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r
factor = 0
end
end
+
if pos_r == righttoleft_code then
pos_h = pos_h - width
end
@@ -390,6 +391,7 @@ flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r
if vfcommands then
flush_vf_packet(pos_h,pos_v,pos_r,font,char,data,factor,vfcommands) -- also f ?
else
+ -- kind of messy that we do orientation here and offsets elsewhere
local orientation = data.orientation
if orientation and (orientation == 1 or orientation == 3) then
local x = data.xoffset
@@ -401,10 +403,10 @@ flush_character = function(current,font,char,factor,vfcommands,pos_h,pos_v,pos_r
pos_v = pos_v + y
end
pushorientation(orientation,pos_h,pos_v)
- flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,naturalwidth,factor,width,f,e)
+ flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor) -- ,naturalwidth,width)
poporientation(orientation,pos_h,pos_v)
else
- flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,naturalwidth,factor,width,f,e)
+ flushcharacter(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor) -- ,naturalwidth,width)
end
end
return width, height, depth
diff --git a/tex/context/base/mkiv/file-job.lua b/tex/context/base/mkiv/file-job.lua
index 4b29f57ec..407c3c15d 100644
--- a/tex/context/base/mkiv/file-job.lua
+++ b/tex/context/base/mkiv/file-job.lua
@@ -326,6 +326,8 @@ end
local suffixes = {
mkvi = usetexfile,
mkiv = usetexfile,
+ mklx = usetexfile,
+ mkxl = usetexfile,
tex = usetexfile,
luc = useluafile,
lua = useluafile,
diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua
index e42d20d4e..1bb63aa51 100644
--- a/tex/context/base/mkiv/font-con.lua
+++ b/tex/context/base/mkiv/font-con.lua
@@ -1139,6 +1139,7 @@ hashmethods.normal = function(list)
m = m + 1
t[m] = k .. '=' .. tostring(v)
end
+ sort(t)
s[n] = k .. '={' .. concat(t,",") .. "}"
else
s[n] = k .. '=' .. tostring(v)
diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua
index cbb81cdb7..bf14dd309 100644
--- a/tex/context/base/mkiv/font-ctx.lua
+++ b/tex/context/base/mkiv/font-ctx.lua
@@ -887,23 +887,6 @@ specifiers.definecontext = definecontext
-- we extend the hasher:
--- constructors.hashmethods.virtual = function(list)
--- local s = { }
--- local n = 0
--- for k, v in next, list do
--- n = n + 1
--- s[n] = k -- no checking on k
--- end
--- if n > 0 then
--- sort(s)
--- for i=1,n do
--- local k = s[i]
--- s[i] = k .. '=' .. tostring(list[k])
--- end
--- return concat(s,"+")
--- end
--- end
-
constructors.hashmethods.virtual = function(list)
local s = { }
local n = 0
@@ -924,6 +907,54 @@ constructors.hashmethods.virtual = function(list)
end
end
+if not JITSUPPORTED then
+
+ constructors.hashmethods.normal = function(list)
+ local s = { }
+ local n = 0
+ for k, v in next, list do
+ if not k then
+ -- no need to add to hash
+ elseif k == "number" or k == "features" then
+ -- no need to add to hash (maybe we need a skip list)
+ else
+ n = n + 1
+ if type(v) == "table" then
+ -- table.sequenced
+ local t = { }
+ local m = 0
+ for k, v in next, v do
+ m = m + 1
+ t[m] = format("%q=%q",k,v)
+ end
+ sort(t)
+ s[n] = format("%q={%s}",k,concat(t,","))
+ else
+ s[n] = format("%q=%q",k,v)
+ end
+ end
+ end
+ if n > 0 then
+ sort(s)
+ return concat(s,"+")
+ end
+ end
+
+ constructors.hashmethods.virtual = function(list)
+ local s = { }
+ local n = 0
+ for k, v in next, list do
+ n = n + 1
+ s[n] = format("%q=%q",k,v)
+ end
+ if n > 0 then
+ sort(s)
+ return concat(s,"+")
+ end
+ end
+
+end
+
-- end of redefine
-- local withcache = { } -- concat might be less efficient than nested tables
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index 7777f9c6a..3058be37b 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -3237,7 +3237,8 @@ function readers.sbix(f,fontdata,specification)
return b.ppem < a.ppem
end
end)
- local glyphs = { }
+ local glyphs = { }
+ local delayed = CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 or fonts.handlers.typethree
for i=1,nofstrikes do
local strike = strikes[i]
local strikeppem = strike.ppem
@@ -3254,13 +3255,28 @@ function readers.sbix(f,fontdata,specification)
local datasize = nextoffset - glyphoffset
if datasize > 0 then
setposition(f,strikeoffset + glyphoffset)
+ local x = readshort(f)
+ local y = readshort(f)
+ local tag = readtag(f) -- or just skip, we never needed it till now
+ local size = datasize - 8
+ local data = nil
+ local offset = nil
+ if delayed then
+ offset = getposition(f)
+ data = nil
+ else
+ data = readstring(f,size)
+ size = nil
+ end
shapes[i] = {
- x = readshort(f),
- y = readshort(f),
- tag = readtag(f), -- maybe for tracing
- data = readstring(f,datasize-8),
- ppem = strikeppem, -- not used, for tracing
- ppi = strikeppi, -- not used, for tracing
+ x = x,
+ y = y,
+ o = offset,
+ s = size,
+ data = data,
+ -- tag = tag, -- maybe for tracing
+ -- ppem = strikeppem, -- not used, for tracing
+ -- ppi = strikeppi, -- not used, for tracing
}
done = done + 1
if done == nofglyphs then
@@ -3462,32 +3478,48 @@ do
local default = { width = 0, height = 0 }
local glyphs = fontdata.glyphs
+ local delayed = CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 or fonts.handlers.typethree
for index, subtable in sortedhash(shapes) do
if type(subtable) == "table" then
local data = nil
+ local size = nil
local metrics = default
local format = subtable.format
local offset = subtable.offsets[index]
setposition(f,offset)
if format == 17 then
metrics = getsmallmetrics(f)
- data = readstring(f,readulong(f))
+ size = true
elseif format == 18 then
metrics = getbigmetrics(f)
- data = readstring(f,readulong(f))
+ size = true
elseif format == 19 then
metrics = subtable.metrics
- data = readstring(f,readulong(f))
+ size = true
else
-- forget about it
end
+ if size then
+ size = readulong(f)
+ if delayed then
+ offset = getposition(f)
+ data = nil
+ else
+ offset = nil
+ data = readstring(f,size)
+ size = nil
+ end
+ else
+ offset = nil
+ end
local x = metrics.width
local y = metrics.height
shapes[index] = {
- -- maybe some metrics
x = x,
y = y,
+ o = offset,
+ s = size,
data = data,
}
-- I'll look into this in more details when needed
@@ -3498,12 +3530,11 @@ do
local height = width * y/x
glyph.boundingbox = { 0, 0, width, height }
end
-
else
shapes[index] = {
x = 0,
y = 0,
- data = "",
+ data = "", -- or just nil
}
end
end
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index da02ab608..fe972114f 100644
--- a/tex/context/base/mkiv/font-mis.lua
+++ b/tex/context/base/mkiv/font-mis.lua
@@ -21,7 +21,7 @@ local readers = otf.readers
if readers then
- otf.version = otf.version or 3.110
+ otf.version = otf.version or 3.111
otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true)
function fonts.helpers.getfeatures(name,save)
diff --git a/tex/context/base/mkiv/font-ocl.lua b/tex/context/base/mkiv/font-ocl.lua
index 77e1538f9..eef221e46 100644
--- a/tex/context/base/mkiv/font-ocl.lua
+++ b/tex/context/base/mkiv/font-ocl.lua
@@ -401,7 +401,7 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg
-- The down and right will change too (we can move that elsewhere). We have
-- a different treatment in lmtx but the next kind of works. These images are
-- a mess anyway as in svg the bbox can be messed up absent). A png image
- -- needs the x/y. I might normalize this once we moev to lmtx exlusively.
+ -- needs the x/y. I might normalize this once we move to lmtx exlusively.
character.commands = {
not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) },
-- lmtx (when we deal with depth in vfimage, currently disabled):
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index 5d3bd4230..aff4cc8c8 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.110 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.111 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.pngcache = containers.define("fonts", "png", otf.version, true)
@@ -534,6 +534,9 @@ local converters = {
}
}
+-- We can get differences between daylight saving etc ... but it makes no sense to
+-- mess with trickery .. so be it when you use a different binary.
+
local function checkconversion(specification)
local filename = specification.filename
local converter = converters[lower(file.suffix(filename))]
diff --git a/tex/context/base/mkiv/l-os.lua b/tex/context/base/mkiv/l-os.lua
index 8394d19e7..64c7de567 100644
--- a/tex/context/base/mkiv/l-os.lua
+++ b/tex/context/base/mkiv/l-os.lua
@@ -637,6 +637,14 @@ function os.validdate(year,month,day)
return year, month, day
end
+function os.date(fmt,...)
+ if not fmt then
+ -- otherwise differences between unix, mingw and msvc
+ fmt = "%Y-%m-%d %H:%M"
+ end
+ return date(fmt,...)
+end
+
local osexit = os.exit
local exitcode = nil
diff --git a/tex/context/base/mkiv/l-table.lua b/tex/context/base/mkiv/l-table.lua
index 98b377bdc..c20bd4733 100644
--- a/tex/context/base/mkiv/l-table.lua
+++ b/tex/context/base/mkiv/l-table.lua
@@ -525,84 +525,15 @@ function table.fromhash(t)
return hsh
end
-local noquotes, hexify, handle, compact, inline, functions, metacheck
+local noquotes, hexify, handle, compact, inline, functions, metacheck, accurate
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if',
'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
- 'NaN', 'goto',
+ 'NaN', 'goto', 'const',
}
--- local function is_simple_table(t)
--- if #t > 0 then
--- local n = 0
--- for _,v in next, t do
--- n = n + 1
--- end
--- if n == #t then
--- local tt, nt = { }, 0
--- for i=1,#t do
--- local v = t[i]
--- local tv = type(v)
--- if tv == "number" then
--- nt = nt + 1
--- if hexify then
--- tt[nt] = format("0x%X",v)
--- else
--- tt[nt] = tostring(v) -- tostring not needed
--- end
--- elseif tv == "string" then
--- nt = nt + 1
--- tt[nt] = format("%q",v)
--- elseif tv == "boolean" then
--- nt = nt + 1
--- tt[nt] = v and "true" or "false"
--- else
--- return nil
--- end
--- end
--- return tt
--- end
--- end
--- return nil
--- end
-
--- local function is_simple_table(t)
--- local nt = #t
--- if nt > 0 then
--- local n = 0
--- for _,v in next, t do
--- n = n + 1
--- -- if type(v) == "table" then
--- -- return nil
--- -- end
--- end
--- if n == nt then
--- local tt = { }
--- for i=1,nt do
--- local v = t[i]
--- local tv = type(v)
--- if tv == "number" then
--- if hexify then
--- tt[i] = format("0x%X",v)
--- else
--- tt[i] = tostring(v) -- tostring not needed
--- end
--- elseif tv == "string" then
--- tt[i] = format("%q",v)
--- elseif tv == "boolean" then
--- tt[i] = v and "true" or "false"
--- else
--- return nil
--- end
--- end
--- return tt
--- end
--- end
--- return nil
--- end
-
-local function is_simple_table(t,hexify) -- also used in util-tab so maybe public
+local function is_simple_table(t,hexify,accurate) -- also used in util-tab so maybe public
local nt = #t
if nt > 0 then
local n = 0
@@ -623,6 +554,8 @@ local function is_simple_table(t,hexify) -- also used in util-tab so maybe publi
-- tt[i] = v -- not needed tostring(v)
if hexify then
tt[i] = format("0x%X",v)
+ elseif accurate then
+ tt[i] = format("%q",v)
else
tt[i] = v -- not needed tostring(v)
end
@@ -644,6 +577,8 @@ local function is_simple_table(t,hexify) -- also used in util-tab so maybe publi
-- tt[i+1] = v -- not needed tostring(v)
if hexify then
tt[i+1] = format("0x%X",v)
+ elseif accurate then
+ tt[i+1] = format("%q",v)
else
tt[i+1] = v -- not needed tostring(v)
end
@@ -738,6 +673,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv == "number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v)) -- %.99g
end
@@ -747,7 +684,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v) == nil then
handle(format("%s {},",depth))
elseif inline then -- and #t > 0
- local st = is_simple_table(v,hexify)
+ local st = is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -775,12 +712,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif tk == "boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
else
handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) -- %.99g
end
@@ -789,12 +730,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
@@ -803,6 +748,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -820,6 +767,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -833,11 +782,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st = is_simple_table(v,hexify)
+ local st = is_simple_table(v,hexify,accurate)
if st then
if tk == "number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -860,6 +811,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -881,6 +834,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -899,6 +854,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -927,6 +884,7 @@ local function serialize(_handle,root,name,specification) -- handle wins
if type(specification) == "table" then
noquotes = specification.noquotes
hexify = specification.hexify
+ accurate = specification.accurate
handle = _handle or specification.handle or print
functions = specification.functions
compact = specification.compact
diff --git a/tex/context/base/mkiv/libs-imp-mujs.lua b/tex/context/base/mkiv/libs-imp-mujs.lua
new file mode 100644
index 000000000..264c8e531
--- /dev/null
+++ b/tex/context/base/mkiv/libs-imp-mujs.lua
@@ -0,0 +1,126 @@
+if not modules then modules = { } end modules ['libs-imp-mujs'] = {
+ version = 1.001,
+ comment = "companion to luat-imp-mujs.mkxl",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- This is an experiment. When a new user knows \JAVASCRIPT\ it can be a
+-- stepping stone to using \LUA.
+
+-- local ecmascript = optional.mujs.initialize("libmujs")
+-- local execute = optional.mujs.execute
+
+local libname = "mujs"
+local libfile = "libmujs"
+
+if package.loaded[libname] then
+ return package.loaded[libname]
+end
+
+local mujslib = resolvers.libraries.validoptional(libname)
+
+if not mujslib then
+ return
+end
+
+local files = { }
+local openfile = io.open
+local findfile = resolvers.findfile
+
+local mujs_execute = mujslib.execute
+local mujs_dofile = mujslib.dofile
+local mujs_reset = mujslib.reset
+
+local function okay()
+ if resolvers.libraries.optionalloaded(libname,libfile) then
+ mujs_execute(
+ "var catcodes = { " ..
+ "'tex': " .. tex.texcatcodes .. "," ..
+ "'ctx': " .. tex.ctxcatcodes .. "," ..
+ "'prt': " .. tex.prtcatcodes .. "," ..
+ "'vrb': " .. tex.vrbcatcodes .. "," ..
+ "};"
+ )
+ okay = function() return true end
+ else
+ okay = function() return false end
+ end
+ return okay()
+end
+
+mujslib.setfindfile(findfile)
+
+mujslib.setopenfile(function(name)
+ local full = findfile(name)
+ if full then
+ local f = openfile(full,"rb")
+ if f then
+ for i=1,100 do
+ if not files[i] then
+ files[i] = f
+ return i
+ end
+ end
+ end
+ end
+end)
+
+mujslib.setclosefile(function(id)
+ local f = files[id]
+ if f then
+ f:close()
+ files[id] = false
+ end
+end)
+
+mujslib.setreadfile(function(id,how)
+ local f = files[id]
+ if f then
+ return (f:read(how or "*l"))
+ end
+end)
+
+mujslib.setseekfile(function(id,whence,offset)
+ local f = files[id]
+ if f then
+ return (f:seek(whence,offset))
+ end
+end)
+
+local reporters = {
+ console = logs.reporter("mujs","console"),
+ report = logs.reporter("mujs","report"),
+}
+
+mujslib.setconsole(function(category,name)
+ reporters[category](name)
+end)
+
+local mujs = {
+ ["execute"] = function(c,s) if okay() then mujs_execute(c,s) end end,
+ ["dofile"] = function(n) if okay() then mujs_dofile(n) end end,
+ ["reset"] = function(n) if okay() then mujs_reset(n) end end,
+}
+
+package.loaded[libname] = mujs
+
+optional.loaded.mujs = mujs
+
+interfaces.implement {
+ name = "ecmacode",
+ actions = mujs.execute,
+ arguments = "string",
+ public = true,
+}
+
+interfaces.implement {
+ name = "ecmafile",
+ actions = mujs.dofile,
+ arguments = "string",
+ public = true,
+ protected = true,
+}
+
+return mujs
diff --git a/tex/context/base/mkiv/libs-imp-mujs.mkxl b/tex/context/base/mkiv/libs-imp-mujs.mkxl
new file mode 100644
index 000000000..0f278dff5
--- /dev/null
+++ b/tex/context/base/mkiv/libs-imp-mujs.mkxl
@@ -0,0 +1,121 @@
+%D \module
+%D [ file=libs-imp-mujs,
+%D version=2020.02.08,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=MuJS interpreter,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D Just an experiment:
+%D
+%D \starttyping
+%D http://mujs.com
+%D \stoptyping
+
+\ifdefined\ecmacode
+ \expandafter \endinput
+\fi
+
+\registerctxluafile{libs-imp-mujs}{}
+
+\unprotect
+
+% todo: environment
+
+\let\stopecmacode\relax
+
+\normalprotected\def\startecmacode % \stopecmacode
+ {\begingroup
+ \obeylualines
+ \obeyluatokens
+ \luat_start_ecma_code_indeed}
+
+\def\luat_start_ecma_code_indeed#1\stopecmacode
+ {\normalexpanded{\endgroup\noexpand\ecmacode{#1}}}
+
+\protect
+
+\continueifinputfile{libs-imp-mujs.mkxl}
+
+\usemodule[article-basic,abbreviations-logos]
+
+\starttext
+
+\startbuffer
+\startluacode
+ local mujs = require("libs-imp-mujs")
+
+ mujs.execute [[
+ var MyMax = 1000;
+ ]]
+
+ mujs.execute [[
+ console("Example One!");
+ texsprint("\\startpacked");
+ for (var i = 1; i <= MyMax; i = i + 1) {
+ texprint(
+ "This is a buildbot compilation challenge for Mojca: "
+ .concat(Math.sqrt(i/MyMax))
+ .concat("!\\par")
+ );
+ }
+ texsprint("\\stoppacked");
+ ]]
+
+ -- mujs.execute [[
+ -- something very bad: an error
+ -- ]]
+\stopluacode
+
+\startecmacode
+ console("Example Two!");
+ for (var i = 1; i <= MyMax; i = i + 1) {
+ texsprint(
+ "And an opportunity for Alan to attract highschool students to \\TeX: "
+ .concat(i)
+ .concat("! ")
+ );
+ }
+\stopecmacode
+
+\ecmacode {
+ console("Example Three!");
+ texprint("And otherwise a way to prototype \\JAVASCRIPT\\ code in \\PDF.")
+}
+
+\startecmacode
+ var f = File("libs-imp-mujs.mkxl","r");
+ console(f);
+ // var l = f.read(400);
+ var l = f.read("*a");
+ console(l);
+ f.close();
+\stopecmacode
+
+\startecmacode
+ console("Example Four!");
+ texsprint("\\startMPcode "
+ .concat(' fill fullcircle scaled 6cm withcolor "darkred";')
+ .concat(' fill fullcircle scaled 4cm withcolor "darkgreen";')
+ .concat(' fill fullcircle scaled 2cm withcolor "darkblue";')
+ .concat("\\stopMPcode ")
+ );
+\stopecmacode
+
+\startluacode
+ context.startMPcode()
+ context('fill fullcircle scaled 6cm withcolor "middlecyan";')
+ context('fill fullcircle scaled 4cm withcolor "middlemagenta";')
+ context('fill fullcircle scaled 2cm withcolor "middleyellow";')
+ context.stopMPcode()
+\stopluacode
+\stopbuffer
+
+\typebuffer \page \getbuffer
+
+\stoptext
diff --git a/tex/context/base/mkiv/libs-imp-mysql.lua b/tex/context/base/mkiv/libs-imp-mysql.lua
index b3896acd4..3e938a6de 100644
--- a/tex/context/base/mkiv/libs-imp-mysql.lua
+++ b/tex/context/base/mkiv/libs-imp-mysql.lua
@@ -44,15 +44,20 @@ local validspecification = helpers.validspecification
local preparetemplate = helpers.preparetemplate
local querysplitter = helpers.querysplitter
local cache = { }
+local timeout -- = 3600 -- to be tested
local function connect(specification)
- return mysql_open(
+ local db = mysql_open(
specification.database or "",
specification.username or "",
specification.password or "",
specification.host or "",
specification.port
)
+ if db and timeout then
+ mysql_execute(db,formatters["SET SESSION connect_timeout=%s ;"](timeout))
+ end
+ return db
end
local function execute_once(specification,retry)
@@ -110,13 +115,13 @@ local function execute_once(specification,retry)
result[nofrows] = convert(values)
end
else
- local column = { }
callback = function(nofcolumns,values,fields)
+ local column = { }
for i=1,nofcolumns do
local field
if fields then
field = fields[i]
- keys[i+1] = field
+ keys[i] = field
else
field = keys[i]
end
@@ -131,7 +136,7 @@ local function execute_once(specification,retry)
for i=1,#query do
local okay = mysql_execute(db,query[i],callback)
if not okay then
- if id and option == "retry" and i == 1 then
+ if id and retry and i == 1 then
report("error: %s, retrying to connect",mysql_getmessage(db))
mysql_close(db)
cache[id] = nil
@@ -183,6 +188,23 @@ return function(cells)
end
]]
+-- return function(result)
+-- if not result then
+-- return { }
+-- end
+-- local nofrows = #result
+-- if nofrows == 0 then
+-- return { }
+-- end
+-- local target = { } -- no %s needed here
+-- for i=1,nofrows do
+-- target[%s] = {
+-- %s
+-- }
+-- end
+-- return result
+-- end
+
local celltemplate = "cells[%s]"
methods.mysql = {
@@ -192,5 +214,7 @@ methods.mysql = {
celltemplate = celltemplate,
}
-package.loaded["util-sql-imp-mysql"] = methods.mysql
-package.loaded[libname] = methods.mysql
+package.loaded["util-sql-imp-ffi"] = methods.mysql
+package.loaded["util-sql-imp-mysql"] = methods.mysql
+package.loaded["util-sql-imp-library"] = methods.mysql
+package.loaded[libname] = methods.mysql
diff --git a/tex/context/base/mkiv/libs-imp-postgress.lua b/tex/context/base/mkiv/libs-imp-postgress.lua
index 5cd04e03b..629079b01 100644
--- a/tex/context/base/mkiv/libs-imp-postgress.lua
+++ b/tex/context/base/mkiv/libs-imp-postgress.lua
@@ -114,13 +114,13 @@ local function execute_once(specification,retry)
result[nofrows] = convert(values)
end
else
- local column = { }
callback = function(nofcolumns,values,fields)
+ local column = { }
for i=1,nofcolumns do
local field
if fields then
field = fields[i]
- keys[i+1] = field
+ keys[i] = field
else
field = keys[i]
end
@@ -135,7 +135,7 @@ local function execute_once(specification,retry)
for i=1,#query do
local okay = postgress_execute(db,query[i],callback)
if not okay then
- if id and option == "retry" and i == 1 then
+ if id and retry and i == 1 then
report("error: %s, retrying to connect",postgress_getmessage(db))
postgress_close(db)
cache[id] = nil
diff --git a/tex/context/base/mkiv/libs-imp-sqlite.lua b/tex/context/base/mkiv/libs-imp-sqlite.lua
index 15c3222ea..5d38986f3 100644
--- a/tex/context/base/mkiv/libs-imp-sqlite.lua
+++ b/tex/context/base/mkiv/libs-imp-sqlite.lua
@@ -119,13 +119,13 @@ local function execute(specification)
result[nofrows] = convert(values)
end
else
- local column = { }
callback = function(nofcolumns,values,fields)
+ local column = { }
for i=1,nofcolumns do
local field
if fields then
field = fields[i]
- keys[i+1] = field
+ keys[i] = field
else
field = keys[i]
end
diff --git a/tex/context/base/mkiv/libs-imp-zint.lua b/tex/context/base/mkiv/libs-imp-zint.lua
index eef2cd605..2c346ae7d 100644
--- a/tex/context/base/mkiv/libs-imp-zint.lua
+++ b/tex/context/base/mkiv/libs-imp-zint.lua
@@ -78,7 +78,7 @@ local shown = false
----- f_rectangle = string.formatters["%sofill unitsquare xysized (%N,%N) shifted (%N,%N);"]
-function zint.execute(specification)
+local function execute(specification)
if okay() then
local code = specification.code
local text = specification.text
@@ -146,3 +146,16 @@ function zint.execute(specification)
end
end
end
+
+optional.loaded.zint = { execute = execute }
+
+interfaces.implement {
+ name = "zint",
+ actions = execute,
+ arguments = {
+ {
+ { "code" },
+ { "text" },
+ }
+ }
+}
diff --git a/tex/context/base/mkiv/libs-imp-zint.mkxl b/tex/context/base/mkiv/libs-imp-zint.mkxl
index d7436a4a4..72ce8157e 100644
--- a/tex/context/base/mkiv/libs-imp-zint.mkxl
+++ b/tex/context/base/mkiv/libs-imp-zint.mkxl
@@ -35,7 +35,10 @@
[\c!alternative=,\c!text=,#1]%
\scale
[#1]%
- {\ctxlua{utilities.zint.execute{code="\dummyparameter\c!alternative",text=\!!bs\dummyparameter\c!text\!!es}}}%
+ {\clf_zint
+ code {\dummyparameter\c!alternative}
+ text {\dummyparameter\c!text}
+ \relax}
\egroup}
\protect
diff --git a/tex/context/base/mkiv/libs-ini.lua b/tex/context/base/mkiv/libs-ini.lua
index 2422305f0..2bac3201d 100644
--- a/tex/context/base/mkiv/libs-ini.lua
+++ b/tex/context/base/mkiv/libs-ini.lua
@@ -106,6 +106,8 @@ resolvers.libraries = libraries
local report = logs.reporter("optional")
+if optional then optional.loaded = { } end
+
function libraries.validoptional(name)
local thelib = optional and optional[name]
if not thelib then
@@ -152,6 +154,21 @@ function libraries.optionalloaded(name,libnames)
end
end
+if FFISUPPORTED and ffi and ffi.load then
+
+ local ffiload = ffi.load
+
+ function ffi.load(name)
+ local full = name and foundlibraries[name]
+ if full then
+ return ffiload(full)
+ else
+ return ffiload(name)
+ end
+ end
+
+end
+
-- local patterns = {
-- "libs-imp-%s.mkxl",
-- "libs-imp-%s.mklx",
diff --git a/tex/context/base/mkiv/lpdf-emb.lua b/tex/context/base/mkiv/lpdf-emb.lua
index 8db2ecaf1..4ffcfd8a8 100644
--- a/tex/context/base/mkiv/lpdf-emb.lua
+++ b/tex/context/base/mkiv/lpdf-emb.lua
@@ -1721,6 +1721,12 @@ do
-- Acrobat X pro only seems to see the image mask but other viewers are doing it ok. Acrobat
-- reader crashes. We really need to add a notdef!
+ local files = utilities.files
+ local openfile = files.open
+ local closefile = files.close
+ local setposition = files.setposition
+ local readstring = files.readstring
+
function methods.png(filename,details)
local properties = details.properties
local pngshapes = properties.indexdata[1]
@@ -1732,23 +1738,37 @@ do
local nofglyphs = 0
local scale = 10 * parameters.size/parameters.designsize
local factor = bpfactor / scale
- local units = parameters.units / 1000
+ -- local units = parameters.units -- / 1000
+ local units = 1000
+ local filehandle = openfile(details.filename,true)
local function pngtopdf(glyph,data)
- -- local width = data.width
- local info = graphics.identifiers.png(glyph.data,"string")
- info.enforcecmyk = pngshapes.enforcecmyk
- local image = lpdf.injectors.png(info,"string")
- embedimage(image)
- nofglyphs = nofglyphs + 1
- local width = (data.width or 0) * factor
- local xoffset = (glyph.x or 0) / units
- local yoffset = (glyph.y or 0) / units
- local name = f_glyph(nofglyphs)
- xforms[name] = pdfreference(image.objnum)
- local pdf = f_image_xy(width,xoffset,yoffset,name)
- return pdf, width
+ -- local info = graphics.identifiers.png(glyph.data,"string")
+ local offset = glyph.o
+ local size = glyph.s
+ local pdfdata = nil
+ if offset and size then
+ setposition(filehandle,offset)
+ local blob = readstring(filehandle,size)
+ local info = graphics.identifiers.png(blob,"string")
+ info.enforcecmyk = pngshapes.enforcecmyk
+ local image = lpdf.injectors.png(info,"string")
+ local width = (data.width or 0) * factor
+ if image then
+ embedimage(image)
+ nofglyphs = nofglyphs + 1
+ local xoffset = (glyph.x or 0) / units
+ local yoffset = (glyph.y or 0) / units
+ local name = f_glyph(nofglyphs)
+ xforms[name] = pdfreference(image.objnum)
+ pdfdata = f_image_xy(width,xoffset,yoffset,name)
+ end
+ end
+ return pdfdata or f_stream(width), width
end
local function closepng()
+ if filehandle then
+ closefile(filehandle)
+ end
pngshapes = nil
end
local function getresources()
diff --git a/tex/context/base/mkiv/lpdf-lmt.lua b/tex/context/base/mkiv/lpdf-lmt.lua
index a14df3eca..0ad0c4e5e 100644
--- a/tex/context/base/mkiv/lpdf-lmt.lua
+++ b/tex/context/base/mkiv/lpdf-lmt.lua
@@ -74,6 +74,7 @@ local pdf_form = pdfconstant("Form")
local fonthashes = fonts.hashes
local characters = fonthashes.characters
+local descriptions = fonthashes.descriptions
local parameters = fonthashes.parameters
local properties = fonthashes.properties
@@ -146,6 +147,7 @@ end
-- fonts
local fontcharacters
+local fontdescriptions
local fontparameters
local fontproperties
local usedcharacters = setmetatableindex("table")
@@ -161,6 +163,7 @@ lpdf.usedcharacters = usedcharacters
local function updatefontstate(font)
fontcharacters = characters[font]
+ fontdescriptions = descriptions[font]
fontparameters = parameters[font]
fontproperties = properties[font]
local size = fontparameters.size -- or bad news
@@ -373,6 +376,32 @@ local flushcharacter do
-- as fontparameters already has checked / set it we can also have a variable
-- for it so
+ local naturalwidth = nil
+
+ local naturalwidths = setmetatableindex(function(t,font)
+ local d = descriptions[font]
+ local c = characters[font]
+ local f = parameters[font].hfactor
+ local v = setmetatableindex(function(t,char)
+ local e = d and d[char]
+ local w = 0
+ if e then
+ w = e.width
+ if w then
+ w = w * f
+ end
+ end
+ e = c[char]
+ if e then
+ w = e.width or 0
+ end
+ t[char] = w
+ return w
+ end)
+ t[font] = v
+ return v
+ end)
+
local function setup_fontparameters(font,factor,f,e)
local slant = fontparameters.slantfactor or 0
local extend = fontparameters.extendfactor or 1
@@ -401,6 +430,8 @@ local flushcharacter do
if format == "opentype" or format == "type1" then
fs = fs * 1000 / fontparameters.units -- can we avoid this ?
end
+ --
+ naturalwidth = naturalwidths[font]
end
-- This only saves a little on hz because there we switch a lot of
@@ -512,7 +543,7 @@ local flushcharacter do
local trace_threshold = false trackers.register("backends.pdf.threshold", function(v) trace_threshold = v end)
- flushcharacter = function(current,pos_h,pos_v,pos_r,font,char,data,naturalwidth,factor,width,f,e)
+ flushcharacter = function(current,pos_h,pos_v,pos_r,font,char,data,f,e,factor) -- ,naturalwidth,width)
if need_tf or font ~= f_cur or f_pdf ~= f_pdf_cur or fs ~= fs_cur or mode == "page" then
pdf_goto_textmode()
setup_fontparameters(font,factor,f,e)
@@ -523,12 +554,12 @@ local flushcharacter do
end
local move = calc_pdfpos(pos_h,pos_v)
- if trace_threshold then
- report(
- "font %i, char %C, factor %i, width %p, naturalwidth %p, move %l, tm %l, hpos %p, delta %p, threshold %p, cw %p",
- font,char,factor,width,naturalwidth,move,need_tm,pos_h,tj_delta,threshold,cw
- )
- end
+ -- if trace_threshold then
+ -- report(
+ -- "font %i, char %C, factor %i, naturalwidth %p, move %l, tm %l, hpos %p, delta %p, threshold %p, cw %p",
+ -- font,char,factor,naturalwidth[char],move,need_tm,pos_h,tj_delta,threshold,cw
+ -- )
+ -- end
if move or need_tm then
if not need_tm then
@@ -569,7 +600,8 @@ local flushcharacter do
end
-- cw = cw + naturalwidth
- cw = cw + width
+ -- cw = cw + width
+ cw = cw + naturalwidth[char]
local index = data.index or char
@@ -2407,67 +2439,69 @@ updaters.register("backend.update.pdf",function()
end
local function embedimage(specification)
- lastindex = lastindex + 1
- index = lastindex
- specification.index = index
- local xobject = pdfdictionary { }
- if not specification.notype then
- xobject.Type = pdf_xobject
- xobject.Subtype = pdf_form
- xobject.FormType = 1
- end
- local bbox = specification.bbox
- if bbox and not specification.nobbox then
- xobject.BBox = pdfarray {
- bbox[1] * bpfactor,
- bbox[2] * bpfactor,
- bbox[3] * bpfactor,
- bbox[4] * bpfactor,
- }
- end
- xobject = xobject + specification.attr
- if bbox and not specification.width then
- specification.width = bbox[3]
- end
- if bbox and not specification.height then
- specification.height = bbox[4]
- end
- local dict = xobject()
- --
- nofobjects = nofobjects + 1
- local objnum = nofobjects
- local nolength = specification.nolength
- local stream = specification.stream or specification.string
- --
- -- We cannot set type in native img so we need this hack or
- -- otherwise we need to patch too much. Better that i write
- -- a wrapper then. Anyway, it has to be done better: a key that
- -- tells either or not to scale by xsize/ysize when flushing.
- --
- if not specification.type then
- local kind = specification.kind
- if kind then
- -- take that one
- elseif attr and find(attr,"BBox") then
- kind = img_stream
- else
- -- hack: a bitmap
- kind = img_none
+ if specification then
+ lastindex = lastindex + 1
+ index = lastindex
+ specification.index = index
+ local xobject = pdfdictionary { }
+ if not specification.notype then
+ xobject.Type = pdf_xobject
+ xobject.Subtype = pdf_form
+ xobject.FormType = 1
end
- specification.type = kind
- specification.kind = kind
- end
- local compress = compresslevel and compresslevel > 0 or nil
- flushstreamobj(stream,objnum,dict,compress,nolength)
- specification.objnum = objnum
- specification.rotation = specification.rotation or 0
- specification.orientation = specification.orientation or 0
- specification.transform = specification.transform or 0
- specification.stream = nil
- specification.attr = nil
- specification.type = specification.kind or specification.type or img_none
- indices[index] = specification -- better create a real specification
- return specification
+ local bbox = specification.bbox
+ if bbox and not specification.nobbox then
+ xobject.BBox = pdfarray {
+ bbox[1] * bpfactor,
+ bbox[2] * bpfactor,
+ bbox[3] * bpfactor,
+ bbox[4] * bpfactor,
+ }
+ end
+ xobject = xobject + specification.attr
+ if bbox and not specification.width then
+ specification.width = bbox[3]
+ end
+ if bbox and not specification.height then
+ specification.height = bbox[4]
+ end
+ local dict = xobject()
+ --
+ nofobjects = nofobjects + 1
+ local objnum = nofobjects
+ local nolength = specification.nolength
+ local stream = specification.stream or specification.string
+ --
+ -- We cannot set type in native img so we need this hack or
+ -- otherwise we need to patch too much. Better that i write
+ -- a wrapper then. Anyway, it has to be done better: a key that
+ -- tells either or not to scale by xsize/ysize when flushing.
+ --
+ if not specification.type then
+ local kind = specification.kind
+ if kind then
+ -- take that one
+ elseif attr and find(attr,"BBox") then
+ kind = img_stream
+ else
+ -- hack: a bitmap
+ kind = img_none
+ end
+ specification.type = kind
+ specification.kind = kind
+ end
+ local compress = compresslevel and compresslevel > 0 or nil
+ flushstreamobj(stream,objnum,dict,compress,nolength)
+ specification.objnum = objnum
+ specification.rotation = specification.rotation or 0
+ specification.orientation = specification.orientation or 0
+ specification.transform = specification.transform or 0
+ specification.stream = nil
+ specification.attr = nil
+ specification.type = specification.kind or specification.type or img_none
+ indices[index] = specification -- better create a real specification
+ return specification
+ end
end
codeinjections.embedimage = embedimage
diff --git a/tex/context/base/mkiv/lpdf-wid.lua b/tex/context/base/mkiv/lpdf-wid.lua
index b8648b32a..8e0a45a00 100644
--- a/tex/context/base/mkiv/lpdf-wid.lua
+++ b/tex/context/base/mkiv/lpdf-wid.lua
@@ -252,20 +252,25 @@ job.register('job.fileobjreferences.collected', tobesavedobjrefs, initializer)
local function flushembeddedfiles()
if enabled and next(filestreams) then
local e = pdfarray()
+ local f = pdfarray()
for tag, reference in sortedhash(filestreams) do
if not reference then
report_attachment("unreferenced file, tag %a",tag)
--- elseif referenced[tag] == "hidden" then
- elseif referenced[tag] ~= "hidden" then
+ elseif referenced[tag] == "hidden" then
e[#e+1] = pdfstring(tag)
e[#e+1] = reference -- already a reference
+ f[#f+1] = reference -- collect all file description references
else
- -- -- messy spec ... when annot not in named else twice in menu list acrobat
+ -- messy spec ... when annot not in named else twice in menu list acrobat
+ f[#f+1] = reference
end
end
if #e > 0 then
lpdf.addtonames("EmbeddedFiles",pdfreference(pdfflushobject(pdfdictionary{ Names = e })))
end
+ if #f > 0 then -- PDF/A-2|3: all associated files must have a relationship to the PDF document (global or part)
+ lpdf.addtocatalog("AF", pdfreference(pdfflushobject(f))) -- global (Catalog)
+ end
end
end
@@ -430,6 +435,7 @@ function nodeinjections.attachfile(specification)
else
referenced[hash] = "annotation"
local name, appearance = analyzesymbol(specification.symbol,attachment_symbols)
+ local flags = specification.flags or 0 -- to keep it expandable
local d = pdfdictionary {
Subtype = pdfconstant("FileAttachment"),
FS = aref,
@@ -442,7 +448,8 @@ function nodeinjections.attachfile(specification)
CA = analyzetransparency(specification.transparencyvalue),
AP = appearance,
OC = analyzelayer(specification.layer),
- F = pdfnull(), -- another rediculous need to satisfy validation
+ -- F = pdfnull(), -- another rediculous need to satisfy validation
+ F = (flags | 4) & (1023-1-2-32-256), -- set 3, clear 1,2,6,9; PDF 32000-1, p385
}
local width = specification.width or 0
local height = specification.height or 0
@@ -534,7 +541,6 @@ function nodeinjections.comment(specification) -- brrr: seems to be done twice
Name = name,
NM = pdfstring("comment:"..nofcomments),
AP = appearance,
- F = pdfnull(), -- another rediculous need to satisfy validation
}
local width = specification.width or 0
local height = specification.height or 0
diff --git a/tex/context/base/mkiv/luat-cod.lua b/tex/context/base/mkiv/luat-cod.lua
index 51eab5a1d..3125495b4 100644
--- a/tex/context/base/mkiv/luat-cod.lua
+++ b/tex/context/base/mkiv/luat-cod.lua
@@ -137,10 +137,8 @@ if LUATEXENGINE == nil then
end
if LUATEXVERSION == nil then
- LUATEXVERSION = status.luatex_revision
LUATEXVERSION = status.luatex_version/100
- -- + tonumber(LUATEXVERSION)/1000
- + (tonumber(LUATEXVERSION) or (string.byte(LUATEXVERSION)-string.byte("a")+10))/1000
+ + tonumber(status.luatex_revision)/10000
end
if CONTEXTLMTXMODE == nil then
diff --git a/tex/context/base/mkiv/luat-ini.lua b/tex/context/base/mkiv/luat-ini.lua
index 332980013..cec0161e7 100644
--- a/tex/context/base/mkiv/luat-ini.lua
+++ b/tex/context/base/mkiv/luat-ini.lua
@@ -26,7 +26,7 @@ if not global then
end
LUATEXVERSION = status.luatex_version/100
- + tonumber(status.luatex_revision)/1000
+ + tonumber(status.luatex_revision)/10000
LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine)
or (string.find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex")
diff --git a/tex/context/base/mkiv/luat-lib.mkiv b/tex/context/base/mkiv/luat-lib.mkiv
index c3bbd8e19..0ffd1dd40 100644
--- a/tex/context/base/mkiv/luat-lib.mkiv
+++ b/tex/context/base/mkiv/luat-lib.mkiv
@@ -73,9 +73,9 @@
\registerctxluafile{data-use}{}
\registerctxluafile{data-aux}{}
-\ifcase\contextlmtxmode
- \registerctxluafile{util-lib}{}
-\fi
+% \ifcase\contextlmtxmode
+% \registerctxluafile{util-lib}{}
+% \fi
\registerctxluafile{luat-cbk}{}
\registerctxluafile{luat-run}{}
diff --git a/tex/context/base/mkiv/m-gnuplot.mkxl b/tex/context/base/mkiv/m-gnuplot.mkxl
new file mode 100644
index 000000000..2077b1741
--- /dev/null
+++ b/tex/context/base/mkiv/m-gnuplot.mkxl
@@ -0,0 +1,97 @@
+%D \module
+%D [ file=m-gnuplot,
+%D version=2020.02.10,
+%D title=\CONTEXT\ Extra Modules,
+%D subtitle=Gnuplot,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This is a variant on the \GNUPLOT\ terminal code. At some point (when there is a
+%D reason) I will make a proper environment that can be used for embedded code.
+
+\unexpanded\def\includegnuplotsvgfile[#1]%
+ {\hbox\bgroup
+ \ctxlua{metapost.startsvghashing()}%
+ \includesvgfile[#1]%
+ \ctxlua{metapost.stopsvghashing()}%
+ \egroup}
+
+\startluacode
+
+local modificationtime = lfs.modification
+local longtostring = string.longtostring
+local formatters = string.formatters
+local expandfilename = dir.expandname
+local isfile = lfs.isfile
+
+local runner = sandbox.registerrunner {
+ name = "gnuplot to svg",
+ program = "gnuplot",
+ template = longtostring [[
+ -e "set output '%newname%'; set terminal svg"
+ "%oldname%"
+ ]],
+ checkers = {
+ oldname = "readable",
+ newname = "writable",
+ },
+}
+
+figures.programs.gnuplot = {
+ runner = runner,
+}
+
+local function remap(specification)
+ local oldname = specification.fullname
+ if oldname then
+ local newname = file.replacesuffix(oldname,"svg")
+ local oldtime = modificationtime(oldname) or 0
+ local newtime = modificationtime(newname) or 0
+ if newtime == 0 or oldtime > newtime then
+ runner {
+ newname = expandfilename(newname),
+ oldname = expandfilename(oldname),
+ }
+ end
+ if isfile(newname) then
+ local only = file.nameonly(newname)
+ local name = formatters["svg-%s-inclusion"](only)
+ local code = formatters["\\includegnuplotsvgfile[%s]\\resetbuffer[%s]"](newname,name)
+ buffers.assign(name,code)
+ specification.format = "buffer"
+ specification.fullname = name
+ end
+ end
+ return specification
+end
+
+figures.remappers.gp = { svg = remap }
+
+\stopluacode
+
+\continueifinputfile{m-gnuplot.mkxl}
+
+\startluacode
+io.savedata("m-gnuplot-demo.gp", [[
+set format xy "$%g$"
+
+set title 'This is a plot of $y=\\sin(x)$'
+set xlabel 'This is the $x$ axis'
+set ylabel 'This is the $y$ axis'
+
+plot [0:6.28] [0:1] sin(x)
+]])
+\stopluacode
+
+\starttext
+
+ \externalfigure[m-gnuplot-demo.gp][conversion=svg,width=4cm]
+
+ \externalfigure[m-gnuplot-demo.gp][conversion=svg,width=8cm]
+
+\stoptext
diff --git a/tex/context/base/mkiv/m-zint.mkxl b/tex/context/base/mkiv/m-zint.mkxl
deleted file mode 100644
index 7135126ba..000000000
--- a/tex/context/base/mkiv/m-zint.mkxl
+++ /dev/null
@@ -1,7 +0,0 @@
-% this is a stub:
-
-% \uselibrary[zint]
-
-\input libs-imp-zint.mkxl
-
-\endinput
diff --git a/tex/context/base/mkiv/meta-imp-threesix.mkxl b/tex/context/base/mkiv/meta-imp-threesix.mkxl
new file mode 100644
index 000000000..277aa85f7
--- /dev/null
+++ b/tex/context/base/mkiv/meta-imp-threesix.mkxl
@@ -0,0 +1,253 @@
+% not yet a module
+
+\startluacode
+ local gsub, utfbyte = string.gsub, utf.byte
+
+ -- The font from DEK's facs9b.ps (I wish I was clever enough to understand all the good
+ -- stuff in there):
+
+ local font36 = {
+ ["0"] = [[00111100 01111110 11000011 11000011 11000011 11000011 01111110 00111100]],
+ ["1"] = [[00011100 11111100 11101100 00001100 00001100 00001100 11111111 11111111]],
+ ["2"] = [[00111110 01110011 01110011 00000011 00001110 00111000 11110001 11111111]],
+ ["3"] = [[01111110 01100110 00000110 00111100 00000110 11100111 11100111 01111110]],
+ ["4"] = [[00001110 00011110 00110110 01100110 11111111 11111111 00000110 00001110]],
+ ["5"] = [[01111110 01111110 01000000 01111100 01000111 00000011 11000111 11111110]],
+ ["6"] = [[01111110 01100110 11000000 11011100 11100110 11000011 01100011 01111110]],
+ ["7"] = [[11111111 11111111 10000111 10001110 00011100 00011100 00011100 00011100]],
+ ["8"] = [[01111110 01100110 01100110 00111100 11000011 11000011 11000011 01111110]],
+ ["9"] = [[01111110 11000110 11000011 01100111 00111011 00000011 01100110 01111110]],
+ ["A"] = [[000110000 000111000 001111100 001101100 011001110 011111110 010000110 111100111]],
+ ["B"] = [[1111100 1110110 0110110 0111100 0110011 0110011 1110011 1111100]],
+ ["C"] = [[01111101 11110011 11100001 11100001 11100000 11100000 11100001 01111110]],
+ ["D"] = [[11111100 11100010 01100011 01100011 01100011 01100011 11100010 11111100]],
+ ["E"] = [[1111111 1110001 0110101 0111100 0110100 0110001 1110001 1111111]],
+ ["F"] = [[11111111 11100001 01100101 01111100 01100100 01100000 11111000 11111000]],
+ ["G"] = [[01111010 11100110 11100010 11100000 11100111 11100010 11100010 01111100]],
+ ["H"] = [[11100111 11100111 01000010 01111110 01000010 01000010 11100111 11100111]],
+ ["I"] = [[1111111 1111111 0011000 0011000 0011000 0011000 1111111 1111111]],
+ ["J"] = [[01111111 01111111 00000110 00000110 11110110 01100110 01100110 00111100]],
+ ["K"] = [[11101110 11100100 01101000 01110000 01111000 01101100 11100110 11101111]],
+ ["L"] = [[111111000 111111000 011000000 011000000 011000000 011000011 111000011 111111111]],
+ ["M"] = [[1100000011 1110000111 0111111110 0100110010 0100110010 0100000010 1100000011 1100000011]],
+ ["N"] = [[11000011 11100011 01110010 01111010 01011110 01001110 11100110 11100010]],
+ ["O"] = [[01111110 11000011 11000011 11000011 11000011 11000011 11000011 01111110]],
+ ["P"] = [[11111110 11100011 01100011 01111110 01100000 01100000 11111000 11111000]],
+ ["Q"] = [[01111100 11000110 11000110 11000110 11000110 11001110 11000110 01111101]],
+ ["R"] = [[11111100 11100110 01100110 01111100 01101000 01100100 11100010 11100111]],
+ ["S"] = [[01111110 11100001 11100001 01111000 00011110 10000111 11000011 10111110]],
+ ["T"] = [[1111111111 1100110011 1100110011 0000110000 0000110000 0000110000 0001111000 0001111000]],
+ ["U"] = [[111101111 111101111 011000010 011000010 011000010 011000010 011000010 001111100]],
+ ["V"] = [[11111000111 11111000111 01110000010 00110000100 00111000100 00011001000 00001101000 00001110000]],
+ ["W"] = [[111000000111 111000000111 110000000010 011000000100 011001000100 001101101000 001101101000 000110110000]],
+ ["X"] = [[1111001110 1111000110 0001101000 0000110000 0000110000 0001011000 0110001111 0111001111]],
+ ["Y"] = [[111100011 111100011 011000010 001110100 000111000 000011000 001111110 001111110]],
+ ["Z"] = [[11111111 10000111 00001110 00011100 00111000 01110000 11100001 11111111]],
+ }
+
+ local f_code = string.formatters["ThreeSix(%s);"]
+ local replace = { ["0"] = "N;", ["1"] = "Y;", [" "] = "L;" }
+
+ local function remap(str)
+ -- permit abundant spacing (bonus)
+ str = gsub(str,"%s+", " ")
+ -- remap what we got to macro calls
+ str = gsub(str,".",replace)
+ -- return the result
+ return str
+ end
+
+ function MP.registerthreesix(name)
+ fonts.dropins.registerglyphs {
+ name = name,
+ units = 12,
+ usecolor = true,
+ preamble = "InitializeThreeSix;",
+ }
+ for u, v in table.sortedhash(font36) do
+ local ny = 8
+ local nx = (#v - ny + 1) // ny
+ local height = ny * 1.1 - 0.1
+ local width = nx * 1.1 - 0.1
+ fonts.dropins.registerglyph {
+ category = name,
+ unicode = utfbyte(u),
+ width = width,
+ height = height,
+ code = f_code(remap(v)),
+ }
+ end
+ end
+
+ MP.registerthreesix("fontthreesix")
+\stopluacode
+
+% \startMPcalculation{simplefun}
+% def InitializeThreeSix =
+% save Y, N, L, S ; save dx, dy, nx, ny ;
+% save shape, fillcolor, mypen, random, currentpen, spread, hoffset ;
+% string shape, fillcolor, mypen ; boolean random ; pen currentpen ;
+% dx := 11/10 ;
+% dy := - 11/10 ;
+% nx := - dx ;
+% ny := 0 ;
+% shape := getparameterdefault "mpsfont" "shape" "circle" ;
+% random := hasoption "mpsfont" "random" "true" ;
+% fillcolor := getparameterdefault "mpsfont" "color" "" ;
+% mypen := getparameterdefault "mpsfont" "pen" "" ;
+% spread := getparameterdefault "mpsfont" "spread" 0 ;
+% hoffset := 12 * spread / 2 ;
+% currentpen := pencircle
+% if mypen = "fancy" :
+% xscaled 1/20 yscaled 2/20 rotated 45
+% else :
+% scaled 1/20
+% fi ;
+% if shape == "square" :
+% def S =
+% unitsquare if random : randomized 1/10 fi
+% shifted (nx,ny)
+% enddef ;
+% elseif shape = "diamond" :
+% def S =
+% unitdiamond if random : randomized 1/10 fi
+% shifted (nx,ny)
+% enddef ;
+% else :
+% def S =
+% unitcircle if random : randomizedcontrols 1/20 fi
+% shifted (nx,ny)
+% enddef ;
+% fi ;
+% def N =
+% nx := nx + dx ;
+% draw S ;
+% enddef ;
+% if fillcolor = "random" :
+% def Y =
+% nx := nx + dx ;
+% fillup S withcolor white randomized (2/3,2/3,2/3) ;
+% enddef ;
+% elseif fillcolor = "" :
+% def Y =
+% nx := nx + dx ;
+% fillup S ;
+% enddef ;
+% else :
+% def Y =
+% nx := nx + dx ;
+% fillup S withcolor fillcolor ;
+% enddef ;
+% fi ;
+% def L =
+% nx := - dx ;
+% ny := ny + dy ;
+% enddef ;
+% enddef ;
+%
+% vardef ThreeSix (text code) =
+% InitializeThreeSix ;
+% draw image (code) shifted (hoffset,-ny) ;
+% enddef ;
+% \stopMPcalculation
+
+\startMPcalculation{simplefun}
+ def InitializeThreeSix =
+ save Y, N, L, S ;
+ % save dx, dy, nx, ny ;
+ save shape, fillcolor, mypen, random, threesixpen, spread, hoffset ;
+ string shape, fillcolor, mypen ; boolean random ; pen threesixpen ;
+ % dx := 11/10 ;
+ % dy := - 11/10 ;
+ % nx := - dx ;
+ % ny := 0 ;
+ shape := getparameterdefault "mpsfont" "shape" "circle" ;
+ random := hasoption "mpsfont" "random" "true" ;
+ fillcolor := getparameterdefault "mpsfont" "color" "" ;
+ mypen := getparameterdefault "mpsfont" "pen" "" ;
+ spread := getparameterdefault "mpsfont" "spread" 0 ;
+ hoffset := 12 * spread / 2 ;
+ threesixpen := pencircle
+ if mypen = "fancy" :
+ xscaled 1/20 yscaled 2/20 rotated 45
+ else :
+ scaled 1/20
+ fi ;
+ if shape == "square" :
+ def S =
+ unitsquare if random : randomized 1/10 fi
+ shifted (nx,ny)
+ enddef ;
+ elseif shape = "diamond" :
+ def S =
+ unitdiamond if random : randomized 1/10 fi
+ shifted (nx,ny)
+ enddef ;
+ else :
+ def S =
+ unitcircle if random : randomizedcontrols 1/20 fi
+ shifted (nx,ny)
+ enddef ;
+ fi ;
+ def N =
+ nx := nx + dx ;
+ draw S ;
+ enddef ;
+ if fillcolor = "random" :
+ def Y =
+ nx := nx + dx ;
+ fillup S withcolor white randomized (2/3,2/3,2/3) ;
+ enddef ;
+ elseif fillcolor = "" :
+ def Y =
+ nx := nx + dx ;
+ fillup S ;
+ enddef ;
+ else :
+ def Y =
+ nx := nx + dx ;
+ fillup S withcolor fillcolor ;
+ enddef ;
+ fi ;
+ def L =
+ nx := - dx ;
+ ny := ny + dy ;
+ enddef ;
+ enddef ;
+
+ vardef ThreeSix (text code) =
+ save dx, dy, nx, ny ;
+ dx := 11/10 ;
+ dy := - 11/10 ;
+ nx := - dx ;
+ ny := 0 ;
+ pickup threesixpen ;
+ draw image (code) shifted (hoffset,-ny) ;
+ enddef ;
+\stopMPcalculation
+
+\definefontfeature % black and white, with some spread
+ [fontthreesix]
+ [default]
+ [metapost=fontthreesix]
+
+\definefontfeature % color, with some spread
+ [fontthreesix-tweak]
+ [default]
+ [metapost={category=fontthreesix,spread=.1}]
+
+\definefontfeature % color, with some spread
+ [fontthreesix-color]
+ [default]
+ [metapost={category=fontthreesix,shape=diamond,color=random,pen=fancy,spread=.1}]
+
+\definefontfeature % color, tight
+ [fontthreesix-initial]
+ [metapost={category=fontthreesix,color=random,shape=circle}] % units?
+
+\definefont[DEKFontA][Serif*fontthreesix]
+\definefont[DEKFontB][Serif*fontthreesix-color]
+\definefont[DEKFontC][Serif*fontthreesix-initial]
+\definefont[DEKFontD][Serif*fontthreesix-tweak]
+
+\endinput
diff --git a/tex/context/base/mkiv/meta-tex.mkiv b/tex/context/base/mkiv/meta-tex.mkiv
index 418ddc196..c580596f7 100644
--- a/tex/context/base/mkiv/meta-tex.mkiv
+++ b/tex/context/base/mkiv/meta-tex.mkiv
@@ -236,4 +236,7 @@
\unexpanded\def\svgsetlayer#1#2%
{\setlayer[svgmps][\c!x=#1\onebasepoint,\c!y=#2\onebasepoint]} % {#3}
+\unexpanded\def\svghashed#1%
+ {\clf_svghashed#1\relax}
+
\protect \endinput
diff --git a/tex/context/base/mkiv/mlib-svg.lua b/tex/context/base/mkiv/mlib-svg.lua
index b56c1fd54..f4b3117a6 100644
--- a/tex/context/base/mkiv/mlib-svg.lua
+++ b/tex/context/base/mkiv/mlib-svg.lua
@@ -75,24 +75,21 @@ if not modules then modules = { } end modules ['mlib-svg'] = {
-- One can run into pretty crazy images, like lines that are fills being clipped
-- to some width. That's the danger of hiding yourself behind an interface I guess.
-local rawget, type, tonumber, tostring, next, setmetatable = rawget, type, tonumber, tostring, next, setmetatable
+local rawget, rawset, type, tonumber, tostring, next, setmetatable = rawget, rawset, type, tonumber, tostring, next, setmetatable
-local P, S, R, C, Ct, Cs, Cc, Cp, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Cc, lpeg.Cp, lpeg.Carg
+local P, S, R, C, Ct, Cs, Cc, Cp, Cg, Cf, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Cc, lpeg.Cp, lpeg.Cg, lpeg.Cf, lpeg.Carg
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
-local pi, sin, cos, asin, sind, cosd, tan, abs, sqrt = math.pi, math.sin, math.cos, math.asin, math.sind, math.cosd, math.tan, math.abs, math.sqrt
+local sqrt = math.sqrt
local concat, setmetatableindex, sortedhash = table.concat, table.setmetatableindex, table.sortedhash
local gmatch, gsub, find, match, rep = string.gmatch, string.gsub, string.find, string.match, string.rep
local formatters, fullstrip = string.formatters, string.fullstrip
-local extract = bit32.extract
local utfsplit, utfbyte = utf.split, utf.byte
local xmlconvert, xmlcollected, xmlcount, xmlfirst, xmlroot = xml.convert, xml.collected, xml.count, xml.first, xml.root
local xmltext, xmltextonly = xml.text, xml.textonly
local css = xml.css or { } -- testing
-local bpfactor = number.dimenfactors.bp
-
local function xmlinheritattributes(c,pa)
local at = c.at
local dt = c.dt
@@ -134,6 +131,47 @@ local pathtracer = {
["fill-opacity"] = ".75",
}
+-- This is just an experiment. Todo: reset hash etc. Also implement
+-- an option handler.
+
+local svghash = false do
+
+ local svglast = 0
+ local svglist = false
+
+ local function checkhash(t,k)
+ local n = svglast + 1
+ svglast = n
+ svglist[n] = k
+ t[k] = n
+ return n
+ end
+
+ function metapost.startsvghashing()
+ svglast = 0
+ svglist = { }
+ svghash = setmetatableindex(checkhash)
+ end
+
+ function metapost.stopsvghashing()
+ svglast = 0
+ svglist = false
+ svghash = false
+ end
+
+ interfaces.implement {
+ name = "svghashed",
+ arguments = "integer",
+ actions = function(n)
+ local t = svglist and svglist[n]
+ if t then
+ context(t)
+ end
+ end
+ }
+
+end
+
-- We have quite some closures because otherwise we run into the local variable
-- limitations. It doesn't always look pretty now, sorry. I'll clean up this mess
-- some day (the usual nth iteration of code).
@@ -149,6 +187,8 @@ local pathtracer = {
local a2c do
+ local pi, sin, cos, tan, asin, abs = math.pi, math.sin, math.cos, math.tan, math.asin, math.abs
+
local d120 = (pi * 120) / 180
local pi2 = 2 * pi
@@ -401,6 +441,8 @@ local rgbcomponents, withcolor, thecolor do
local f_svggray = formatters['svggray(%.3N)']
local f_svgname = formatters['"%s"']
+ local extract = bit32.extract
+
local triplets = setmetatableindex(function(t,k)
-- we delay building all these strings
local v = svgcolors[k]
@@ -971,6 +1013,8 @@ local f_wrapped_stop = formatters[") shifted (0,%N) scaled %N ;"]
local handletransform, handleviewbox do
+ local sind = math.sind
+
--todo: better lpeg
local f_rotatedaround = formatters[" rotatedaround((%N,%N),%N)"]
@@ -1017,7 +1061,7 @@ local handletransform, handleviewbox do
local function skewx(x)
if x then
- return f_slanted_x(math.sind(-x))
+ return f_slanted_x(sind(-x))
else
return ""
end
@@ -1025,7 +1069,7 @@ local handletransform, handleviewbox do
local function skewy(y)
if y then
- return f_slanted_y(math.sind(-y))
+ return f_slanted_y(sind(-y))
else
return ""
end
@@ -1035,24 +1079,34 @@ local handletransform, handleviewbox do
return f_matrix(rx or 1, sx or 0, sy or 0, ry or 1, tx or 0, - (ty or 0))
end
- -- how to deal with units here?
+ -- How to deal with units here? Anyway, order seems to matter.
- local p_transform = Cs ( (
- P("translate") * p_numbers / translate -- maybe xy
- + P("scale") * p_numbers / scale
- + P("rotate") * p_numbers / rotate
- + P("matrix") * p_numbers / matrix
- + P("skewX") * p_numbers / skewx
- + P("skewY") * p_numbers / skewy
- -- + p_separator
- + P(1)/""
- )^1)
+ local p_transform = Cf ( Ct("") * (
+ lpegpatterns.whitespace^0 * Cg(
+ C("translate") * (p_numbers / translate) -- maybe xy
+ + C("scale") * (p_numbers / scale)
+ + C("rotate") * (p_numbers / rotate)
+ + C("matrix") * (p_numbers / matrix)
+ + C("skewX") * (p_numbers / skewx)
+ + C("skewY") * (p_numbers / skewy)
+ )
+ )^1, rawset)
handletransform = function(at)
local t = at.transform
if t then
local e = lpegmatch(p_transform,t)
- return s_transform_start, f_transform_stop(e), t
+ if e then
+ e = concat({
+ e.rotate or "",
+ e.skewX or "",
+ e.skewY or "",
+ e.scale or "",
+ e.translate or "",
+ e.matrix or "",
+ }, " ")
+ return s_transform_start, f_transform_stop(e), t
+ end
end
end
@@ -2340,6 +2394,7 @@ do
local f_scaled = formatters["\\svgscaled{%N}{%s}{%s}{%s}"]
local f_normal = formatters["\\svgnormal{%s}{%s}{%s}"]
+ local f_hashed = formatters["\\svghashed{%s}"]
-- We move to the outer (x,y) and when we have an inner offset we
-- (need to) compensate for that outer offset.
@@ -2348,8 +2403,14 @@ do
-- local f_text_normal_svg = formatters['(svgtext("%s") shifted (%N,%N))']
-- local f_text_simple_svg = formatters['svgtext("%s")']
- local f_text_normal_svg = formatters['(textext.drt("%s") shifted (%N,%N))']
- local f_text_simple_svg = formatters['textext.drt("%s")']
+ local anchors = {
+ ["start"] = "drt",
+ ["end"] = "dflt",
+ ["middle"] = "d",
+ }
+
+ local f_text_normal_svg = formatters['(textext.%s("%s") shifted (%N,%N))']
+ local f_text_simple_svg = formatters['textext.%s("%s")']
-- or just maptext
@@ -2480,7 +2541,9 @@ do
di = gsub(di,"%s+$","")
end
local chars = utfsplit(di)
- if tx then
+ if svghash then
+ di = f_hashed(svghash[di])
+ elseif tx then
for i=1,#chars do
chars[i] = f_poschar(
(tx[i] or 0) - x,
@@ -2540,6 +2603,7 @@ do
v_fill = "black"
end
local color, opacity, invisible = fillproperties(v_fill,at)
+ local anchor = anchors[at["text-anchor"] or "start"] or "drt"
local r = metapost.remappedtext(only)
if r then
if x == 0 and y == 0 then
@@ -2567,9 +2631,9 @@ do
result[#result+1] = s_stoplayer
result = concat(result)
if x == 0 and y == 0 then
- result = f_text_simple_svg(result)
+ result = f_text_simple_svg(anchor,result)
else
- result = f_text_normal_svg(result,x,y)
+ result = f_text_normal_svg(anchor,result,x,y)
end
flushobject(result,at,color,opacity)
if trace_text then
@@ -2741,7 +2805,7 @@ do
definitions = { }
tagstyles = { }
classstyles = { }
- for s in xmlcollected(c,"/style") do
+ for s in xmlcollected(c,"style") do -- can also be in a def, so let's play safe
handlestyle(c)
end
handlechains(c)
@@ -2777,101 +2841,107 @@ end
-- a bit more efficient, because we now go to mp and back which is kind of redundant,
-- but for now it will do.
-function metapost.includesvgfile(filename,offset) -- offset in sp
- if lfs.isfile(filename) then
+do
+
+ local bpfactor = number.dimenfactors.bp
+
+ function metapost.includesvgfile(filename,offset) -- offset in sp
+ if lfs.isfile(filename) then
+ context.startMPcode("doublefun")
+ context('draw lmt_svg [ filename = "%s", offset = %N ] ;',filename,(offset or 0)*bpfactor)
+ context.stopMPcode()
+ end
+ end
+
+ function metapost.includesvgbuffer(name,offset) -- offset in sp
context.startMPcode("doublefun")
- context('draw lmt_svg [ filename = "%s", offset = %N ] ;',filename,(offset or 0)*bpfactor)
+ context('draw lmt_svg [ buffer = "%s", offset = %N ] ;',name or "",(offset or 0)*bpfactor)
context.stopMPcode()
end
-end
-
-function metapost.includesvgbuffer(name,offset) -- offset in sp
- context.startMPcode("doublefun")
- context('draw lmt_svg [ buffer = "%s", offset = %N ] ;',name or "",(offset or 0)*bpfactor)
- context.stopMPcode()
-end
-interfaces.implement {
- name = "includesvgfile",
- actions = metapost.includesvgfile,
- arguments = { "string", "dimension" },
-}
+ interfaces.implement {
+ name = "includesvgfile",
+ actions = metapost.includesvgfile,
+ arguments = { "string", "dimension" },
+ }
-interfaces.implement {
- name = "includesvgbuffer",
- actions = metapost.includesvgbuffer,
- arguments = { "string", "dimension" },
-}
+ interfaces.implement {
+ name = "includesvgbuffer",
+ actions = metapost.includesvgbuffer,
+ arguments = { "string", "dimension" },
+ }
-function metapost.showsvgpage(data)
- local dd = data.data
- if not dd then
- local fn = data.filename
- dd = fn and table.load(fn)
- end
- if type(dd) == "table" then
- local comment = data.comment
- local offset = data.pageoffset
- local index = data.index
- local first = math.max(index or 1,1)
- local last = math.min(index or #dd,#dd)
- for i=first,last do
- local d = setmetatableindex( {
- data = dd[i],
- comment = comment and i or false,
- pageoffset = offset or nil,
- }, data)
- metapost.showsvgpage(d)
- end
- elseif data.method == "code" then
- context.startMPcode(doublefun)
- context(metapost.svgtomp(data))
- context.stopMPcode()
- else
- context.startMPpage { instance = "doublefun", offset = data.pageoffset or nil }
- context(metapost.svgtomp(data))
+ function metapost.showsvgpage(data)
+ local dd = data.data
+ if not dd then
+ local fn = data.filename
+ dd = fn and table.load(fn)
+ end
+ if type(dd) == "table" then
local comment = data.comment
- if comment then
- context("draw boundingbox currentpicture withcolor .6red ;")
- context('draw textext.bot("\\strut\\tttf %s") ysized (10pt) shifted center bottomboundary currentpicture ;',comment)
- end
- context.stopMPpage()
- end
-end
-
-function metapost.typesvgpage(data)
- local dd = data.data
- if not dd then
- local fn = data.filename
- dd = fn and table.load(fn)
- end
- if type(dd) == "table" then
- local index = data.index
- if index and index > 0 and index <= #dd then
- data = dd[index]
+ local offset = data.pageoffset
+ local index = data.index
+ local first = math.max(index or 1,1)
+ local last = math.min(index or #dd,#dd)
+ for i=first,last do
+ local d = setmetatableindex( {
+ data = dd[i],
+ comment = comment and i or false,
+ pageoffset = offset or nil,
+ }, data)
+ metapost.showsvgpage(d)
+ end
+ elseif data.method == "code" then
+ context.startMPcode(doublefun)
+ context(metapost.svgtomp(data))
+ context.stopMPcode()
else
- data = nil
+ context.startMPpage { instance = "doublefun", offset = data.pageoffset or nil }
+ context(metapost.svgtomp(data))
+ local comment = data.comment
+ if comment then
+ context("draw boundingbox currentpicture withcolor .6red ;")
+ context('draw textext.bot("\\strut\\tttf %s") ysized (10pt) shifted center bottomboundary currentpicture ;',comment)
+ end
+ context.stopMPpage()
end
end
- if type(data) == "string" and data ~= "" then
- buffers.assign("svgpage",data)
- context.typebuffer ({ "svgpage" }, { option = "XML", strip = "yes" })
+
+ function metapost.typesvgpage(data)
+ local dd = data.data
+ if not dd then
+ local fn = data.filename
+ dd = fn and table.load(fn)
+ end
+ if type(dd) == "table" then
+ local index = data.index
+ if index and index > 0 and index <= #dd then
+ data = dd[index]
+ else
+ data = nil
+ end
+ end
+ if type(data) == "string" and data ~= "" then
+ buffers.assign("svgpage",data)
+ context.typebuffer ({ "svgpage" }, { option = "XML", strip = "yes" })
+ end
end
-end
-function metapost.svgtopdf(data,...)
- local mps = metapost.svgtomp(data,...)
- if mps then
- -- todo: special instance, only basics needed
- local pdf = metapost.simple("metafun",mps,true,false,"svg")
- if pdf then
- return pdf
+ function metapost.svgtopdf(data,...)
+ local mps = metapost.svgtomp(data,...)
+ if mps then
+ -- todo: special instance, only basics needed
+ local pdf = metapost.simple("metafun",mps,true,false,"svg")
+ if pdf then
+ return pdf
+ else
+ -- message
+ end
else
-- message
end
- else
- -- message
end
+
end
do
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index b7c571975..e5fe90ad2 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 453fc01db..ac49b2139 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/tabl-xtb.lua b/tex/context/base/mkiv/tabl-xtb.lua
index d2b1e9768..2ff87e21a 100644
--- a/tex/context/base/mkiv/tabl-xtb.lua
+++ b/tex/context/base/mkiv/tabl-xtb.lua
@@ -478,36 +478,50 @@ end
function xtables.initialize_construct()
local r = data.currentrow
local c = data.currentcolumn + 1
+ local settings = data.settings
local rows = data.rows
local row = rows[r]
while row[c].span do -- can also be previous row ones
c = c + 1
end
data.currentcolumn = c
- local widths = data.widths
- local heights = data.heights
- local depths = data.depths
+ local widths = data.widths
+ local heights = data.heights
+ local depths = data.depths
+ local distances = data.distances
--
local drc = row[c]
local wd = drc.wd
local ht = drc.ht
local dp = drc.dp
+ local nx = drc.nx - 1
+ local ny = drc.ny - 1
--
local width = widths[c]
local height = heights[r]
local depth = depths[r] -- problem: can be the depth of a one liner
--
- for x=1,drc.nx-1 do
- width = width + widths[c+x]
+ local total = height + depth
+ --
+ if nx > 0 then
+ for x=1,nx do
+ width = width + widths[c+x] + distances[c+x-1]
+ end
+ local distance = settings.columndistance
+ if distance ~= 0 then
+ width = width + nx * distance
+ end
end
--
- local total = height + depth
- local ny = drc.ny
- if ny > 1 then
- for y=1,ny-1 do
+ if ny > 0 then
+ for y=1,ny do
local nxt = r + y
total = total + heights[nxt] + depths[nxt]
end
+ local distance = settings.rowdistance
+ if distance ~= 0 then
+ total = total + ny * distance
+ end
end
--
texsetdimen("d_tabl_x_width",width)
diff --git a/tex/context/base/mkiv/util-pck.lua b/tex/context/base/mkiv/util-pck.lua
index b90853fb6..6af53f9eb 100644
--- a/tex/context/base/mkiv/util-pck.lua
+++ b/tex/context/base/mkiv/util-pck.lua
@@ -10,6 +10,7 @@ if not modules then modules = { } end modules ['util-pck'] = {
local next, tostring, type = next, tostring, type
local sort, concat = table.sort, table.concat
+local format = string.format
local sortedhashkeys, sortedkeys, tohash = table.sortedhashkeys, table.sortedkeys, table.tohash
utilities = utilities or { }
@@ -17,14 +18,17 @@ utilities.packers = utilities.packers or { }
local packers = utilities.packers
packers.version = 1.01
+local fmt_kv = JITSUPPORTED and "%s=%s" or "%s=%q"
+local fmt_kt = JITSUPPORTED and "%s={%s}" or "%s={%q}"
+
local function hashed(t)
local s, ns = { }, 0
for k, v in next, t do
ns = ns + 1
if type(v) == "table" then
- s[ns] = k .. "={" .. hashed(v) .. "}"
+ s[ns] = format(fmt_kt,k,hashed(v))
else
- s[ns] = k .. "=" .. tostring(v)
+ s[ns] = format(fmt_kv,k,v)
end
end
sort(s)
@@ -35,7 +39,7 @@ local function simplehashed(t)
local s, ns = { }, 0
for k, v in next, t do
ns = ns + 1
- s[ns] = k .. "=" .. v
+ s[ns] = format(fmt_kv,k,v)
end
sort(s)
return concat(s,",")
diff --git a/tex/context/base/mkiv/util-sql.lua b/tex/context/base/mkiv/util-sql.lua
index 61f1f19fa..36f3eab19 100644
--- a/tex/context/base/mkiv/util-sql.lua
+++ b/tex/context/base/mkiv/util-sql.lua
@@ -116,12 +116,12 @@ if optional then
library = "mysql",
swiglib = "mysql",
postgress = "postgress",
- sqlite = "sqlite"
- sqlite3 = "sqlite"
+ sqlite = "sqlite",
+ sqlite3 = "sqlite",
}
setmetatableindex(sql.methods,function(t,k)
- local m = methods[k
+ local m = methods[k]
if m then
report_state("start loading method %a as %a",k,m)
require("libs-imp-" .. m)
diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua
index 68c9be586..4d23f88b7 100644
--- a/tex/context/base/mkiv/util-str.lua
+++ b/tex/context/base/mkiv/util-str.lua
@@ -701,14 +701,18 @@ local format_left = function(f)
end
end
-local format_q = function()
+local format_q = JITSUPPORTED and function()
n = n + 1
-- lua 5.3 has a different q than lua 5.2 (which does a tostring on numbers)
-- return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
-- return format("(a%s ~= nil and escapedquotes(tostring(a%s)) or '')",n,n)
+end or function()
+ n = n + 1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
+
local format_Q = function() -- fast escaping
n = n + 1
-- return format("format('%%q',tostring(a%s))",n)
diff --git a/tex/context/base/mkiv/util-tab.lua b/tex/context/base/mkiv/util-tab.lua
index 410292ca8..4dafb2acd 100644
--- a/tex/context/base/mkiv/util-tab.lua
+++ b/tex/context/base/mkiv/util-tab.lua
@@ -314,102 +314,177 @@ end
-- best keep [%q] keys (as we have some in older applications i.e. saving user data (otherwise
-- we also need to check for reserved words)
-local f_hashed_string = formatters["[%Q]=%Q,"]
-local f_hashed_number = formatters["[%Q]=%s,"]
-local f_hashed_boolean = formatters["[%Q]=%l,"]
-local f_hashed_table = formatters["[%Q]="]
-
-local f_indexed_string = formatters["[%s]=%Q,"]
-local f_indexed_number = formatters["[%s]=%s,"]
-local f_indexed_boolean = formatters["[%s]=%l,"]
-local f_indexed_table = formatters["[%s]="]
-
-local f_ordered_string = formatters["%Q,"]
-local f_ordered_number = formatters["%s,"]
-local f_ordered_boolean = formatters["%l,"]
-
-function table.fastserialize(t,prefix) -- todo, move local function out
-
- -- prefix should contain the =
- -- not sorted
- -- only number and string indices (currently)
-
- local r = { type(prefix) == "string" and prefix or "return" }
- local m = 1
- local function fastserialize(t,outer) -- no mixes
- local n = #t
- m = m + 1
- r[m] = "{"
- if n > 0 then
- local v = t[0]
- if v then
- local tv = type(v)
- if tv == "string" then
- m = m + 1 r[m] = f_indexed_string(0,v)
- elseif tv == "number" then
- m = m + 1 r[m] = f_indexed_number(0,v)
- elseif tv == "table" then
- m = m + 1 r[m] = f_indexed_table(0)
- fastserialize(v)
- elseif tv == "boolean" then
- m = m + 1 r[m] = f_indexed_boolean(0,v)
+if JITSUPPORTED then
+
+ local f_hashed_string = formatters["[%Q]=%Q,"]
+ local f_hashed_number = formatters["[%Q]=%s,"]
+ local f_hashed_boolean = formatters["[%Q]=%l,"]
+ local f_hashed_table = formatters["[%Q]="]
+
+ local f_indexed_string = formatters["[%s]=%Q,"]
+ local f_indexed_number = formatters["[%s]=%s,"]
+ local f_indexed_boolean = formatters["[%s]=%l,"]
+ local f_indexed_table = formatters["[%s]="]
+
+ local f_ordered_string = formatters["%Q,"]
+ local f_ordered_number = formatters["%s,"]
+ local f_ordered_boolean = formatters["%l,"]
+
+ function table.fastserialize(t,prefix) -- todo, move local function out
+
+ -- prefix should contain the =
+ -- not sorted
+ -- only number and string indices (currently)
+
+ local r = { type(prefix) == "string" and prefix or "return" }
+ local m = 1
+ local function fastserialize(t,outer) -- no mixes
+ local n = #t
+ m = m + 1
+ r[m] = "{"
+ if n > 0 then
+ local v = t[0]
+ if v then
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_indexed_string(0,v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_indexed_number(0,v)
+ elseif tv == "table" then
+ m = m + 1 r[m] = f_indexed_table(0)
+ fastserialize(v)
+ m = m + 1 r[m] = f_indexed_table(0)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_indexed_boolean(0,v)
+ end
end
- end
- for i=1,n do
- local v = t[i]
- local tv = type(v)
- if tv == "string" then
- m = m + 1 r[m] = f_ordered_string(v)
- elseif tv == "number" then
- m = m + 1 r[m] = f_ordered_number(v)
- elseif tv == "table" then
- fastserialize(v)
- elseif tv == "boolean" then
- m = m + 1 r[m] = f_ordered_boolean(v)
+ for i=1,n do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_ordered_string(v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_ordered_number(v)
+ elseif tv == "table" then
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_ordered_boolean(v)
+ end
end
end
- end
- -- hm, can't we avoid this ... lua should have a way to check if there
- -- is a hash part
- for k, v in next, t do
- local tk = type(k)
- if tk == "number" then
- if k > n or k < 0 then
+ -- hm, can't we avoid this ... lua should have a way to check if there
+ -- is a hash part
+ for k, v in next, t do
+ local tk = type(k)
+ if tk == "number" then
+ if k > n or k < 0 then
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_indexed_string(k,v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_indexed_number(k,v)
+ elseif tv == "table" then
+ m = m + 1 r[m] = f_indexed_table(k)
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_indexed_boolean(k,v)
+ end
+ end
+ else
local tv = type(v)
if tv == "string" then
- m = m + 1 r[m] = f_indexed_string(k,v)
+ m = m + 1 r[m] = f_hashed_string(k,v)
elseif tv == "number" then
- m = m + 1 r[m] = f_indexed_number(k,v)
+ m = m + 1 r[m] = f_hashed_number(k,v)
elseif tv == "table" then
- m = m + 1 r[m] = f_indexed_table(k)
+ m = m + 1 r[m] = f_hashed_table(k)
fastserialize(v)
elseif tv == "boolean" then
- m = m + 1 r[m] = f_indexed_boolean(k,v)
+ m = m + 1 r[m] = f_hashed_boolean(k,v)
end
end
+ end
+ m = m + 1
+ if outer then
+ r[m] = "}"
else
- local tv = type(v)
- if tv == "string" then
- m = m + 1 r[m] = f_hashed_string(k,v)
- elseif tv == "number" then
- m = m + 1 r[m] = f_hashed_number(k,v)
- elseif tv == "table" then
- m = m + 1 r[m] = f_hashed_table(k)
- fastserialize(v)
- elseif tv == "boolean" then
- m = m + 1 r[m] = f_hashed_boolean(k,v)
- end
+ r[m] = "},"
end
+ return r
end
- m = m + 1
- if outer then
- r[m] = "}"
- else
- r[m] = "},"
+ return concat(fastserialize(t,true))
+ end
+
+else
+
+ local f_v = formatters["[%q]=%q,"]
+ local f_t = formatters["[%q]="]
+ local f_q = formatters["%q,"]
+
+ function table.fastserialize(t,prefix) -- todo, move local function out
+ local r = { type(prefix) == "string" and prefix or "return" }
+ local m = 1
+ local function fastserialize(t,outer) -- no mixes
+ local n = #t
+ m = m + 1
+ r[m] = "{"
+ if n > 0 then
+ local v = t[0]
+ if v then
+ m = m + 1
+ r[m] = "[0]='"
+ if type(v) == "table" then
+ fastserialize(v)
+ else
+ r[m] = format("%q,",v)
+ end
+ end
+ for i=1,n do
+ local v = t[i]
+ m = m + 1
+ if type(v) == "table" then
+ r[m] = format("[%i]=",i)
+ fastserialize(v)
+ else
+ r[m] = format("[%i]=%q,",i,v)
+ end
+ end
+ end
+ -- hm, can't we avoid this ... lua should have a way to check if there
+ -- is a hash part
+ for k, v in next, t do
+ local tk = type(k)
+ if tk == "number" then
+ if k > n or k < 0 then
+ m = m + 1
+ if type(v) == "table" then
+ r[m] = format("[%i]=",k)
+ fastserialize(v)
+ else
+ r[m] = format("[%i]=%q,",k,v)
+ end
+ end
+ else
+ m = m + 1
+ if type(v) == "table" then
+ r[m] = format("[%q]=",k)
+ fastserialize(v)
+ else
+ r[m] = format("[%q]=%q,",k,v)
+ end
+ end
+ end
+ m = m + 1
+ if outer then
+ r[m] = "}"
+ else
+ r[m] = "},"
+ end
+ return r
end
- return r
+ return concat(fastserialize(t,true))
end
- return concat(fastserialize(t,true))
+
end
function table.deserialize(str)
@@ -533,34 +608,34 @@ end
-- husayni.tma : 0.28 -> 0.19
local f_start_key_idx = formatters["%w{"]
-local f_start_key_num = formatters["%w[%s]={"]
+local f_start_key_num = JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
local f_start_key_str = formatters["%w[%q]={"]
local f_start_key_boo = formatters["%w[%l]={"]
local f_start_key_nop = formatters["%w{"]
local f_stop = formatters["%w},"]
-local f_key_num_value_num = formatters["%w[%s]=%s,"]
-local f_key_str_value_num = formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num = formatters["%w[%l]=%s,"]
+local f_key_num_value_num = JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num = JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num = JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
-local f_key_num_value_str = formatters["%w[%s]=%Q,"]
+local f_key_num_value_str = JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
local f_key_str_value_str = formatters["%w[%Q]=%Q,"]
local f_key_boo_value_str = formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo = formatters["%w[%s]=%l,"]
+local f_key_num_value_boo = JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
local f_key_str_value_boo = formatters["%w[%Q]=%l,"]
local f_key_boo_value_boo = formatters["%w[%l]=%l,"]
-local f_key_num_value_not = formatters["%w[%s]={},"]
+local f_key_num_value_not = JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
local f_key_str_value_not = formatters["%w[%Q]={},"]
local f_key_boo_value_not = formatters["%w[%l]={},"]
-local f_key_num_value_seq = formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq = JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
local f_key_str_value_seq = formatters["%w[%Q]={ %, t },"]
local f_key_boo_value_seq = formatters["%w[%l]={ %, t },"]
-local f_val_num = formatters["%w%s,"]
+local f_val_num = JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
local f_val_str = formatters["%w%Q,"]
local f_val_boo = formatters["%w%l,"]
local f_val_not = formatters["%w{},"]
@@ -573,8 +648,6 @@ local f_table_direct = formatters["{"]
local f_table_entry = formatters["[%Q]={"]
local f_table_finish = formatters["}"]
------ f_string = formatters["%q"]
-
local spaces = utilities.strings.newrepeater(" ")
local original_serialize = table.serialize -- the extensive one, the one we started with
diff --git a/tex/context/modules/common/s-abbreviations-logos.tex b/tex/context/modules/common/s-abbreviations-logos.tex
index 9f1d5599e..11c5b9725 100644
--- a/tex/context/modules/common/s-abbreviations-logos.tex
+++ b/tex/context/modules/common/s-abbreviations-logos.tex
@@ -97,6 +97,7 @@
\logo [DVIWINDO] {dviwindo}
\logo [EBCDIC] {ebcdic}
\logo [EC] {ec}
+\logo [ECMASCRIPT] {ecmascript}
\logo [EIFFEL] {Eiffel}
\logo [EMACS] {emacs}
\logo [EMTEX] {em\TeXsuffix}
diff --git a/tex/context/modules/mkiv/m-zint.mkiv b/tex/context/modules/mkiv/m-zint.mkiv
deleted file mode 100644
index 4957c8461..000000000
--- a/tex/context/modules/mkiv/m-zint.mkiv
+++ /dev/null
@@ -1,112 +0,0 @@
-%D \module
-%D [ file=m-zint,
-%D version=2010.12.07,
-%D title=\CONTEXT\ Extra Modules,
-%D subtitle=Zint Barcode Generator,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-%D Using \type {zint} seems to be the easiest way to generate
-%D (PDF417) barcodes so therefore we now have this module. There
-%D are proper (also windows) binaries at:
-%D
-%D \starttyping
-%D http://www.zint.org.uk
-%D \stoptyping
-%D
-%D There is a bit more code than needed as we want to be able to
-%D feed names.
-
-\startluacode
-
-moduledata.zint = { }
-
-local format, lower, gsub = string.format, string.lower, string.gsub
-local patterns = lpeg.patterns
-
-local zint = "zint" -- '"c:/program files/zint/zint.exe"'
-local defaultcode = "PDF417"
-
-local whitespace = patterns.whitespace
-local spaces = whitespace^0
-local key = (spaces / "") * patterns.digit^0 * (patterns.colon * spaces / "")
-local value = (whitespace / "" + (1 - key))^1
-local pattern = lpeg.Cf(lpeg.Ct("") * (lpeg.Cg((lpeg.Cs(key) / tonumber) * (lpeg.Cs(value) / lower)) + patterns.anything)^0,rawset)
-
-local reverse
-
-local function cleancode(code)
- if not code or code == "" then
- code = defaultcode
- end
- return lower(gsub(code," ",""))
-end
-
-local function numberofcode(code)
- if not reverse then
- local types = os.resultof(format("%s --types",zint)) or ""
- local formats = lpeg.match(pattern,types)
- if not formats or not next(formats) then
- return code
- end
- reverse = table.swapped(formats) or { }
- end
- code = cleancode(code)
- return reverse[code] or code
-end
-
-function moduledata.zint.generate(code,data,suffix,options)
- if not data or data == "" then
- data = "unset"
- end
- local code = cleancode(code)
- local base = format("zint-%s-%s",code,md5.hex(data))
- local name = file.addsuffix(base,suffix or "eps")
- if not lfs.isfile(name) then
- local temp = file.addsuffix(base,"tmp")
- local code = numberofcode(code)
- logs.simple("using 'zint' to generate '%s'",base)
- io.savedata(temp,data)
- os.execute(format('%s --barcode=%s --output="%s" --input="%s" %s',zint,code,name,temp,options or ""))
- os.remove(temp)
- end
- return name
-end
-
-\stopluacode
-
-\unprotect
-
-\unexpanded\def\barcode[#1]% [alternative=,text=]
- {\bgroup
- \getdummyparameters
- [\c!alternative=,\c!text=,#1]%
- \externalfigure
- [\cldcontext{moduledata.zint.generate("\dummyparameter\c!alternative",\!!bs\dummyparameter\c!text\!!es)}]%
- [#1,\c!alternative=,\c!text=]%
- \egroup}
-
-\protect
-
-\continueifinputfile{m-zint.mkiv}
-
-\starttext
-
- \externalfigure[\cldcontext{moduledata.zint.generate("PDF417",[[Hans Hagen]])}]
- \blank
- \externalfigure[\cldcontext{moduledata.zint.generate("PDF417","Ton Otten")}]
- \blank
- \externalfigure[\cldcontext{moduledata.zint.generate("ISBN","9789490688011")}]
- \blank
- \barcode[text=Does It Work?,width=\textwidth]
- \blank
- \barcode[alternative=isbn,text=9789490688011,width=3cm]
-
-\stoptext
-
-
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index ce2794cf3..cc61d0a18 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 01/26/20 18:34:44
+-- merge date : 2020-02-11 16:36
do -- begin closure to overcome local limits and interference
@@ -1383,13 +1383,13 @@ function table.fromhash(t)
end
return hsh
end
-local noquotes,hexify,handle,compact,inline,functions,metacheck
+local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'NaN','goto','const',
}
-local function is_simple_table(t,hexify)
+local function is_simple_table(t,hexify,accurate)
local nt=#t
if nt>0 then
local n=0
@@ -1408,6 +1408,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i]=format("0x%X",v)
+ elseif accurate then
+ tt[i]=format("%q",v)
else
tt[i]=v
end
@@ -1428,6 +1430,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i+1]=format("0x%X",v)
+ elseif accurate then
+ tt[i+1]=format("%q",v)
else
tt[i+1]=v
end
@@ -1499,6 +1503,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv=="number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v))
end
@@ -1508,7 +1514,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -1536,12 +1542,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
else
handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
end
@@ -1549,12 +1559,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v))
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v))
end
@@ -1563,6 +1577,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -1579,6 +1595,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -1591,11 +1609,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -1617,6 +1637,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -1636,6 +1658,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -1653,6 +1677,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -1676,6 +1702,7 @@ local function serialize(_handle,root,name,specification)
if type(specification)=="table" then
noquotes=specification.noquotes
hexify=specification.hexify
+ accurate=specification.accurate
handle=_handle or specification.handle or print
functions=specification.functions
compact=specification.compact
@@ -3493,9 +3520,12 @@ local format_left=function(f)
return format("a%s..utfpadding(a%s,%i)",n,n,-f)
end
end
-local format_q=function()
+local format_q=JITSUPPORTED and function()
n=n+1
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end or function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
local format_Q=function()
n=n+1
@@ -9634,6 +9664,7 @@ hashmethods.normal=function(list)
m=m+1
t[m]=k..'='..tostring(v)
end
+ sort(t)
s[n]=k..'={'..concat(t,",").."}"
else
s[n]=k..'='..tostring(v)
@@ -20032,6 +20063,7 @@ function readers.sbix(f,fontdata,specification)
end
end)
local glyphs={}
+ local delayed=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 or fonts.handlers.typethree
for i=1,nofstrikes do
local strike=strikes[i]
local strikeppem=strike.ppem
@@ -20048,13 +20080,25 @@ function readers.sbix(f,fontdata,specification)
local datasize=nextoffset-glyphoffset
if datasize>0 then
setposition(f,strikeoffset+glyphoffset)
+ local x=readshort(f)
+ local y=readshort(f)
+ local tag=readtag(f)
+ local size=datasize-8
+ local data=nil
+ local offset=nil
+ if delayed then
+ offset=getposition(f)
+ data=nil
+ else
+ data=readstring(f,size)
+ size=nil
+ end
shapes[i]={
- x=readshort(f),
- y=readshort(f),
- tag=readtag(f),
- data=readstring(f,datasize-8),
- ppem=strikeppem,
- ppi=strikeppi,
+ x=x,
+ y=y,
+ o=offset,
+ s=size,
+ data=data,
}
done=done+1
if done==nofglyphs then
@@ -20233,29 +20277,46 @@ do
end
local default={ width=0,height=0 }
local glyphs=fontdata.glyphs
+ local delayed=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 or fonts.handlers.typethree
for index,subtable in sortedhash(shapes) do
if type(subtable)=="table" then
local data=nil
+ local size=nil
local metrics=default
local format=subtable.format
local offset=subtable.offsets[index]
setposition(f,offset)
if format==17 then
metrics=getsmallmetrics(f)
- data=readstring(f,readulong(f))
+ size=true
elseif format==18 then
metrics=getbigmetrics(f)
- data=readstring(f,readulong(f))
+ size=true
elseif format==19 then
metrics=subtable.metrics
- data=readstring(f,readulong(f))
+ size=true
+ else
+ end
+ if size then
+ size=readulong(f)
+ if delayed then
+ offset=getposition(f)
+ data=nil
+ else
+ offset=nil
+ data=readstring(f,size)
+ size=nil
+ end
else
+ offset=nil
end
local x=metrics.width
local y=metrics.height
shapes[index]={
x=x,
y=y,
+ o=offset,
+ s=size,
data=data,
}
local glyph=glyphs[index]
@@ -23251,7 +23312,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.110
+otf.version=3.111
otf.cache=containers.define("fonts","otl",otf.version,true)
otf.svgcache=containers.define("fonts","svg",otf.version,true)
otf.pngcache=containers.define("fonts","png",otf.version,true)
diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua
index 85fe1ae97..9f45408b1 100644
--- a/tex/generic/context/luatex/luatex-fonts.lua
+++ b/tex/generic/context/luatex/luatex-fonts.lua
@@ -257,7 +257,9 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then
loadmodule('font-vfc.lua')
- -- This is the bulk of opentype code.
+ -- This is the bulk of opentype code. The color and variable font support (as for
+ -- emoji) can (and might) actually go away here because it has never been used
+ -- outside context so in retrospect there was no need for it being generic.
loadmodule('font-otr.lua')
loadmodule('font-oti.lua')