diff options
author | Hans Hagen <pragma@wxs.nl> | 2021-07-22 19:30:29 +0200 |
---|---|---|
committer | Context Git Mirror Bot <phg@phi-gamma.net> | 2021-07-22 19:30:29 +0200 |
commit | ed85eb918354b77672bbe347c2afcfe2e0b6b7fb (patch) | |
tree | 9f3f5330a1c08b7aaccdf1c99963cd461310982f | |
parent | 215aeff4092b7483f4ac024d19984a37c381ba52 (diff) | |
download | context-ed85eb918354b77672bbe347c2afcfe2e0b6b7fb.tar.gz |
2021-07-22 19:14:00
31 files changed, 1356 insertions, 216 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index ddc6e4c94..c85382380 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{2021.07.21 19:51} +\newcontextversion{2021.07.22 19:11} %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 f51879ef6..4c02f23df 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{2021.07.21 19:51} +\edef\contextversion{2021.07.22 19:11} %D For those who want to use this: diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 668a2bb71..bc2a91dcf 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{2021.07.21 19:51} +\newcontextversion{2021.07.22 19:11} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index c49efc796..061a6651d 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{2021.07.21 19:51} +\edef\contextversion{2021.07.22 19:11} %D Kind of special: diff --git a/tex/context/base/mkiv/font-phb-imp-library.lua b/tex/context/base/mkiv/font-phb-imp-library.lua new file mode 100644 index 000000000..fe991b023 --- /dev/null +++ b/tex/context/base/mkiv/font-phb-imp-library.lua @@ -0,0 +1,498 @@ +if not modules then modules = { } end modules ['font-phb-imp-library'] = { + version = 1.000, -- 2020.01.08, + comment = "companion to font-txt.mkiv", + original = "derived from a prototype by Kai Eigner", + author = "Hans Hagen", -- so don't blame KE + copyright = "TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- The hb library comes in versions and the one I tested in 2016 was part of the inkscape +-- suite. In principle one can have incompatibilities due to updates but that is the nature +-- of a library. When a library ie expected one has better use the system version, if only +-- to make sure that different programs behave the same. +-- +-- The main reason for testing this approach was that when Idris was working on his fonts, +-- we wanted to know how different shapers deal with it and the hb command line program +-- could provide uniscribe output. For the context shaper uniscribe is the reference, also +-- because Idris started out with Volt a decade ago. +-- +-- We treat the lib as a black box as it should be. At some point Kai Eigner made an ffi +-- binding and that one was adapted to the plugin approach of context. It saved me the +-- trouble of looking at source files to figure it all out. Below is the adapted code. +-- +-- Keep in mind that this file is for mkiv only. It won't work in lmtx where instead of +-- ffi we use simple optional libraries with delayed bindings. In principle this mechanism +-- is generic but because other macropackages follow another route we don't spend time +-- on that code path here. + +local next, tonumber, pcall = next, tonumber, pcall +local reverse = table.reverse +local loaddata = io.loaddata + +local report = utilities.hb.report or print +local packtoutf32 = utilities.hb.helpers.packtoutf32 + +if not FFISUPPORTED or not ffi then + report("no ffi support") + return +elseif CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 then + report("no ffi support") + return +elseif not context then + return +end + +local harfbuzz = ffilib(os.name == "windows" and "libharfbuzz-0" or "libharfbuzz") + +if not harfbuzz then + report("no hb library found") + return +end + +-- jit.on() : on very long (hundreds of pages) it looks faster but +-- the normal font processor slows down ... this is consistent with +-- earlier observations that turning it on is often slower on these +-- one-shot tex runs (also because we don't use many math and/or +-- string helpers and therefore the faster vm of luajit gives most +-- benefits (given the patched hasher) + +-- Here is Kai's ffi mapping, a bit reorganized. We only define what we +-- need. I'm happy that Kai did the deciphering of the api that I could +-- then build upon. + +ffi.cdef [[ + +typedef struct hb_blob_t hb_blob_t ; + +typedef enum { + HB_MEMORY_MODE_DUPLICATE, + HB_MEMORY_MODE_READONLY, + HB_MEMORY_MODE_WRITABLE, + HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE +} hb_memory_mode_t ; + +typedef void (*hb_destroy_func_t) ( + void *user_data +) ; + +typedef struct hb_face_t hb_face_t ; + +typedef const struct hb_language_impl_t *hb_language_t ; + +typedef struct hb_buffer_t hb_buffer_t ; + +typedef enum { + HB_SCRIPT_COMMON, HB_SCRIPT_INHERITED, HB_SCRIPT_UNKNOWN, + + HB_SCRIPT_ARABIC, HB_SCRIPT_ARMENIAN, HB_SCRIPT_BENGALI, HB_SCRIPT_CYRILLIC, + HB_SCRIPT_DEVANAGARI, HB_SCRIPT_GEORGIAN, HB_SCRIPT_GREEK, + HB_SCRIPT_GUJARATI, HB_SCRIPT_GURMUKHI, HB_SCRIPT_HANGUL, HB_SCRIPT_HAN, + HB_SCRIPT_HEBREW, HB_SCRIPT_HIRAGANA, HB_SCRIPT_KANNADA, HB_SCRIPT_KATAKANA, + HB_SCRIPT_LAO, HB_SCRIPT_LATIN, HB_SCRIPT_MALAYALAM, HB_SCRIPT_ORIYA, + HB_SCRIPT_TAMIL, HB_SCRIPT_TELUGU, HB_SCRIPT_THAI, HB_SCRIPT_TIBETAN, + HB_SCRIPT_BOPOMOFO, HB_SCRIPT_BRAILLE, HB_SCRIPT_CANADIAN_SYLLABICS, + HB_SCRIPT_CHEROKEE, HB_SCRIPT_ETHIOPIC, HB_SCRIPT_KHMER, HB_SCRIPT_MONGOLIAN, + HB_SCRIPT_MYANMAR, HB_SCRIPT_OGHAM, HB_SCRIPT_RUNIC, HB_SCRIPT_SINHALA, + HB_SCRIPT_SYRIAC, HB_SCRIPT_THAANA, HB_SCRIPT_YI, HB_SCRIPT_DESERET, + HB_SCRIPT_GOTHIC, HB_SCRIPT_OLD_ITALIC, HB_SCRIPT_BUHID, HB_SCRIPT_HANUNOO, + HB_SCRIPT_TAGALOG, HB_SCRIPT_TAGBANWA, HB_SCRIPT_CYPRIOT, HB_SCRIPT_LIMBU, + HB_SCRIPT_LINEAR_B, HB_SCRIPT_OSMANYA, HB_SCRIPT_SHAVIAN, HB_SCRIPT_TAI_LE, + HB_SCRIPT_UGARITIC, HB_SCRIPT_BUGINESE, HB_SCRIPT_COPTIC, + HB_SCRIPT_GLAGOLITIC, HB_SCRIPT_KHAROSHTHI, HB_SCRIPT_NEW_TAI_LUE, + HB_SCRIPT_OLD_PERSIAN, HB_SCRIPT_SYLOTI_NAGRI, HB_SCRIPT_TIFINAGH, + HB_SCRIPT_BALINESE, HB_SCRIPT_CUNEIFORM, HB_SCRIPT_NKO, HB_SCRIPT_PHAGS_PA, + HB_SCRIPT_PHOENICIAN, HB_SCRIPT_CARIAN, HB_SCRIPT_CHAM, HB_SCRIPT_KAYAH_LI, + HB_SCRIPT_LEPCHA, HB_SCRIPT_LYCIAN, HB_SCRIPT_LYDIAN, HB_SCRIPT_OL_CHIKI, + HB_SCRIPT_REJANG, HB_SCRIPT_SAURASHTRA, HB_SCRIPT_SUNDANESE, HB_SCRIPT_VAI, + HB_SCRIPT_AVESTAN, HB_SCRIPT_BAMUM, HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, + HB_SCRIPT_IMPERIAL_ARAMAIC, HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, + HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, HB_SCRIPT_JAVANESE, HB_SCRIPT_KAITHI, + HB_SCRIPT_LISU, HB_SCRIPT_MEETEI_MAYEK, HB_SCRIPT_OLD_SOUTH_ARABIAN, + HB_SCRIPT_OLD_TURKIC, HB_SCRIPT_SAMARITAN, HB_SCRIPT_TAI_THAM, + HB_SCRIPT_TAI_VIET, HB_SCRIPT_BATAK, HB_SCRIPT_BRAHMI, HB_SCRIPT_MANDAIC, + HB_SCRIPT_CHAKMA, HB_SCRIPT_MEROITIC_CURSIVE, HB_SCRIPT_MEROITIC_HIEROGLYPHS, + HB_SCRIPT_MIAO, HB_SCRIPT_SHARADA, HB_SCRIPT_SORA_SOMPENG, HB_SCRIPT_TAKRI, + HB_SCRIPT_BASSA_VAH, HB_SCRIPT_CAUCASIAN_ALBANIAN, HB_SCRIPT_DUPLOYAN, + HB_SCRIPT_ELBASAN, HB_SCRIPT_GRANTHA, HB_SCRIPT_KHOJKI, HB_SCRIPT_KHUDAWADI, + HB_SCRIPT_LINEAR_A, HB_SCRIPT_MAHAJANI, HB_SCRIPT_MANICHAEAN, + HB_SCRIPT_MENDE_KIKAKUI, HB_SCRIPT_MODI, HB_SCRIPT_MRO, HB_SCRIPT_NABATAEAN, + HB_SCRIPT_OLD_NORTH_ARABIAN, HB_SCRIPT_OLD_PERMIC, HB_SCRIPT_PAHAWH_HMONG, + HB_SCRIPT_PALMYRENE, HB_SCRIPT_PAU_CIN_HAU, HB_SCRIPT_PSALTER_PAHLAVI, + HB_SCRIPT_SIDDHAM, HB_SCRIPT_TIRHUTA, HB_SCRIPT_WARANG_CITI, HB_SCRIPT_AHOM, + HB_SCRIPT_ANATOLIAN_HIEROGLYPHS, HB_SCRIPT_HATRAN, HB_SCRIPT_MULTANI, + HB_SCRIPT_OLD_HUNGARIAN, HB_SCRIPT_SIGNWRITING, HB_SCRIPT_ADLAM, + HB_SCRIPT_BHAIKSUKI, HB_SCRIPT_MARCHEN, HB_SCRIPT_OSAGE, HB_SCRIPT_TANGUT, + HB_SCRIPT_NEWA, HB_SCRIPT_MASARAM_GONDI, HB_SCRIPT_NUSHU, HB_SCRIPT_SOYOMBO, + HB_SCRIPT_ZANABAZAR_SQUARE, HB_SCRIPT_DOGRA, HB_SCRIPT_GUNJALA_GONDI, + HB_SCRIPT_HANIFI_ROHINGYA, HB_SCRIPT_MAKASAR, HB_SCRIPT_MEDEFAIDRIN, + HB_SCRIPT_OLD_SOGDIAN, HB_SCRIPT_SOGDIAN, HB_SCRIPT_ELYMAIC, + HB_SCRIPT_NANDINAGARI, HB_SCRIPT_NYIAKENG_PUACHUE_HMONG, HB_SCRIPT_WANCHO, + + HB_SCRIPT_INVALID, _HB_SCRIPT_MAX_VALUE, _HB_SCRIPT_MAX_VALUE_SIGNED, +} hb_script_t ; + +typedef enum { + HB_DIRECTION_INVALID, + HB_DIRECTION_LTR, + HB_DIRECTION_RTL, + HB_DIRECTION_TTB, + HB_DIRECTION_BTT +} hb_direction_t ; + +typedef int hb_bool_t ; + +typedef uint32_t hb_tag_t ; + +typedef struct hb_feature_t { + hb_tag_t tag; + uint32_t value; + unsigned int start; + unsigned int end; +} hb_feature_t ; + +typedef struct hb_font_t hb_font_t ; + +typedef uint32_t hb_codepoint_t ; +typedef int32_t hb_position_t ; +typedef uint32_t hb_mask_t ; + +typedef union _hb_var_int_t { + uint32_t u32; + int32_t i32; + uint16_t u16[2]; + int16_t i16[2]; + uint8_t u8[4]; + int8_t i8[4]; +} hb_var_int_t ; + +typedef struct hb_glyph_info_t { + hb_codepoint_t codepoint ; + hb_mask_t mask ; + uint32_t cluster ; + /*< private >*/ + hb_var_int_t var1 ; + hb_var_int_t var2 ; +} hb_glyph_info_t ; + +typedef struct hb_glyph_position_t { + hb_position_t x_advance ; + hb_position_t y_advance ; + hb_position_t x_offset ; + hb_position_t y_offset ; + /*< private >*/ + hb_var_int_t var ; +} hb_glyph_position_t ; + +const char * hb_version_string ( + void +) ; + +hb_blob_t * hb_blob_create ( + const char *data, + unsigned int length, + hb_memory_mode_t mode, + void *user_data, + hb_destroy_func_t destroy +) ; + +void hb_blob_destroy ( + hb_blob_t *blob +) ; + +hb_face_t * hb_face_create ( + hb_blob_t *blob, + unsigned int index +) ; + +void hb_face_destroy ( + hb_face_t *face +) ; + +hb_language_t hb_language_from_string ( + const char *str, + int len +) ; + +void hb_buffer_set_language ( + hb_buffer_t *buffer, + hb_language_t language +) ; + +hb_script_t hb_script_from_string ( + const char *s, + int len +) ; + +void hb_buffer_set_script ( + hb_buffer_t *buffer, + hb_script_t script +) ; + +hb_direction_t hb_direction_from_string ( + const char *str, + int len +) ; + +void hb_buffer_set_direction ( + hb_buffer_t *buffer, + hb_direction_t direction +) ; + +hb_bool_t hb_feature_from_string ( + const char *str, + int len, + hb_feature_t *feature +) ; + +hb_bool_t hb_shape_full ( + hb_font_t *font, + hb_buffer_t *buffer, + const hb_feature_t *features, + unsigned int num_features, + const char * const *shaper_list +) ; + + +hb_buffer_t * hb_buffer_create ( + void +) ; + +void hb_buffer_destroy ( + hb_buffer_t *buffer +) ; + +void hb_buffer_add_utf8 ( + hb_buffer_t *buffer, + const char *text, + int text_length, + unsigned int item_offset, + int item_length +) ; + +void hb_buffer_add_utf32 ( + hb_buffer_t *buffer, + const char *text, + int text_length, + unsigned int item_offset, + int item_length +) ; + +void hb_buffer_add ( + hb_buffer_t *buffer, + hb_codepoint_t codepoint, + unsigned int cluster +) ; + +unsigned int hb_buffer_get_length ( + hb_buffer_t *buffer +) ; + +hb_glyph_info_t * hb_buffer_get_glyph_infos ( + hb_buffer_t *buffer, + unsigned int *length +) ; + +hb_glyph_position_t *hb_buffer_get_glyph_positions ( + hb_buffer_t *buffer, + unsigned int *length +) ; + +void hb_buffer_reverse ( + hb_buffer_t *buffer +) ; + +void hb_buffer_reset ( + hb_buffer_t *buffer +) ; + +void hb_buffer_guess_segment_properties ( + hb_buffer_t *buffer +) ; + +hb_font_t * hb_font_create ( + hb_face_t *face +) ; + +void hb_font_destroy ( + hb_font_t *font +) ; + +void hb_font_set_scale ( + hb_font_t *font, + int x_scale, + int y_scale +) ; + +void hb_ot_font_set_funcs ( + hb_font_t *font +) ; + +unsigned int hb_face_get_upem ( + hb_face_t *face +) ; + +const char ** hb_shape_list_shapers ( + void +); +]] + +-- The library must be somewhere accessible. The calls to the library are similar to +-- the ones in the prototype but we organize things a bit differently. I tried to alias +-- the functions in the harfbuzz namespace (luajittex will optimize this anyway but +-- normal luatex not) but it crashes luajittex so I revered that. + +do + + local l = harfbuzz.hb_shape_list_shapers() + local s = { } + + for i=0,9 do + local str = l[i] + if str == ffi.NULL then + break + else + s[#s+1] = ffi.string(str) + end + end + + report("using hb library version %a, supported shapers: %,t",ffi.string(harfbuzz.hb_version_string()),s) + +end + +-- we don't want to store userdata in the public data blob + +local fontdata = fonts.hashes.identifiers + +local loaded = { } +local shared = { } +local featured = { } + +local function loadfont(font) + local tfmdata = fontdata[font] + local resources = tfmdata.resources + local filename = resources.filename + local instance = shared[filename] + if not instance then + local wholefont = io.loaddata(filename) + local wholeblob = ffi.gc(harfbuzz.hb_blob_create(wholefont,#wholefont,0,nil,nil),harfbuzz.hb_blob_destroy) + local wholeface = ffi.gc(harfbuzz.hb_face_create(wholeblob,font),harfbuzz.hb_face_destroy) + local scale = harfbuzz.hb_face_get_upem(wholeface) + instance = ffi.gc(harfbuzz.hb_font_create(wholeface),harfbuzz.hb_font_destroy) + harfbuzz.hb_font_set_scale(instance,scale,scale) + harfbuzz.hb_ot_font_set_funcs(instance) + shared[filename] = instance + end + return instance +end + +local function loadfeatures(data) + local featureset = data.featureset or { } + local feature = ffi.new("hb_feature_t[?]",#featureset) + local featurespec = feature[0] + local noffeatures = 0 + for i=1,#featureset do + local f = featureset[i] + harfbuzz.hb_feature_from_string(f,#f,feature[noffeatures]) + noffeatures = noffeatures + 1 + end + return { + noffeatures = #featureset, + featureblob = feature, + featurespec = featurespec, + } +end + +local function crap(t) + return ffi.new("const char *[?]", #t, t) +end + +local shapers = { + native = crap { "ot", "uniscribe", "fallback" }, + uniscribe = crap { "uniscribe", "ot", "fallback" }, + -- uniscribe = crap { "uniscribe", "fallback" }, -- stalls without fallback when no uniscribe present + fallback = crap { "fallback" }, +} + +-- Reusing a buffer doesn't make a difference in performance so we forget +-- about it and keep things simple. Todo: check if using locals makes sense. + +function utilities.hb.methods.library(font,data,rlmode,text,leading,trailing) + local instance = loaded[font] + if not instance then + instance = loadfont(font) + loaded[font] = instance + end + -- todo: dflt -> DFLT ? + -- todo: whatever -> Whatever ? + local language = data.language or "dflt" + local script = data.script or "dflt" + local direction = rlmode < 0 and "rtl" or "ltr" + local shaper = shapers[data.shaper] + local featurehash = data.features + local featuredata = featured[featurehash] + if not featuredata then + featuredata = loadfeatures(data) + featured[featurehash] = featuredata + end + + local buffer = ffi.gc(harfbuzz.hb_buffer_create(),harfbuzz.hb_buffer_destroy) + + -- if false then + -- -- i have no time to look into this now but something like this should + -- -- be possible .. it probably doesn't make a difference in performance + -- local n = 0 -- here we also start at 0 + -- if leading then + -- harfbuzz.hb_buffer_add(buffer,[todo: 0x20],n) + -- end + -- for i=1,#text do + -- n = n + 1 + -- harfbuzz.hb_buffer_add(buffer,[todo: text[i] ],n) + -- end + -- if trailing then + -- n = n + 1 + -- harfbuzz.hb_buffer_add(buffer,[todo: 0x20 ],n) + -- end + -- else + -- maybe also utf 8 clusters here like on the command line but i have no time + -- to figure that out + text = packtoutf32(text,leading,trailing) + local size = #text/4 + text = text .. "\000\000\000\000\000\000\000\000" -- trial and error: avoid crash + harfbuzz.hb_buffer_add_utf32(buffer,text,#text,0,size) + -- end + + -- maybe: hb_buffer_set_segment_properties(buffer,...) + + harfbuzz.hb_buffer_set_language(buffer,harfbuzz.hb_language_from_string(language,#language)) + harfbuzz.hb_buffer_set_script(buffer,harfbuzz.hb_script_from_string(script,#script)) + harfbuzz.hb_buffer_set_direction(buffer,harfbuzz.hb_direction_from_string(direction,#direction)) + + harfbuzz.hb_buffer_guess_segment_properties(buffer) -- why is this needed (we already set them) + harfbuzz.hb_shape_full(instance,buffer,featuredata.featurespec,featuredata.noffeatures,shaper) + + if rlmode < 0 then + harfbuzz.hb_buffer_reverse(buffer) + end + + local size = harfbuzz.hb_buffer_get_length(buffer) + local infos = harfbuzz.hb_buffer_get_glyph_infos(buffer, nil) + local positions = harfbuzz.hb_buffer_get_glyph_positions(buffer, nil) + + local result = { } + for i=1,size do + local info = infos[i-1] + local position = positions[i-1] + result[i] = { + info.codepoint, + info.cluster, + position.x_offset, + position.y_offset, + position.x_advance, + position.y_advance, + } + end + -- inspect(result) + return result + +end diff --git a/tex/context/base/mkiv/mlib-pps.lua b/tex/context/base/mkiv/mlib-pps.lua index 122ca6f99..c80777f5f 100644 --- a/tex/context/base/mkiv/mlib-pps.lua +++ b/tex/context/base/mkiv/mlib-pps.lua @@ -1463,6 +1463,8 @@ local function tr_process(object,prescript,before,after) sp_specs = concat(sp_specs,",") definemultitonecolor(sp_name,sp_specs,"","") sp_type = "named" + elseif sp_type == "named" then + cs = { 1 } -- factor 1 end if sp_type == "named" then -- we might move this to another namespace .. also, named can be a spotcolor diff --git a/tex/context/base/mkiv/page-imp.mkiv b/tex/context/base/mkiv/page-imp.mkiv index 829ed24f4..ec249d652 100644 --- a/tex/context/base/mkiv/page-imp.mkiv +++ b/tex/context/base/mkiv/page-imp.mkiv @@ -102,6 +102,15 @@ \installshipoutmethod \v!none {\page_shipouts_ignore} +% \setuppaper[method=rotate,rotation=15] \showframe +% \starttext \dorecurse{10}{\input knuth\endgraf} \stoptext + +\installshipoutmethod\v!rotate + {\page_shipouts_rotate} + +\protected\def\page_shipouts_rotate#1% + {\invokepagehandler\v!normal{\rotate[\c!rotation=\rootlayouttargetparameter\c!rotation]{#1}}} + % extension mechanism \newcount\c_page_boxes_flush_n % set at the lua end diff --git a/tex/context/base/mkiv/publ-imp-aps-prb.mkvi b/tex/context/base/mkiv/publ-imp-aps-prb.mkvi new file mode 100644 index 000000000..19735b949 --- /dev/null +++ b/tex/context/base/mkiv/publ-imp-aps-prb.mkvi @@ -0,0 +1,40 @@ +%D \module +%D [ file=publ-imp-aps-prb, +%D version=2015.03.22, +%D title=Phys. Rev. B APS bibliography style, +%D subtitle=Publications, +%D author=Alan Braslau and 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 therefore copyrighted +%D by \PRAGMA. See mreadme.pdf for details. + +\startbtxrenderingdefinitions[aps-prb] + +\loadbtxdefinitionfile[aps] + +\setupbtxlist + [aps] + [\c!alternative=\v!paragraph, + \c!width=\v!auto, + \c!distance=\zeropoint, + \c!numberalign=\v!flushright] + +\setupbtx + [aps:list:numbering:num] + [\c!command=\high, + \c!left=, + \c!right=, + \c!stopper=] + +\setupbtx + [aps:cite:num] + [\c!command=\high, + \c!left=, + \c!right=] + +%\setupbtx +% [\c!specification=aps] + +\stopbtxrenderingdefinitions diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 82fa2f6a3..96866e655 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 26b23cda0..8013acd66 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index 70b47d75d..3fedf6b5b 100644 --- a/tex/context/base/mkxl/cont-new.mkxl +++ b/tex/context/base/mkxl/cont-new.mkxl @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.07.21 19:51} +\newcontextversion{2021.07.22 19:11} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl index 67ecc671c..b517cf7b9 100644 --- a/tex/context/base/mkxl/context.mkxl +++ b/tex/context/base/mkxl/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \immutable\edef\contextformat {\jobname} -\immutable\edef\contextversion{2021.07.21 19:51} +\immutable\edef\contextversion{2021.07.22 19:11} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error diff --git a/tex/context/base/mkxl/core-uti.lua b/tex/context/base/mkxl/core-uti.lmt index 887ef9a75..1bb50060d 100644 --- a/tex/context/base/mkxl/core-uti.lua +++ b/tex/context/base/mkxl/core-uti.lmt @@ -348,30 +348,6 @@ function job.loadother(filename) statistics.stoptiming(_load_) end --- function job.keep(filename) --- local suffix = file.suffix(filename) --- local base = file.removesuffix(filename) --- if suffix == "" then --- suffix = "tuc" --- end --- for i=1,10 do --- local tmpname = format("%s-%s-%02d.tmp",base,suffix,i) --- if lfs.isfile(tmpname) then --- os.remove(tmpname) --- report_passes("removing %a",tmpname) --- end --- end --- if lfs.isfile(filename) then --- local tmpname = format("%s-%s-%02d.tmp",base,suffix,environment.currentrun or 1) --- report_passes("copying %a into %a",filename,tmpname) --- file.copy(filename,tmpname) --- else --- report_passes("no file %a, nothing kept",filename) --- end --- end - --- eventually this will end up in strc-ini - statistics.register("startup time", function() return statistics.elapsedseconds(statistics,"including runtime option file processing") end) @@ -393,17 +369,16 @@ statistics.register("jobdata time",function() end) statistics.register("callbacks", function() - local c_internal = status.callbacks or 0 - local c_file = status.indirect_callbacks or 0 - local c_direct = status.direct_callbacks or 0 - local c_late = backends.getcallbackstate().count - local c_function = status.function_callbacks or 0 - local c_total = c_internal + c_file + c_direct + c_late + c_function - local n_pages = structures.pages.nofpages or 0 - local c_average = n_pages > 0 and math.round(c_total/n_pages) or 0 - local result = format ( - "internal: %s, file: %s, direct: %s, late: %s, function %s, total: %s (%s per page)", - c_internal, c_file, c_direct, c_late, c_function, c_total, c_average + local backend = backends.getcallbackstate() + local frontend = status.getcallbackstate() + local pages = structures.pages.nofpages or 0 + local total = frontend.count + backend.count + local average = pages > 0 and math.round(total/pages) or 0 + local result = format ( + "file: %s, saved: %s, direct: %s, function: %s, value: %s, message: %s, bytecode: %s, late %s, total: %s (%s per page)", + frontend.file, frontend.saved, frontend.direct, frontend["function"], + frontend.value, frontend.message, frontend.bytecode, backend.count, + total, average ) statistics.callbacks = function() return result @@ -417,15 +392,6 @@ statistics.register("randomizer", function() end end) --- a sort of joke (for ctx meeting) - --- local kg_per_watt_per_second = 1 / 15000000 --- local watts_per_core = 50 --- local speedup_by_other_engine = 1.2 --- local used_wood_factor = watts_per_core * kg_per_watt_per_second / speedup_by_other_engine --- local used_wood_factor = (50 / 15000000) / 1.2 - - function statistics.formatruntime(runtime) if not environment.initex then -- else error when testing as not counters yet -- stoptiming(statistics) -- to be sure @@ -448,9 +414,10 @@ function statistics.formatruntime(runtime) end implement { - name = "savevariable", + name = "savecurrentvalue", + public = true, actions = job.variables.save, - arguments = "2 strings", + arguments = { "csname", "argument" }, } implement { diff --git a/tex/context/base/mkxl/meta-imp-kindergarten.mkxl b/tex/context/base/mkxl/meta-imp-kindergarten.mkxl new file mode 100644 index 000000000..6b2402bf0 --- /dev/null +++ b/tex/context/base/mkxl/meta-imp-kindergarten.mkxl @@ -0,0 +1,118 @@ +%D \module +%D [ file=meta-imp-kindergarten, +%D version=2020.00.00, +%D title=\METAPOST\ Graphics, +%D subtitle=Kindergarten Math, +%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. + +% \nopdfcompression + +%D For Arthur, who told me that about the urban legend that \CONTEXT\ can do only +%D kindergarten math. Somehow I'd forgotten top add this to the distribution + +\startMPcalculation{simplefun} + + pen KindergartenPen ; KindergartenPen := pencircle scaled 1 ; + + % 10 x 10 grid + + vardef KindergartenEqual = + draw image + ( + draw (2,6) -- (9,5) ; + draw (2,4) -- (8,3) ; + ) + shifted (0,-2) + withpen KindergartenPen + withcolor "KindergartenEqual" + enddef ; + vardef KindergartenPlus = + draw image + ( + draw (1,4) -- (9,5) ; + draw (4,1) -- (5,8) ; + ) + shifted (0,-2) + withpen KindergartenPen + withcolor "KindergartenPlus" + enddef ; + vardef KindergartenMinus = + draw image + ( + draw (1,5) -- (9,4) ; + ) + shifted (0,-2) + withpen KindergartenPen + withcolor "KindergartenMinus" + enddef ; + vardef KindergartenTimes = + draw image + ( + draw (2,1) -- (9,8) ; + draw (8,1) -- (2,8) ; + ) + shifted (0,-2) + withpen KindergartenPen + withcolor "KindergartenTimes" + enddef ; + vardef KindergartenDivided = + draw image + ( + draw (2,1) -- (8,9) ; + ) + shifted (0,-2) + withpen KindergartenPen + withcolor "KindergartenDivided" + enddef ; + + lmt_registerglyphs [ + name = "kindergarten", + units = 10, + % usecolor = true, + width = 10, + height = 8, + depth = 2, + ] ; + + lmt_registerglyph [ category = "kindergarten", unicode = "0x003D", + code = "KindergartenEqual" + ] ; + lmt_registerglyph [ category = "kindergarten", unicode = "0x002B", + code = "KindergartenPlus" + ] ; + lmt_registerglyph [ category = "kindergarten", unicode = "0x2212", + code = "KindergartenMinus" + ] ; + lmt_registerglyph [ category = "kindergarten", unicode = "0x00D7", + code = "KindergartenTimes" + ] ; + lmt_registerglyph [ category = "kindergarten", unicode = "0x002F", + code = "KindergartenDivided" + ] ; + +\stopMPcalculation + +\definecolor[KindergartenEqual] [darkgreen] +\definecolor[KindergartenPlus] [darkred] +\definecolor[KindergartenMinus] [darkred] +\definecolor[KindergartenTimes] [darkblue] +\definecolor[KindergartenDivided][darkblue] + +\continueifinputfile{meta-imp-kindergarten.mkxl} + +\definefontfeature + [mathextra] + [metapost=kindergarten] + +\setupbodyfont[dejavu] + +\startTEXpage[offset=10pt] + $ y = 2 \times x + a - b / 3 $ \par + \hfill \infofont{kindergarten math} +\stopTEXpage diff --git a/tex/context/base/mkxl/meta-imp-placeholders.mkxl b/tex/context/base/mkxl/meta-imp-placeholders.mkxl new file mode 100644 index 000000000..aa48b814c --- /dev/null +++ b/tex/context/base/mkxl/meta-imp-placeholders.mkxl @@ -0,0 +1,83 @@ +%D \module +%D [ file=meta-imp-placeholders, +%D version=2021.02.01, +%D title=\METAPOST\ Graphics, +%D subtitle=Missing Glyph Placeholders, +%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 drop in for the already existing placeholder function. It could be made +%D more clever by hashing similar shapes but as this is mostly a diagnostic feature +%D we go a quick an ddirty two dimensional array. + +%D It is now mostly a file one can run to get an idea what the replace macro triggers +%D so I've added it to the distribution. + +% \startMPcalculation{simplefun} +% loadfile("mp-miss.mpxl") ; +% \stopMPcalculation +% +% \startluacode +% +% local chardata = characters.data +% local fontdata = fonts.hashes.identifiers +% local mapping = fonts.checkers.mapping +% +% function fonts.checkers.placeholder(font,char) +% local category = chardata[char].category or "lu" -- todo: unknown +% local fakedata = mapping[category] +% local tfmdata = fontdata[font] +% local units = tfmdata.parameters.units or 1000 +% local slant = (tfmdata.parameters.slant or 0)/65536 +% local scale = units/1000 +% local rawdata = tfmdata.shared and tfmdata.shared.rawdata +% local weight = (rawdata and rawdata.metadata and rawdata.metadata.pfmweight or 400)/400 +% local specification = { +% code = "MissingGlyph", +% scale = scale, +% slant = slant, +% weight = weight, +% namespace = font, +% shapes = { { shape = fakedata[1], color = fakedata[2] } }, +% } +% fonts.helpers.setmetaglyphs("missing", font, char, specification) +% end +% +% \stopluacode + +%D We enable the checker: + +% \enabletrackers[fonts.missing=replace] + +\replacemissingcharacters + +\continueifinputfile{meta-imp-placeholders.mkxl} + +% \enableexperiments[fonts.compact] + +% \showglyphs + +\startbuffer + \startlines[before=,after=] + \strut {\tf test \char 12345\ test \char 12346\ test} + \strut {\bf test \char 12345\ test \char 12346\ test} + \strut {\it test \char 12345\ test \char 12346\ test} + \strut {\bi test \char 12345\ test \char 12346\ test} + \strut {test ὀ ρ φ α ν ῖ ο ς test} + \stoplines +\stopbuffer + +\starttext + \startTEXpage[offset=2pt,strut=no] + \getbuffer + \switchtobodyfont[pagella] + \getbuffer + \switchtobodyfont[dejavu] + \getbuffer + \stopTEXpage +\stoptext diff --git a/tex/context/base/mkxl/meta-imp-txt.lmt b/tex/context/base/mkxl/meta-imp-txt.lmt new file mode 100644 index 000000000..e4b88bd36 --- /dev/null +++ b/tex/context/base/mkxl/meta-imp-txt.lmt @@ -0,0 +1,116 @@ +if not modules then modules = { } end modules ['meta-imp-txt'] = { + version = 1.001, + comment = "companion to meta-imp-txt.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +local setmetatableindex = table.setmetatableindex + +local texset = tex.set + +local scan = mp.scan +local scannumeric = scan.numeric +local scaninteger = scan.integer +local scanboolean = scan.boolean +local scanstring = scan.string + +local expandmacro = token.expandmacro -- todo + +local bpfactor = number.dimenfactors.bp + +local metapost = metapost +metapost.parshapes = { } + +local parshapes = { } +local properties = { } + +-- initialize shapes to 0 hsize + +function metapost.parshapes.reset() + parshapes = { } + properties = { } +end + +function metapost.parshapes.next() + properties = { } + parshapes[#parshapes+1] = properties +end + +function metapost.parshapes.inspect() + inspect(parshapes) +end + +function metapost.parshapes.getshape(n) + return (parshapes and parshapes[n]) or parshapes or nil +end + +function metapost.parshapes.get(index,name) + local v = parshapes[index][name] + if type(v) == "boolean" then + context(v and 1 or 0) + else + context(v) + end +end + +function metapost.parshapes.wholeshape() -- maybe just collect them earlier + local t, n = { }, 0 + for i=1,#parshapes do + local s = parshapes[i].shape + if s then + for i=1,#s do + n = n + 1 + t[n] = s[i] + end + end + end + if n > 0 then + texset("parshape",t) + end +end + +metapost.registerscript("setparshapeproperty", function() + local k = scanstring() + if k == "line" then + local entry = properties.shape[scannumeric()] + local indent = scannumeric() / bpfactor + local width = scannumeric() / bpfactor + entry[1] = indent + entry[2] = width + elseif k == "lines" then + properties.lines = scaninteger() + properties.shape = setmetatableindex(function(t,k) + local v = { 0, properties.width or 0 } + t[k] = v + return v + end) + elseif k == "first" then + properties[k] = scanboolean() + elseif k == "inspect" then + inspect(properties) + else + properties[k] = scannumeric() / bpfactor + end +end) + +interfaces.implement { + name = "setparagraphmetashape", + public = true, + protected = true, + arguments = "optional", + actions = function(list) + if list and list ~= "" then + list = utilities.parsers.settings_to_array(list) + if #list > 0 then + metapost.parshapes.reset() + for i=1,#list do + metapost.parshapes.next() + expandmacro("spac_shapes_calculate","{"..list[i].."}") + end + metapost.parshapes.wholeshape() + end + end + end +} diff --git a/tex/context/base/mkxl/mlib-pps.lmt b/tex/context/base/mkxl/mlib-pps.lmt index cea8a179d..19535b070 100644 --- a/tex/context/base/mkxl/mlib-pps.lmt +++ b/tex/context/base/mkxl/mlib-pps.lmt @@ -1492,6 +1492,8 @@ local function tr_process(object,prescript,before,after) sp_specs = concat(sp_specs,",") definemultitonecolor(sp_name,sp_specs,"","") sp_type = "named" + elseif sp_type == "named" then + cs = { 1 } -- factor 1 end if sp_type == "named" then -- we might move this to another namespace .. also, named can be a spotcolor diff --git a/tex/context/base/mkxl/page-imp.mkxl b/tex/context/base/mkxl/page-imp.mkxl index 4ee7c159b..676313029 100644 --- a/tex/context/base/mkxl/page-imp.mkxl +++ b/tex/context/base/mkxl/page-imp.mkxl @@ -100,6 +100,15 @@ \installshipoutmethod \v!none {\page_shipouts_ignore} +% \setuppaper[method=rotate,rotation=15] \showframe +% \starttext \dorecurse{10}{\input knuth\endgraf} \stoptext + +\installshipoutmethod\v!rotate + {\page_shipouts_rotate} + +\protected\def\page_shipouts_rotate#1% + {\invokepagehandler\v!normal{\rotate[\c!rotation=\rootlayouttargetparameter\c!rotation]{#1}}} + % extension mechanism \newcount\c_page_boxes_flush_n % set at the lua end diff --git a/tex/context/base/mkxl/typo-bld.lmt b/tex/context/base/mkxl/typo-bld.lmt index 9bd5172e7..d9cd78385 100644 --- a/tex/context/base/mkxl/typo-bld.lmt +++ b/tex/context/base/mkxl/typo-bld.lmt @@ -176,7 +176,7 @@ local function processor(head,followed_by_display) -- todo: not again in otr so we need to flag if enabled then starttiming(parbuilders) - head = actions(head,followed_by_display) + head = tonode(actions(tonut(head),followed_by_display)) stoptiming(parbuilders) return head else diff --git a/tex/context/modules/common/s-abbreviations-mixed.mkiv b/tex/context/modules/common/s-abbreviations-mixed.mkiv deleted file mode 100644 index d5294fd56..000000000 --- a/tex/context/modules/common/s-abbreviations-mixed.mkiv +++ /dev/null @@ -1,28 +0,0 @@ -%D \module -%D [ file=s-abbreviations-mixed, % was: s-abr-04 -%D version=1996.01.01, -%D title=\CONTEXT\ Style File, -%D subtitle=General Abbreviations Mixed, -%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. - -\unprotect - -\setupsorting - [logo] - [\c!style=\font_style_pseudoMixedCapped] - -\protect - -\startmodule[abbreviations-mixed] - -\usemodule[abbreviations-logos] -\usemodule[abbreviations-extras] - -\stopmodule - diff --git a/tex/context/modules/common/s-abbreviations-pseudocaps.mkiv b/tex/context/modules/common/s-abbreviations-pseudocaps.mkiv deleted file mode 100644 index fa8606a7b..000000000 --- a/tex/context/modules/common/s-abbreviations-pseudocaps.mkiv +++ /dev/null @@ -1,30 +0,0 @@ -%D \module -%D [ file= s-abbreviations-pseudocaps, % was: s-abr-01 -%D version=1996.01.01, -%D title=\CONTEXT\ Style File, -%D subtitle=General Abbreviations Pseudocaps, -%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. - -\unprotect - -\setupsorting - [logo] - [\c!style=\v!capital] - -\setupcapitals - [\c!title=\v!no] - -\protect - -\startmodule[abbreviations-pseudocaps] - -\usemodule[abbreviations-logos] -\usemodule[abbreviations-extras] - -\stopmodule diff --git a/tex/context/modules/common/s-abbreviations-smallcaps.mkiv b/tex/context/modules/common/s-abbreviations-smallcaps.mkiv deleted file mode 100644 index 2ce86ca33..000000000 --- a/tex/context/modules/common/s-abbreviations-smallcaps.mkiv +++ /dev/null @@ -1,31 +0,0 @@ -%D \module -%D [ file= s-abbreviations-smallcaps, % was: s-abr-02 -%D version=1996.01.01, -%D title=\CONTEXT\ Style File, -%D subtitle=General Abbreviations Smallcaps, -%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. - -\unprotect - -\setupsorting - [logo] - [\c!style=\v!smallcaps] - -\setupcapitals - [\c!title=\v!no] - -\protect - -\startmodule[abbreviations-smallcaps] - -\usemodule[abbreviations-logos] -\usemodule[abbreviations-extras] - -\stopmodule - diff --git a/tex/context/modules/common/s-abbreviations-words.mkiv b/tex/context/modules/common/s-abbreviations-words.mkiv deleted file mode 100644 index 2b7d7cedc..000000000 --- a/tex/context/modules/common/s-abbreviations-words.mkiv +++ /dev/null @@ -1,28 +0,0 @@ -%D \module -%D [ file= s-abbreviations-words, % was: s-abr-32 -%D version=1998.08.10, -%D title=\CONTEXT\ Style File, -%D subtitle=General Abbreviations Words, -%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. - -\unprotect - -\setupsorting - [logo] - [\c!style=\v!WORD] - -\protect - -\startmodule[abbreviations-words] - -\usemodule[abbreviations-logos] -\usemodule[abbreviations-extras] - -\stopmodule - diff --git a/tex/context/modules/common/s-abbreviations-extras.tex b/tex/context/modules/mkiv/s-abbreviations-extras.tex index 7ee6e1553..7ee6e1553 100644 --- a/tex/context/modules/common/s-abbreviations-extras.tex +++ b/tex/context/modules/mkiv/s-abbreviations-extras.tex diff --git a/tex/context/modules/common/s-abbreviations-logos.tex b/tex/context/modules/mkiv/s-abbreviations-logos.tex index dfac57f0a..dfac57f0a 100644 --- a/tex/context/modules/common/s-abbreviations-logos.tex +++ b/tex/context/modules/mkiv/s-abbreviations-logos.tex diff --git a/tex/context/modules/common/s-obsolete-tokens.mkiv b/tex/context/modules/mkiv/s-obsolete-tokens.mkiv index 117282a60..117282a60 100644 --- a/tex/context/modules/common/s-obsolete-tokens.mkiv +++ b/tex/context/modules/mkiv/s-obsolete-tokens.mkiv diff --git a/tex/context/modules/mkiv/s-physics-units.lua b/tex/context/modules/mkiv/s-physics-units.lua new file mode 100644 index 000000000..008320858 --- /dev/null +++ b/tex/context/modules/mkiv/s-physics-units.lua @@ -0,0 +1,86 @@ +if not modules then modules = { } end modules ['s-physics-units'] = { + version = 1.001, + comment = "companion to s-physics-units.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +moduledata.physics = moduledata.physics or { } +moduledata.physics.units = moduledata.physics.units or { } + +local tables = physics.units.tables +local units = tables.units +local shortcuts = tables.shortcuts + +local HL = context.HL +local NC = context.NC +local NR = context.NR + +local function typeset(list,followup,name,category) + if list then + if followup then + context.TB() + end + if category then + HL() + NC() + context.rlap(category .. ":" .. name) + NC() + NC() + NR() + HL() + end + for k, v in table.sortedhash(list) do + NC() + context(k) + NC() + if isunit then + context(v) + else + context.type(v) + end + NC() + if name == "units" or name == "symbols" or name == "packaged" then + context.unittext(v) + elseif name == "prefixes" then + context.prefixtext(v) + elseif name == "operators" then + context.operatortext(v) + elseif name == "suffixes" then + context.suffixtext(v) + end + NC() + NR() + end + if category and name then + HL() + end + end +end + +function moduledata.physics.units.showlist(name) + specification = interfaces.checkedspecification(specification) + context.starttabulate { "|lT|l|c|" } + local name = specification.name + if name and name ~= "" then + local first, second = string.match(name,"(.-):(.-)") -- [units|shortcuts]:[units|...] + if first then + typeset(tables[first] and tables[first][second],false) + else + typeset(units[name],false) + typeset(shortcuts[name],true) + end + else + local done = false + for what, list in table.sortedhash(units) do + typeset(list,done,what,"units") + done = true + end + for what, list in table.sortedhash(shortcuts) do + typeset(list,done,what,"shortcuts") + done = true + end + end + context.stoptabulate() +end diff --git a/tex/context/modules/mkiv/s-version.mkiv b/tex/context/modules/mkiv/s-version.mkiv new file mode 100644 index 000000000..63005aa33 --- /dev/null +++ b/tex/context/modules/mkiv/s-version.mkiv @@ -0,0 +1,123 @@ +%D \module +%D [ file=s-version, +%D version=2011.07.28, +%D title=\CONTEXT\ Version Pictogram, +%D subtitle=Basics, +%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 an oldie that we use to generate a pictogram that reflects the current +%D version. + +\startMPextensions +vardef context_version(expr variant, mark, year, month, day, hours, minutes, seconds) = + + image ( + + interim overloadmode := 0; + + save angle, min, max, mk, yr, mo, da, ho, mi, se, max_mk, max_yr, max_mo, max_da, max_ho, max_mi, max_se ; + + numeric angle, delta ; pair min, max ; angle := 360/7.25 ; delta := (360-7*angle)/7 ; min := (0,10) ; max := (0,100) ; + + numeric mk, max_mk ; max_mk := 8 ; mk := if (mark <= 0) or (mark > max_mk) : max_mk else : mark fi ; + numeric yr, max_yr ; max_yr := 2050 ; yr := if (year <= 2000) or (year > max_yr) : max_yr else : year fi ; + numeric mo, max_mo ; max_mo := 12 ; mo := if (month <= 0) or (month > max_mo) : max_mo else : month fi ; + numeric da, max_da ; max_da := 31 ; da := if (day <= 0) or (day > max_da) : max_da else : day fi ; + numeric ho, max_ho ; max_ho := 24 ; ho := if (hours <= 0) or (hours > max_ho) : max_ho else : hours fi ; + numeric mi, max_mi ; max_mi := 60 ; mi := if (minutes <= 0) or (minutes > max_mi) : max_mi else : minutes fi ; + numeric se, max_se ; max_se := 60 ; se := if (seconds <= 0) or (seconds > max_se) : max_se else : seconds fi ; + + max_da := if (mo = 2) : 28 elseif (mo = 4) or (mo = 6) or (mo = 9) or (mo = 11) : 30 else : 31 fi ; + + if da > max_da : da := max_da fi ; yr := yr - 2000 ; max_yr := max_yr - 2000 ; + + if (variant = 2) or (variant = 3) : + fill fullcircle scaled 205 withcolor .7white ; + fi ; + + color colorant[] ; + + vardef do_context_version(expr i, amount) = + fill (min/2 rotated (-angle/2) -- max { dir -40 } .. max rotated -angle -- cycle) rotated -(i*(angle+delta)) withcolor .3colorant[i] ; + fill (min rotated (-angle/2) -- max { dir -(45+45*amount) } .. max rotated -angle -- cycle) rotated -(i*(angle+delta)) withcolor .7colorant[i] ; + enddef ; + + color orange ; orange := (1,.62,.06) ; % .5white + + colorant[0] := red ; colorant[1] := green ; colorant[2] := blue ; colorant[3] := orange ; + colorant[4] := cyan ; colorant[5] := magenta ; colorant[6] := yellow ; + + do_context_version(0, (yr-1)/max_yr) ; + do_context_version(1, (mo-1)/max_mo) ; + do_context_version(2, (da-1)/max_da) ; + do_context_version(3, (mk-1)/max_mk) ; + do_context_version(4, (ho-1)/max_ho) ; + do_context_version(5, (mi-1)/max_mi) ; + do_context_version(6, (se-1)/max_se) ; + + currentpicture := currentpicture slanted .15 ; + + if (variant = 3) : + setbounds currentpicture to boundingbox currentpicture enlarged 10 ; + addbackground withcolor .3white ; + setbounds currentpicture to boundingbox currentpicture enlarged -5 ; + fi ; + + ) + +enddef ; + +% draw context_version(4,2011,07,28,14,50,30) ; +% draw context_version(4,01,01,01,01,01,01) ; +% draw context_version(4,99,12,31,24,60,60) ; + +\stopMPextensions + +\startluacode + moduledata.versions = moduledata.versions or { } + + function moduledata.versions.drawcontextversion(variant, mark, year, month, day, hours, minutes, seconds) + if not variant then + variant = 3 + end + if not mark then + mark = 4 + year, month, day, hours, minutes, seconds = string.match(environment.version,"(....).(..).(..) (..).(..)") + seconds = 30 + end + context.startMPcode() + context("draw context_version(%s,%s,%s,%s,%s,%s,%s,%s) ;", + variant or 1, + mark or 4, + year or os.date("%y"), + month or os.date("%m"), + day or os.date("%d"), + hours or os.date("%H"), + minutes or os.date("%M"), + seconds or os.date("%S") + ) + context.stopMPcode() + end +\stopluacode + +\continueifinputfile{s-version.mkiv} + +\starttext + +\startluacode + context.startTEXpage() + moduledata.versions.drawcontextversion() + context.stopTEXpage() +\stopluacode + +\stoptext + +% d:\imagemagick\convert.exe -geometry 256x256 s-version.pdf context-version.png +% d:\imagemagick\convert.exe -geometry 72x72 s-version.pdf context-version.ico +% d:\imagemagick\convert.exe -geometry 128x128 s-version.pdf context-version.icns diff --git a/tex/context/modules/mkxl/s-system-tokens.lmt b/tex/context/modules/mkxl/s-system-tokens.lmt new file mode 100644 index 000000000..39258d637 --- /dev/null +++ b/tex/context/modules/mkxl/s-system-tokens.lmt @@ -0,0 +1,247 @@ +if not modules then modules = { } end modules['s-system-tokens'] = { + version = 1.001, + comment = "companion to s-system-tokens.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local context = context +local ctx_NC = context.NC +local ctx_BC = context.BC +local ctx_NR = context.NR +local ctx_FL = context.FL +local ctx_ML = context.ML +local ctx_LL = context.LL +local gsub = string.gsub +local find = string.find +local concat = table.concat + +moduledata.system = moduledata.system or { } +moduledata.system.tokens = moduledata.system.tokens or { } + +local getrange = token.get_range +local getcmdchrcs = token.get_cmdchrcs +local whatever = { [1] = true, [4] = true, [8] = true } + +local collected = nil -- at some point we might have this one preloaded + +function moduledata.system.tokens.collect() + + if not collected then + + local allcommands = tokens.commands + local primitives = tex.primitives() + collected = { } + + for i=0,#allcommands do + local codes = { } + local kind, min, max, fixedvalue = getrange(i) + if min and whatever[kind] and max >= 0 and max <= 256 then + for i=min,max do + codes[i] = false + end + end + collected[i] = codes + collected[allcommands[i]] = codes + end + + for i=1,#primitives do + local prm = primitives[i] + local cmd, chr = getcmdchrcs("normal"..prm) + local codes = collected[cmd] + if codes and codes[chr] == false then + codes[chr] = prm + codes[prm] = chr + else + -- print(cmd,chr) + end + end + + collected.undefined_cs = nil + + -- table.save("whatever.lua",collected) + -- local p = token.getprimitives() + -- table.sort(p,function(a,b) if a[1] == b[1] then return a[2] < b[2] else return a[1] < b[1] end end) + -- table.save("moreever.lua",p) + + -- local p = token.getprimitives() + -- for i=1,#p do + -- local t = p[i] + -- pi[i] = { t[1], t[2], t[3], getrange(t[1]) } + -- end + + -- inspect(collected) + + end + + return collected + +end + +function moduledata.system.tokens.showlist() + + local l = tokens.commands + local t = moduledata.system.tokens.collect() + + context.starttabulate { "|cT|rT|lT|rT|rT|pTA{flushleft,verytolerant,stretch}|" } + ctx_FL() + ctx_BC() context("") + ctx_BC() context("cmd") + ctx_BC() context("name") + ctx_BC() context("min") + ctx_BC() context("max") + ctx_BC() context("default or subcommands") + ctx_BC() ctx_NR() + ctx_ML() + for i=0,#l do + local kind, min, max, fixedvalue = getrange(i) + local what = whatever[kind] + ctx_NC() context(kind) + ctx_NC() context(i) + ctx_NC() context(l[i]) + ctx_NC() if min then if what or min == 0 then context(min) else context("-0x%X",-min) end end + ctx_NC() if max then if what or max == 0 then context(max) else context("0x%X",max) end end + ctx_NC() + if min and what and max >= 0 and max <= 256 then + local l = { } + local c = t[i] + if c then + for j=min, max do + local s = c[j] + if s == " " then + s = "<space>" + elseif not s then + s = "<unavailable>" + end + l[#l+1] = j .. "=" .. s + end + if (#l > 0) then + context(table.concat(l," ")) + elseif fixedvalue ~= 0 then + context("0x%X",fixedvalue) + end + else + print("weird") + end + elseif fixedvalue and fixedvalue ~= 0 then + context("0x%X",fixedvalue) + end + ctx_NC() ctx_NR() + end + ctx_LL() + context.stoptabulate() + +end + +function moduledata.system.tokens.table(t) + local t = t or token.peek_next() -- local t = token.scan_next() token.put_back(t) + local n = "" + local w = "" + local c = t.cmdname + if c == "left_brace" then + w = "given token list" + t = token.scan_toks(false) + elseif c == "register_toks" then + token.scan_next() + w = "token register" + n = t.csname or t.index + t = tex.gettoks(n,true) + elseif c == "internal_toks" then + token.scan_next() + w = "internal token variable" + n = t.csname or t.index + t = tex.gettoks(n,true) + else + n = token.scan_csname() + local r = { } + local m = token.get_meaning(n,true) + if t.frozen then r[#r+1] = "frozen" end + if t.permanent then r[#r+1] = "permanent" end + if t.immutable then r[#r+1] = "immutable" end + if t.primitive then r[#r+1] = "primitive" end + if t.mutable then r[#r+1] = "mutable" end + if t.noaligned then r[#r+1] = "noaligned" end + if t.instance then r[#r+1] = "instance" end + if t.tolerant then r[#r+1] = "tolerant" end + if t.protected then r[#r+1] = "protected" end + r[#r+1] = "control sequence" + if type(m) == "table" then + t = m + else + t = { t } + end + w = concat(r, " ") + end + if type(t) == "table" then + context.starttabulate { "|l|r|r|l|c|l|l|" } + ctx_FL() + ctx_NC() context.formatted.rlap("\\bold %s: %s",w,n) + ctx_NC() ctx_NC() ctx_NC() ctx_NC() ctx_NC() ctx_NC() ctx_NC() + ctx_NC() ctx_NR() + ctx_ML() + for i=1,#t do + local ti = t[i] + local cs = ti.csname + local id = ti.id + local ix = ti.index + local cd = ti.command + local cn = gsub(ti.cmdname,"_"," ") + ctx_NC() context(id) + ctx_NC() context(cd) + ctx_NC() context("%3i",ix) + ctx_NC() context(cn) + if cs then + ctx_NC() + ctx_NC() + ctx_NC() context(cs) + ctx_NC() ctx_NR() + elseif cn == "letter" or cn == "other char" then + ctx_NC() context.char(ix) + ctx_NC() context("%U",ix) + ctx_NC() + ctx_NC() ctx_NR() + elseif cn == "match" then + ctx_NC() + ctx_NC() + if ix == 32 then context("optional spacer") -- space + elseif ix == 43 then context("keep braces") -- "+" + elseif ix == 45 then context("thrash") -- "-" + elseif ix == 61 then context("mandate braces") -- "=" + elseif ix == 94 then context("keep spaces") -- "^" + elseif ix == 95 then context("keep mandate braces") -- "_" + else context("argument %c",ix) + end + ctx_NC() + ctx_NC() ctx_NR() + else + ctx_NC() + ctx_NC() + ctx_NC() + ctx_NC() ctx_NR() + if cn == "end match" then + context.ML() + end + end + end + context.LL() + context.stoptabulate() + else + context.starttabulate { "|l|" } + ctx_FL() + ctx_NC() context("%s: %s",w,n) + ctx_NC() ctx_NR() + ctx_ML() + ctx_NC() context("<no tokens>") + ctx_NC() ctx_NR() + ctx_LL() + context.stoptabulate() + end +end + +interfaces.implement { + name = "luatokentable", + public = true, + protected = true, + actions = moduledata.system.tokens.table, +} diff --git a/tex/context/modules/mkxl/s-system-tokens.mkxl b/tex/context/modules/mkxl/s-system-tokens.mkxl index b83a4f47b..584fcf82f 100644 --- a/tex/context/modules/mkxl/s-system-tokens.mkxl +++ b/tex/context/modules/mkxl/s-system-tokens.mkxl @@ -31,54 +31,11 @@ \starttext - \showsystemtokens - - Some tokens cannot be created yet because they are more complex but eventually the creator will - deal with them. The indices are sometimes the same as internal but in most cases nicely start - at zero. When they start at another value, then there is an internal token or state that is not - user accessible. You always need to use symbolic constants as the numbers can change. - - The first column is a classifier (which is experimental and categories might change when we feel - the need). - - \startcolumns[n=5] - \starttabulate[|T||] - \NC 0 \NC unused \NC \NR - \NC 1 \NC regular \NC \NR - \NC 2 \NC character \NC \NR - \NC 3 \NC register \NC \NR - \NC 4 \NC internal \NC \NR - \NC 5 \NC reference \NC \NR - \NC 6 \NC data \NC \NR - \NC 7 \NC token \NC \NR - \NC 8 \NC node \NC \NR - \stoptabulate - \stopcolumns - - \page - - Here is a typeset table of \type {\startframed} using \type {\luatokentable\startframed}: - \luatokentable\startframed - which calls \type {\pack_framed_start_framed} where \type {\luatokentable\pack_framed_start_framed} gives: - - - \unprotect - \luatokentable\pack_framed_start_framed - \protect - - So you can guess what generates this: - - \unprotect - \luatokentable\pack_framed_start_framed_nop - \protect - - And this: + \page - \unprotect - \luatokentable\pack_framed_start_framed_yes - \protect + \showsystemtokens \stoptext diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index d1462e4b4..3864fbc99 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 : 2021-07-21 19:51 +-- merge date : 2021-07-22 19:11 do -- begin closure to overcome local limits and interference |