nkb boundary
Podajesz limit, który deklaruje pole, i dostajesz wartości, które go testują: pustą, o jeden krótszą, dokładnie równą i o jeden dłuższą, ze znaków, które ważą inaczej w bajtach i w jednostkach UTF-16.
nkb boundary [--max-length N] [--min-length N]
[--unit graphemes|code-points|utf16|bytes]
[--format json|csv|lines] [--escaped|--raw] [--base64]
Co tworzy?
Dla pola, które przyjmuje najwyżej 50 znaków: wartość pustą, a potem wartości o długości 49, 50 i 51 w każdym z sześciu wypełnień. Z --min-length dochodzą długości wokół najmniejszej, jaką pole przyjmuje, a długość wspólna dla dwóch granic pojawia się raz. Każda wartość mówi, jak długa jest w czterech jednostkach i czy jej długość mieści się w limicie.
Paczki to listy nietypowych znaków. To polecenie odpowiada na jedno zdanie, które specyfikacja mówi o polu.
Dlaczego sześć wypełnień?
Bo „50 znaków” to jedna z czterech liczb, a rzadko wiadomo, którą z nich liczy aplikacja:
maxlengthw przeglądarce jest mierzony tak, jak JavaScript mierzy napis, w jednostkach UTF-16. Emoji to dwie.varchar(n)w PostgreSQL mieści n znaków, nie bajtów.varchar(n)w SQL Server liczy bajty, anvarchar(n)pary bajtów.- Autor specyfikacji liczy to, co widzi.
Pięćdziesiąt liter a to pięćdziesiąt w każdej jednostce, więc nie odróżni jednej od drugiej. Pięćdziesiąt liter dwubajtowych to pięćdziesiąt znaków i sto bajtów, pięćdziesiąt emoji to sto jednostek UTF-16, a pięćdziesiąt emoji rodziny to dla oka pięćdziesiąt znaków i dwieście pięćdziesiąt punktów kodowych. Pole, które przyjmuje pięćdziesiąt liter a, a odrzuca albo ucina którąś z pozostałych wartości, właśnie powiedziało, co liczy.
Żaden z tych znaków nie zmienia się w żadnej postaci normalnej Unicode, więc pole, które normalizuje tekst, nadal dostaje długość, o którą chodziło.
Przykłady
Jedna wartość na wiersz, do wklejania albo dla testu:
$ nkb boundary --max-length 50 --format lines > limit-50.txt
nkb boundary: 19 values, 1500 code points, 4350 bytes
CSV, z czterema rozmiarami każdej wartości obok siebie:
$ nkb boundary --max-length 50 --format csv
nkb boundary: 19 values, 1500 code points, 4350 bytes
id,name,value,fill,length,within,graphemes,code_points,utf16_units,bytes
empty,Empty value,,,0,true,0,0,0,0
letters-49,49 x a,aaaaa...,letters,49,true,49,49,49,49
letters-50,50 x a,aaaaa...,letters,50,true,50,50,50,50
letters-51,51 x a,aaaaa...,letters,51,false,51,51,51,51
...
two-byte-50,50 x U+0142,...,two-byte,50,true,50,50,50,100
four-byte-50,50 x U+1F600,...,four-byte,50,true,50,50,100,200
cluster-50,50 x U+1F468 U+200D U+1F469 U+200D U+1F467,...,cluster,50,true,50,250,400,900
Limit liczony w bajtach. Każda wartość ma dokładnie tyle bajtów, ile mówi jej wiersz, z literą a z przodu tam, gdzie całe znaki nie dają tej liczby:
$ nkb boundary --max-length 50 --unit bytes --format csv
...
two-byte-49,1 x a + 24 x U+0142,...,two-byte,49,true,25,25,25,49
two-byte-50,25 x U+0142,...,two-byte,50,true,25,25,25,50
two-byte-51,1 x a + 25 x U+0142,...,two-byte,51,false,26,26,26,51
O którą jednostkę poprosić?
Zacznij bez --unit. Wartości są wtedy liczone tak, jak liczy człowiek, a odpowiedź aplikacji na cięższe wypełnienia pokazuje, co liczy ona.
Potem uruchom polecenie jeszcze raz, w tej jednostce. Wartość o 51 bajtach z litery dwubajtowej to jedno a i dwadzieścia pięć liter, więc pole, które tnie na 50 bajtach, przecina ostatnią literę w połowie. W utf16 to samo spotyka emoji, a zostaje pół znaku: tekst, który przestaje się wyświetlać, zapis, który się nie udaje, albo błąd daleko od pola. Wartość z całych znaków aż do limitu nigdy tego nie wywoła i dlatego dopełnienie stoi z przodu.
Jak czytać counterstring?
Przed każdą gwiazdką stoi numer jej własnego miejsca. To counterstring o długości 51:
*3*5*7*9*12*15*18*21*24*27*30*33*36*39*42*45*48*51*
Jeśli w polu zostało ...42*45*48*51, ostatnia gwiazdka stoi na miejscu 48 i są po niej dwa znaki, więc weszło 50. Miejsce cięcia czytasz z samego pola, bez liczenia i bez drugiego narzędzia.
Counterstring to cyfry i gwiazdki. Pole, które przyjmuje same litery, odrzuci go z tego powodu i od tego jest wypełnienie letters. Pole, które renderuje Markdown, może połknąć gwiazdki.
Co obiecuje „within”?
Że długość wartości mieści się w podanym limicie, w podanej jednostce, i nic więcej. Pole wymagane nadal odrzuci wartość pustą, a pole przyjmujące same litery nadal odrzuci emoji. Gdy wartość mieszcząca się w limicie zostaje odrzucona z powodu długości, to albo aplikacja liczy w innej jednostce, albo limit jest inny, niż mówi specyfikacja. Jedno i drugie warto zgłosić.
Opcje
Wypełnienia
Jednostki
Formaty
Kody wyjścia
Pomoc tego polecenia nie wymienia własnych kodów wyjścia. Liczby znaczą to samo w każdym poleceniu: Kody wyjścia
Pomoc, tak jak wypisuje ją program
Co wypisuje nkb boundary --help (nkb 0.3.0).
nkb boundary - make the values that test the length limit of a field
Usage:
nkb boundary [--max-length N] [--min-length N]
[--unit graphemes|code-points|utf16|bytes]
[--format json|csv|lines] [--escaped|--raw] [--base64]
Give the limit the field states and get the values worth trying: nothing,
then one under, exactly at and one over each bound. Every length comes in
six fills, because "50 characters" is a different number in each unit.
Fills:
letters The letter a
counterstring Numbers and stars, as in *3*5*7*9*12*. Each number is the
place of the star after it, so a field that cut the value
shows where it cut
two-byte A letter of two bytes (U+0142)
three-byte A sign of three bytes (U+20AC)
four-byte An emoji of four bytes and two UTF-16 units (U+1F600)
cluster A family emoji: one character to the eye, five code points
Units:
graphemes Characters as a person counts them. The default
code-points Unicode code points
utf16 UTF-16 units, which a browser's maxlength and JavaScript count
bytes Bytes of UTF-8
Counted in graphemes, 50 two-byte letters are 100 bytes and 50 emoji are
100 UTF-16 units, so a field that refuses or cuts them counts something
else. Run again in that unit: a value then has exactly that many units,
padded with the letter a in front, and the limit falls inside the last
character of the value one over it.
Values go to standard output and the account of what came out goes to
standard error. "within" says whether the length of a value is inside the
limit and nothing more: a required field still refuses the empty value.
Formats:
json Both forms of every value, with its fill, its length, whether it
is within the limit and its size in all four units. The default
csv One row per value, with the same columns. Escaped by default
lines One value per line. The empty value is an empty line
Options:
--max-length N The most the field takes, from 1 to 100000
--min-length N The least the field takes, from 1 to 100000
--unit What the limit is counted in (default: graphemes)
--escaped Print values as a pack file stores them
--raw Print values literally
--base64 Encode values, for channels that damage text
-h, --help Show this help and exit with 0