--- parser3/operators.txt 2024/12/20 17:17:47 1.259
+++ parser3/operators.txt 2024/12/20 19:24:17 1.264
@@ -1,40 +1,40 @@
-операторы
- ^eval(выражение)[формат] выражение, кроме обычных функций:
- допустимы #комментарии
- работают до конца строки или закрывающейся круглой скобки
- внутри комментария допустимы вложенные круглые скобки
- из неочевидных операторов:
- | побитный xor
- || логический xor
- ~ побитное отрицание
- \ целочисленное деление 10\3=3
- def для проверки defined,
- пустая строка не defined
- пустая таблица не defined
- пустой hash не defined
- eq ne lt gt le ge для сравнения строк,
- in "/dir/" для проверки, находится ли текущий документ в каталоге
- ["внутри не допустимы выражения, если надо сравнить со сложным, пусть это будет переменная]
- is 'type' для проверки типа левого операнда,
- можно проверить, "не hash ли параметр метода?"
- -f для проверки существования файла на диске,
- -d для проверки существования каталога на диске,
- строка в кавычках или апострофах - строка, без кавычек или апострофов строка до ближайшего whitespace
- числовой литерал бывает 0xABC
- приоритеты:
+operators
+ ^eval(expression)[format] expressions, apart from the usual functions, supports:
+ #comments allowed
+ they work until the end of the line or the closing parenthesis
+ nested parentheses are allowed inside comments
+ among the non-obvious operators:
+ | bitwise XOR
+ || logical XOR
+ ~ bitwise negation
+ \ integer division 10\3=3
+ def checks if defined:
+ an empty string is not defined
+ an empty table is not defined
+ an empty hash is not defined
+ eq ne lt gt le ge for string comparison,
+ in "/dir/" to check if the current document is located in the specified directory
+ ["no expressions allowed inside; if you need a complex comparison, assign it to a variable"]
+ is 'type' to check the type of the left operand,
+ e.g., "is the method parameter not a hash?"
+ -f checks if a file exists on disk,
+ -d checks if a directory exists on disk,
+ a quoted string (double or single quotes) is treated as a string, unquoted text is a string until the nearest whitespace
+ numeric literals can be in hex format like 0xABC
+ priorities:
/* logical */
%left "!||"
%left "||"
%left "&&"
- %left '<' '>' "<=" ">=" "lt" "gt" "le" "ge"
- %left "==" "!=" "eq" "ne"
+ %left '<' '>' "<=" ">=" "lt" "gt" "le" "ge"
+ %left "==" "!=" "eq" "ne"
%left "is" "def" "in" "-f" "-d"
%left '!'
/* bitwise */
%left '!|'
%left '|'
- %left '&'
+ %left '&'
%left '~'
/* numerical */
@@ -42,94 +42,94 @@
%left '*' '/' '%' '\\'
%left '~' /* negation: unary */
- литералы:
+ literals:
true
false
- ^if(условие){когда да}{когда нет}
- ^if(условие1){да}[(условие2){да}[(условие2){да}[...]]]{нет}
- количество доп. условий не ограничено (в общем elseif это :)
+ ^if(condition){then}{else}
+ ^if(condition1){yes}[(condition2){yes}[(condition3){yes}[...]]]{no}
+ unlimited number of additional conditions (elseif)
- ^switch[значение]{^case[вариант1[;вариант2...]]{действие}^case[DEFAULT]{действие по умолчанию}}
+ ^switch[value]{^case[var1[;var2...]]{action}^case[DEFAULT]{default action}}
- ^while(условие){тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
+ ^while(condition){body}[[delimiter]|{delimiter executed before each non-empty non-first body}]
- ^for[i](0;4){тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
+ ^for[i](0;4){body}[[delimiter]|{delimiter executed before each non-empty non-first body}]
^try{
...
- ^throw[sql.connect[;вася[;ошибся]]] // был ^error[текст]
+ ^throw[sql.connect[;vasya[;mistaken]]] // previously ^error[text]
^throw[
$.type[sql.connect]
- $.source[вася]
- $.comment[ошибся]
+ $.source[vasya]
+ $.comment[mistaken]
]
...
}{
^if($exception.type eq "sql"){
- $exception.handled(1|true) ^rem{флаг, что exception обработан}
+ $exception.handled(1|true) ^rem{flag that exception is handled}
....
}
^switch[$exception.type]{
^case[sql;mail]{
$exception.handled(1)
- код, обрабатывающий sql ошибку
+ code handling sql error
$exception.type = sql.connect
- $exception.file $exception.lineno $exception.colno [если не запрещены при компиляции]
- $exception.source = вася
- $exception.comment = ошибся
+ $exception.file $exception.lineno $exception.colno [if not disabled at compile time]
+ $exception.source = vasya
+ $exception.comment = mistaken
}
^case[DEFAULT]{
- код, обрабатывающий другую ошибку
+ code handling another error
^throw[$exception] << re-throw // DON'T! It's default behaviour!
}
}
}
^break[]
- обрывает цикл
+ breaks the loop
^break(true|false)
- обрывает цикл, если true
+ breaks the loop if true
^continue[]
- обрывает итерацию цикла
+ breaks the current iteration of the loop
^continue(true|false)
- обрывает итерацию цикла, если true
+ breaks the current iteration if true
^return[]
- обрывает выполнение метода
+ stops method execution
^return[value]
- присваивает $result значение value и обрывает выполнение метода
+ assigns $result the value and stops method execution
- ^untaint[[as-is|file-spec|uri|http-header|mail-header|sql|js|json|parser-code|regex|xml|html|optimized-[as-is|xml|html]]]{код}
+ ^untaint[[as-is|file-spec|uri|http-header|mail-header|sql|js|json|parser-code|regex|xml|html|optimized-[as-is|xml|html]]]{code}
default as-is
- ^taint[[lang]][код]
+ ^taint[[lang]][code]
default "just tainted, language unknown"
- ^apply-taint[[lang;]текст]
- выполняет заданные в строке преобразования, неопределенно грязное как lang, на выходе чистая строка
+ ^apply-taint[[lang;]text]
+ applies transformations specified in the string, "indefinitely dirty" is considered as lang, producing a clean string
- ^process[[$caller.CLASS|$object|$КЛАСС:CLASS]]{строка, которая будет process-ed, как код}[
- $.main[во что переименовать @main]
- $.file[имя файла из которого, якобы, данный текст]
- $.lineno(номер строки в файле, откуда данный текст, можно отрицательный)
+ ^process[[$caller.CLASS|$object|$CLASS:CLASS]]{string to be processed as code}[
+ $.main[what to rename @main to]
+ $.file[name of the file supposedly containing this text]
+ $.lineno(line number in the file from where this text originated, can be negative)
]
- ^process..[путь][во что переименовать @main]
- по умолчанию, методы компилируются в $self [в случае оператора, $self=$MAIN:CLASS]
+ ^process..[path][what to rename @main to]
+ by default, methods are compiled into $self [in case of operator, $self=$MAIN:CLASS]
- ^connect[protocol://строка соединения]]{код с ^sql[...]-ями}
+ ^connect[protocol://connection-string]]{code with ^sql[...] calls}
mysql://user:pass@{host[:port][, host[:port]]|[/unix/socket]}/database?
ClientCharset=parser-charset << charset in which parser thinks client works
charset=UTF-8&
timeout=3&
compress=0&
named_pipe=1&
- multi_statements=1& allow execute more then one query in one parser :sql{} request
+ multi_statements=1& allow executing more than one query in a single :sql{} request
config_file=.my.cnf&
config_group=parser3& use group name from .my.cnf
autocommit=1
- autocommit если выставить в 0, будет делать commit/rollback
+ if autocommit is set to 0, it will perform commit/rollback
pgsql://user:pass@{host[:port]|[local]}/database?
client_encoding=win,[to-find-out]
@@ -143,7 +143,7 @@
ClientCharset=parser-charset& << charset in which parser thinks client works
autocommit=1
- для работы connect нужно, чтобы заранее (рекомендуется в системном конфигурационном auto.p) была определена таблица
+ to use ^connect, the $SQL table must be defined beforehand (recommended in the system configuration auto.p)
#sql drivers
$SQL[
$.drivers[^table::create{protocol driver client
@@ -154,590 +154,741 @@ odbc parser3odbc.dll
}]
]
^rem{}
- комментарий, удаляется при компиляции
+ a comment, removed at compile time
- ^cache[файл](секунд){код}[{catch код}]
- относительное задание времени
- скешировать строку, которая получается при выполнении кода на 'секунд' секунд
- если 0 секунд, значит не кешировать, а старый такой стереть
- в catch коде $exception.handled[cache] ^rem{флаг, что exception обработан}
- ^cache[файл][expires date]{код}[{catch код}]
- абсолютное задание времени
- ^cache[файл]
- удалить файл [не ругает, если его нет]
- ^cache(секунд)
+ ^cache[file](seconds){code}[{catch code}]
+ relative time assignment
+ caches the string resulting from the code execution for 'seconds' seconds
+ if 0 seconds, do not cache, and remove any existing old cache
+ in the catch code, $exception.handled[cache] ^rem{flag that exception is handled}
+ ^cache[file][expires date]{code}[{catch code}]
+ absolute time assignment
+ ^cache[file]
+ deletes the file [no error if it doesn't exist]
+ ^cache(seconds)
^cache[expires date]
- сигнализирует вышестоящему ^cache "уменьши до стольких-то 'секунд'/'expires'"
- в пределе: ^cache(0) отменить кеширование
+ signals to the upper-level ^cache "reduce it to these many 'seconds'/'expires'"
+ ultimately: ^cache(0) cancels caching
^cache[]
- выдаёт текущую expires date
+ returns the current expires date
- у всех методов есть локальная переменная $result, если в неё что положить,
- то это будет результатом метода, а не его тело
+ each method has a local variable $result. If you put something in it,
+ that will be the method's result, not its body
- у всех методов есть локальная переменная $caller, в ней лежит родительский stack frame,
- можно записать в его локальную переменную
+ each method has a local variable $caller, containing the parent stack frame,
+ you can write to its local variables
- use(^use или @USE) ищет и подключает файл:
- 1. если путь начинается с /, то считается, что это путь от корня веб пространства
- 2. относительно текущей директории
- 3. относительно строк из table $MAIN:CLASS_PATH, снизу вверх
- $MAIN:CLASS_PATH - глобальная строка или таблица с путём или путями к каталогу
- с классами (от корня веб пространства), задавайте её в конфигурационном auto.p
-
- глобальная табличка $CHARSETS[$.название[имя файла]]
- задаёт какие буквы считаются какими (whitespace, letter, etc), а также их unicode
- формат: tab delimited файл, с заголовком:
+ use(^use or @USE) searches for and includes a file:
+ 1. If the path starts with /, it is considered a path from the web root
+ 2. Relative to the current directory
+ 3. Relative to strings from the $MAIN:CLASS_PATH table, bottom-up
+ $MAIN:CLASS_PATH is a global string or table with a path or paths to a directory
+ with classes (from the web root), set it in the configuration auto.p
+
+ A global table $CHARSETS[$.name[filename]]
+ defines which characters are considered what (whitespace, letter, etc.), as well as their Unicode
+ format: tab-delimited file, with a header:
char white-space digit hex-digit letter word lowercase unicode1 unicode2
- A x x x a 0x0041 0xFF21
- где char и lowercase могут быть буквами, а могут быть и 0xКОДАМИ
- если символ имеет единственное unicode представление, равное самому символу, можно не указывать unicode
- всегда есть кодировка UTF-8, она является кодировкой по-умолчанию для request и response
- ВНИМАНИЕ: имя кодировки case insensitive
-
-
-синтаксис
- $имя[новое значение]
- $имя(математическое выражение нового значения)
- $имя{код нового значения}
- $имя whitespace или ${имя}неважно - вывод значения переменой
- ^имя параметры - вызов
- $имя.CLASS - класс значения
- $имя.CLASS_NAME - имя класса
- $имя[$.key[] () {}] - конструктор переменной-хеша с элементом $имя.key
- ^method[$.key[] () {}] - конструктор параметра-хеша с элементом $parameter.key
- $CLASS.имя обращение к переменной класса
-
- имя заканчивается перед: пробел tab linefeed ; ] } ) " < > + * / % & | = ! ' , ?
- т.е. можно $имя,aaaa
- но если нужно после имени символ, скажем -, то ${имя}-
-
- в выражениях + и - являются дополнительными концами имени
-
- можно обращаться к составным объектам так: $name.subname где subname бывает:
- строка
- $переменная
- строка$переменная
- [код, вычисляющий строку]
- например: $хеш[$.возраст(88)] $достать[$.поле[возраст]] ^хеш.[$достать.поле].format{%05d}
-
-параметры := один или много параметров
-параметр :=
- (математическое выражение) вычисляется много раз внутри вызова,
-| [код] вычисляется один раз перед вызовом,
-| {код} вычисляется 0 или много раз внутри вызова,
- допустимы ';' чтобы сделать много параметров в одних скобках
+ A x x x a 0x0041 0xFF21
+ where char and lowercase can be letters or 0xCODES
+ if the character has a single Unicode representation equal to itself, you can omit unicode
+ UTF-8 is always available and is the default encoding for request and response
+ WARNING: the encoding name is case-insensitive
+
+syntax
+ $name[new value]
+ $name(arithmetic expression of new value)
+ $name{code of new value}
+ $name whitespace or ${name}something - variable value
+ ^name parameters - call
+ $name.CLASS - class of the value
+ $name.CLASS_NAME - name of the class
+ $name[$.key[] () {}] - constructor of a hash variable with element $name.key
+ ^method[$.key[] () {}] - constructor of a hash parameter with element $parameter.key
+ $CLASS.name access a class variable
+
+ the name ends before: space tab linefeed ; ] } ) " < > + * / % & | = ! ' , ?
+ i.e. you can do $name,aaaa
+ but if you need a character after the name, say -, then ${name}-
+
+ in expressions, + and - are additional name boundaries
+
+ you can access compound objects as: $name.subname where subname can be:
+ a string
+ a $variable
+ a string$variable
+ [code computing a string]
+ for example: $hash[$.age(88)] $get[$.field[age]] ^hash.[$get.field].format{%05d}
+
+parameters := one or more parameters
+parameter :=
+ (arithmetic expression) evaluated multiple times inside the call,
+| [code] evaluated once before the call,
+| {code} evaluated zero or many times inside the call,
+ ';' are allowed, making multiple parameters in a single bracket
+
void
- доступны все методы, присутствующие у объекта класса string, результат как у пустой строки
- ^void:sql{запрос без результата}{$.bind[см. table::sql]}
+ all methods present in the string class object are available, the result behaves as if it were an empty string
+ ^void:sql{query without result}{$.bind[see table::sql]}
int,double
- ^имя.int[]
- целочисленное значение
- ^имя.double[]
- double значение
- ^имя.bool[] ^name.bool(true|false)
- bool значение
- ^имя.inc(на сколько +)
- ^имя.dec(на сколько -)
- ^имя.mul(на сколько *)
- ^имя.div(на сколько /)
- ^имя.mod(на сколько %)
- ^имя.format[формат]
- ^int/double:sql{query}[[$.limit(2) $.offset(4) $.default{0} $.bind[см. table::sql]]]
- запрос, результат которого должен быть один столбец/одна строка
+ ^name.int[]
+ integer value
+ ^name.double[]
+ double value
+ ^name.bool[] ^name.bool(true|false)
+ boolean value
+ ^name.inc(how much +)
+ ^name.dec(how much -)
+ ^name.mul(how much *)
+ ^name.div(how much /)
+ ^name.mod(how much %)
+ ^name.format[format]
+ ^int/double:sql{query}[[$.limit(2) $.offset(4) $.default{0} $.bind[see table::sql]]]
+ the query result should be one column/one row
string
- в выражении
- def значение равно "не пуста?"
- логическое/числовое значение равно попытке преобразовывания к double,
- пустая строка тихо преобразуется к 0
- пример:
- ^if(def $form:name) не пуста?
- ^if($user.isAlive) истина? [автопреобразование к числу, не ноль?]
- ^string:sql{query}[[$.limit(1) $.offset(4) $.default{n/a} $.bind[см. table::sql]]]
- результат запроса должен быть один столбец/одна строка
- ^строка.int[] ^строка.int(default)
- целочисленное значение строки, если ломается преобразование, берётся default
- ^строка.double[] ^строка.double(default)
- double значение строки, если ломается преобразование, берётся default
- ^строка.bool[] ^строка.bool(default)
- bool значение строки, если ломается преобразование, берётся default
- ^строка.format[формат] %d %.2f %02d...
- ^строка.match[шаблон-строка|шаблон-regex][[опции поиска]] $prematch $match $postmatch $1 $2...
- опции поиска=
+ in expression
+ def value means "not empty?"
+ logical/numerical value equals an attempt to convert to double,
+ an empty string quietly converts to 0
+ example:
+ ^if(def $form:name) not empty?
+ ^if($user.isAlive) true? [auto-convert to number, not zero?]
+ ^string:sql{query}[[$.limit(1) $.offset(4) $.default{n/a} $.bind[see table::sql]]]
+ the query result should be one column/one row
+ ^string.int[] ^string.int(default)
+ integer value of the string, if conversion fails, default is taken
+ ^string.double[] ^string.double(default)
+ double value of the string, if conversion fails, default is taken
+ ^string.bool[] ^string.bool(default)
+ boolean value of the string, if conversion fails, default is taken
+ ^string.format[format] %d %.2f %02d...
+ ^string.match[string-pattern|regex-pattern][[search options]] $prematch $match $postmatch $1 $2...
+ search options:
i CASELESS
x whitespace in regex ignored
- s singleline = $ считается концом всего текста
- m multiline = $ считается концом строки[\n], не концом всего текста
- g найти все вхождения, а не одно
- ' создавать столбцы prematch, match, postmatch
- n вернуть цисло с количеством найденных совпадений, а не таблицу с результатами
- U инвертировать смысл модификатора '?'
- ^строка.match[шаблон-строка|шаблон-regex][опции поиска]{замена}
- опции поиска+=
- g заменить все вхождения, а не одно
- ^строка.split[разделитель|regex][[lrhva]][[название столбца для вертикального разбиения]]
- l слева направо [default]
- r справа налево
- h nameless таблица с ключами 0, 1, 2, ...
- v таблица из 1 столбца 'piece' или как передадут [default]
- a массив
- ^строка.{l|r}split[разделитель] таблица из столбца $piece
- оставлен для совместимости
- ^строка.upper|lower[]
- ^строка.length[]
- ^строка.mid(P[;N])
- без N - "до конца строки"
- ^строка.left(N), -1 выдает всю строку
- ^строка.right(N)
- ^строка.pos[подстрока]
- ^строка.pos[подстрока](позиция, с которой ищем)
- <0 = не найдено
- ^строка.replace[$таблица_подстановок_строка_на_строку]
- ^строка.replace[$что;$на-что]
- ^строка.save[[append;]путь]
- ^строка.save[путь[;$.charset[в какой кодировке сохраняем] $.append(true)]]
- сохраняет строку в файл
- ^строка.trim[start|both|end|left|right[;chars]]
- выкидывает chars из начала/конца/и начала и конца
+ s singleline = $ matches end of entire text
+ m multiline = $ matches end of line[\n], not end of entire text
+ g find all occurrences, not just one
+ ' create columns prematch, match, postmatch
+ n return the number of matches instead of a table
+ U invert the meaning of the '?' modifier
+ ^string.match[string-pattern|regex-pattern][search options]{replacement}
+ additional search option:
+ g replace all occurrences, not just one
+ ^string.split[delimiter|regex][[lrhva]][[column name for vertical splitting]]
+ l left to right [default]
+ r right to left
+ h nameless table with keys 0, 1, 2, ...
+ v table of one column 'piece' or as provided [default]
+ a array
+ ^string.{l|r}split[delimiter] a table from the $piece column
+ kept for compatibility
+ ^string.upper|lower[]
+ ^string.length[]
+ ^string.mid(P[;N])
+ without N - "until the end of the string"
+ ^string.left(N), -1 returns the entire string
+ ^string.right(N)
+ ^string.pos[substring]
+ ^string.pos[substring](position from which to search)
+ <0 = not found
+ ^string.replace[$table_of_substitutions_string_to_string]
+ ^string.replace[$what;$to]
+ ^string.save[[append;]path]
+ ^string.save[path[;$.charset[in which encoding save] $.append(true)]]
+ saves the string to a file
+ ^string.trim[start|both|end|left|right[;chars]]
+ removes chars from the start/end/or both start and end
default 'chars' = whitespace chars
- ^строка.trim[chars]
- выкидывает chars из начала и конца
- ^строка.base64[ $.pad(bool) $.wrap(bool) $.url-safe(bool) ] encode
+ ^string.trim[chars]
+ removes chars from start and end
+ ^string.base64[ $.pad(bool) $.wrap(bool) $.url-safe(bool) ] encode
^string:base64[encoded[; $.pad(bool) $.strict(bool) $.url-safe(bool) ]] decode
- ^строка.idna[]
- IDNA кодирование, поддержка кириллических доменов
+ ^string.idna[]
+ IDNA encoding, supports Cyrillic domains
^string:idna[encoded]
- IDNA декодирование, поддержка кириллических доменов
- ^строка.js-escape[]
- кодирование для передачи в JS (%uXXXX)
+ IDNA decoding, supports Cyrillic domains
+ ^string.js-escape[]
+ encoding for passing to JS (%uXXXX)
^string:js-unescape[escaped]
- декодирование переданного из js
+ decoding from js
^string:unescape[js|uri;escaped; $.charset[] ]
- декодирование переданного из js или uri
- ^строка.contains[ключ]
- для совместимости с hash
+ decoding passed from js or uri
+ ^string.contains[key]
+ for compatibility with hashtable
table
- в выражении
- логическое значение равно "не пуста?"
- числовое значение равно count[]
- $таблица.поле
- $таблица.поле[новое значение]
- $таблица.fields
- из named таблицы выдаёт текущую запись как Hash
- ^table::create[[nameless]]{данные}[[$.separator[^#09] $.encloser[]]]
+ in expression
+ logical value means "not empty?"
+ numerical value equals count[]
+ $table.field
+ $table.field[new value]
+ $table.fields
+ from a named table returns the current record as a Hash
+ ^table::create[[nameless]]{data}[[$.separator[^#09] $.encloser[]]]
^table::create[table][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
- клонирует таблицу
- reverse - в обратном порядке
- ^table::load[[nameless;]путь[;опции]]
- если не nameless, названия колонок берутся из первой строки
- пустые строки, и строки в первой колонке содержащие '#', игнорируются
+ clones the table
+ reverse - in reverse order
+ ^table::load[[nameless;]path[;options]]
+ if not nameless, column names are taken from the first line
+ empty lines, and lines in the first column containing '#' are ignored
$.separator[^#09]
- $.encloser["] по-умолчанию, нет
+ $.encloser["] by default, none
^table::sql{query}[[$.limit(2) $.offset(4) $.bind[hash]]]
- bind привязывает переменные в запросе к их значениям
- пока реализован только для oracle
- в запросе надо написать ":имя"
- в параметре bind передать hash, из которого возьмётся (или куда запишется) значение
- ^таблица.save[[nameless|append;]путь[;опции, см. load]]
- сохраняет таблицу в файл
- ^таблица.menu{тело}[[разделитель]]
- выполняет код тела для каждой строки таблицы
- ^таблица.foreach[позиция;значение]{тело}[[разделитель]]
- ^таблица.line[]
- текущий ряд таблицы, начинается с 1
- ^таблица.offset[]
- смещение текущего ряда таблицы от начала, начинается с 0
- ^таблица.offset[[whence]](5)
- сдвигает whence=cur|set, без whence - это cur
- ^таблица.count[], ^таблица.count[rows]
- количество строк в таблице
- ^таблица.count[columns]
- количество столбцов таблицы
- ^таблица.count[cells]
- количество ячеек в текущей строке таблицы
- ^таблица.sort{{ключеделатель строка}|(ключеделатель число)}[{desc|asc}] default=asc
- ^таблица.append{данные}
- ^таблица.append[ $.имя столбца[значение столбца] ]
- ^таблица.insert{данные} добавить запись на текущую позицию
- ^таблица.insert[ $.имя столбца[значение столбца] ]
- ^таблица.delete[]
- стирает запись с текущей позиции
- ^таблица.join[таблица][$.limit(1) $.offset(5) $.offset[cur]]
- добавляет записи из таблицы, таблицы должны иметь одинаковую структуру
- ^таблица.flip[]
- выдаёт транспонированную
- ^таблица.locate[поле;значение][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
- передвигает текущую строку, если найдёт. выдаёт bool
- ^таблица.locate(логическое выражение)[[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
- передвигает текущую строку, если найдёт. выдаёт bool
- ^таблица.hash{[поле]|{код}|(выражение)}[[поле значений|table поля значений]{код значения}][[$.distinct(1) $.distinct[tables] $.type[hash]]]
- по умолчанию значением $hash.ключ будет hash в котором поля значений будут ключами
- поля значений могут быть не указаны, тогда ими будут все столбцы, включая ключевой
- если distinct содержит true, то не будет ошибки при повторяющихся ключах
- если distinct содержит tables, то будет создан hash из таблиц, содержащих строки с ключом
- $.type[string/table] поменять значение элемента на строку (указать одну колонку) или таблицу
- ^таблица.columns[[название столбца]]
- таблица из одного столбца 'column' или как передадут
- ^таблица.cells[], ^таблица.cells(лимит)
- выдает массив ячеек текущей строки
- ^таблица.array[]
- возвращает массив, элементами которого являются хеши, отображающие данные каждой строки
- ^таблица.array[колонка]
- возвращает массив значений указанной колонки
- ^таблица.array{код}
- возвращает массив результатов выполнения переданного кода для каждой строки таблицы
- ^таблица.rename[название столбца;новое навание столбца] ^таблица.rename[ $.название столбца[новое навание столбца] ]
- переименовывает столбец или столбцы
- $отобранное[^таблица.select(выражение)]
- таблица из тех столбцов и строк, у которых условие совпало
+ bind associates variables in the query with their values
+ currently implemented only for oracle
+ in the query you need to write ":name"
+ in the bind parameter pass a hash from which the value is taken (or where it is written)
+ ^table.save[[nameless|append;]path[;options, see load]]
+ saves the table to a file
+ ^table.menu{body}[[delimiter]]
+ executes the body code for each row of the table
+ ^table.foreach[position;value]{body}[[delimiter]]
+ ^table.line[]
+ current table row, starting from 1
+ ^table.offset[]
+ offset of the current row from the start, starting from 0
+ ^table.offset[[whence]](5)
+ shifts whence=cur|set, without whence = cur
+ ^table.count[], ^table.count[rows]
+ number of rows in the table
+ ^table.count[columns]
+ number of columns
+ ^table.count[cells]
+ number of cells in the current row
+ ^table.sort{{string-key-maker}|(numeric-key-maker)}[{desc|asc}] default=asc
+ ^table.append{data}
+ ^table.append[ $.column_name[column_value] ]
+ ^table.insert{data} add a record at the current position
+ ^table.insert[ $.column_name[column_value] ]
+ ^table.delete[]
+ deletes the record at the current position
+ ^table.join[table][$.limit(1) $.offset(5) $.offset[cur]]
+ adds records from the table, tables must have the same structure
+ ^table.flip[]
+ returns the transposed version
+ ^table.locate[field;value][[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
+ moves the current row if found. returns bool
+ ^table.locate(logical expression)[[$.limit(1) $.offset(5) $.offset[cur] $.reverse(1)]]
+ moves the current row if found. returns bool
+ ^table.hash{[field]|{code}|(expression)}[[value field(s)|table of value fields]{value code}][[$.distinct(1) $.distinct[tables] $.type[hash]]]
+ by default $hash.key value is a hash where value fields are keys
+ value fields may not be specified, then they are all columns including the key
+ if distinct is true, no error if duplicate keys
+ if distinct is tables, a hash of tables is created, containing rows with that key
+ $.type[string/table] changes the element value to a string (specify one column) or a table
+ ^table.columns[[column name]]
+ table of one column 'column' or as provided
+ ^table.cells[], ^table.cells(limit)
+ returns an array of cells of the current row
+ ^table.array[]
+ returns an array of hashes, each hash representing the data of one row
+ ^table.array[column]
+ returns an array of values from the specified column
+ ^table.array{code}
+ returns an array of results from executing the given code for each row
+ ^table.rename[column name;new column name] ^table.rename[ $.column_name[new column name] ...]
+ renames a column or multiple columns
+ $selected[^table.select(expression)]
+ a table from those columns and rows where the condition matched
$adults[^man.select($man.age>=18)]
- ^таблица.color[цвет1;цвет2]
- чередует цвет1 и цвет2 последовательно для каждого ряда
+ ^table.color[color1;color2]
+ alternates color1 and color2 for each row
hash
- в выражении
- логическое значение равно "не пуст?", хеш с _default уже не пуст
- числовое значение равно count[]
- $хеш.ключ
- _default - специальный ключ, если задан,
- то при обращении по ключу, которому нет соответствия, выдаётся _default значение
- $хеш.fields
- выдает $hash, чтобы класс hash был чуть больше похож на класс table
+ in expression
+ logical value means "not empty?", a hash with _default is already not empty
+ numerical value equals count[]
+ $hash.key
+ _default - a special key, if defined,
+ then when accessing a non-existing key, _default value is returned
+ $hash.fields
+ returns $hash, making hash class more similar to table class
^hash::create[[|copy_from_hash|copy_from_hashfile]]
- создаёт новый hash, копию старого
- ^хеш.add[слагаемое]
- перезаписывает одноимённые
- ^хеш.sub[вычитаемое]
- ^хеш.union[b]
- объединение, одноимённые остаются
- ^хеш.intersection[b][[$.order[self|arg]]]
- пересечение, новый хеш, order задает порядок элементов (как в исходном хеше или хеше-параметре)
- ^хеш.intersects[b] = bool
- ^hash::sql{запрос}[[$.distinct(1) $.limit(2) $.offset(4) $.type[hash|string|table]]]
- получается hash(ключи=значения первая колонка ответа) of hash(ключи=названия остальных колонкок ответа) или
- string=значение каждого элемента - строка, при этом надо указать ровно два столбца или
- table=значение каждого элемента - таблица
- ^хеш.keys[[название колонки с ключами]]
- таблица из одного столбца key или как передадут
- ^хеш.count[]
- ^хеш.foreach[key;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
- ^хеш.delete[ключ]
- удалить ключ
- ^хеш.contain[ключ]
- существует ли в хеше ключ (bool)
- ^хеш.at[first|last][[key|value|hash]]
- ^хеш.at([-]N)[[key|value|hash]]
- доступ к заданным элементам упорядоченного хеша
- ^хеш.set[first|last;значение]
- ^хеш.set([-+]N)[значение]
- устанавливает значение заданного элемента упорядоченного хеша
- ^хеш.rename[старый_ключ;новый_ключ]
- ^хеш.rename[ $.старый_ключ[новый_ключ] ... ]
- переименовывает заданные ключи хеша
- ^хеш.sort[key;value]{{ключеделатель строка}|(ключеделатель число)}[[desc|asc]] default=asc
- $обратный_хеш[^хеш.reverse[]]
- $отобранное[^хеш.select[key;value](выражение)[ $.limit(N) $.reverse(bool) $.default(bool) ]]
- хеш из ключей и значений, для которых условие истинно
+ creates a new hash, a copy of the old one
+ ^hash.add[term]
+ overwrites entries with the same name
+ ^hash.sub[subtracted]
+ ^hash.union[b]
+ union, same-named remain
+ ^hash.intersection[b][[$.order[self|arg]]]
+ intersection, new hash, order defines the element order (as in the source hash or parameter hash)
+ ^hash.intersects[b] = bool
+ ^hash::sql{query}[[$.distinct(1) $.limit(2) $.offset(4) $.type[hash|string|table]]]
+ results is hash(keys = values of the first column of the response) of hash(keys = names of the other columns), or
+ string = each element's value is a string (need exactly two columns), or
+ table = each element's value is a table
+ ^hash.keys[[name of key column]]
+ a table of one 'key' column or as provided
+ ^hash.count[]
+ ^hash.foreach[key;value]{body}[[delimiter]|{delimiter executed before each non-empty non-first body}]
+ ^hash.delete[key]
+ delete key
+ ^hash.contain[key]
+ checks if hash contains a key (bool)
+ ^hash.at[first|last][[key|value|hash]]
+ ^hash.at([-]N)[[key|value|hash]]
+ access specified elements of an ordered hash
+ ^hash.set[first|last;value]
+ ^hash.set([-+]N)[value]
+ sets the value of the specified ordered hash element
+ ^hash.rename[old_key;new_key]
+ ^hash.rename[ $.old_key[new_key] ...]
+ renames the specified hash keys
+ ^hash.sort[key;value]{{string-key-maker}|(numeric-key-maker)}[[desc|asc]] default=asc
+ $reversed_hash[^hash.reverse[]]
+ $selected[^hash.select[key;value](expression)[ $.limit(N) $.reverse(bool) $.default(bool) ]]
+ a hash of keys and values for which the condition is true
hashfile
^hashfile::open[filename]
- ^хешфайл.clear[]
- забыть всё
- $хешфайл.ключ[значение]
- положить значение
- $хешфайл.ключ[$.value[значение] $.expires[ЗНАЧЕНИЕ]}
- положить значение до expires
- значение поля expires может быть date, или число дней(0дней=на вечно)
- $хешфайл.ключ достать
- ^хешфайл.delete[ключ] удалить ключ
- ^хешфайл.delete[] удалить файлы, содержащие данные
- ^хешфайл.hash[]
- преобразовать в обычный hash
- попутно стирает устаревшие пары
- ^хешфайл.foreach[key;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
- ^хешфайл.release[]
- записать данные и снять блокировки
- при повторном обращении к элементам откроется автоматически
- ^хешфайл.cleanup[]
- пробежаться по всем элементам и удалить устаревшие.
+ ^hashfile.clear[]
+ forget all
+ $hashfile.key[value]
+ put value
+ $hashfile.key[$.value[value] $.expires[VALUE]]
+ put value until expires
+ expires can be a date, or number of days (0days=forever)
+ $hashfile.key retrieve
+ ^hashfile.delete[key] delete key
+ ^hashfile.delete[] delete files containing data
+ ^hashfile.hash[]
+ convert to a regular hash
+ removing expired pairs along the way
+ ^hashfile.foreach[key;value]{body}[[delimiter]|{delimiter executed before each non-empty non-first body}]
+ ^hashfile.release[]
+ write data and release locks.
+ next access to elements will reopen automatically.
+ ^hashfile.cleanup[]
+ iterate all elements and delete expired ones.
- пример:
+ example:
$sessions[^hashfile::open[/db/sessions]]
$sid[^math:uuid[]]
$sessions.$sid[$.value[$uid] $.expires(1)]
$uid[$sessions.$sid]
-
array
- в выражении
- логическое значение равно "не пуст?"
- числовое значение равно count[]
- $массив.индекс, $массив.(выражение)
- возврат значения по заданному индексу
- $массив.индекс[значение], $массив.(выражение)[значение]
- присваивание значения по индексу
- $массив[значение;значение;...]
- создание массива с заданными значениями
+ in expression
+ logical value means "not empty?"
+ numerical value equals count[]
+ $array.index, $array.(expression)
+ returns the value at the given index
+ $array.index[value], $array.(expression)[value]
+ assigns a value by index
+ $array[value;value;...]
+ creates an array with the given values
^array::create[]
- ^array::create[значение;значение;...]
- создание массива с заданными значениями или пустого массива
- ^array::copy[копируемый массив или хеш с цифровыми ключами]
- копирование массива или хеша с цифровыми ключами
- ^массив.add[добавляемый массив или хеш с цифровыми ключами]
- добавление элементов из другого массива или хеша с перезаписью значений у совпадающих индексов
- ^массив.join[добавляемый массив или произвольный хеш]
- добавление элементов другого массива или хеша в конец массива
- ^массив.append[значение;значение;...]
- добавление элементов в конец массива
- ^массив.insert(индекс)[значение;значение;...]
- вставка элементов в указанную позицию массива
- ^массив.left(n)
- возвращает новый массив из n первых элементов массива
- ^массив.right(n)
- возвращает новый массив из n последних элементов массива
- ^массив.mid(m;n)
- возвращает новый массив, содержащий n инициализированных элементов массива, начиная с позиции m
- ^массив.delete(index)
- удаление элемента массива с оставлением пустого места
- ^массив.remove(index)
- удаление элемента со сдвигом последующих элементов на его место
- ^массив.push[значение]
- добавление элемента в конец массив
- ^массив.pop[]
- возвращает последний элемент и удаляет его из массива
- ^массив.contain(индекс)
- существует ли в массиве элемент по переданому индексу (bool)
- ^array::sql{запрос}[[ $.sparse(false) $.distinct(false) $.limit(2) $.offset(4) $.type[hash|string|table]]]
- создание массива на основе выборки из базы данных
- $.sparse(false), по умолчанию - создать обычный массив. Значения строк выборки последовательно добавляются в массив
- $.sparse(true) - создать разреженный массив. Первая колонка данных должна содержать индексы,
- по которым будут размещены значения (аналогично ^hash::sql{})
- получается array of hash (ключи=названия остальных колонкок ответа) или
- string = значение каждого элемента - строка, при этом надо указать ровно два столбца или
- table = значение каждого элемента - таблица
- ^массив.keys[[название колонки с ключами]]
- таблица из одного столбца key или переданного названия с индексами инициализированных элементов массива
- ^массив.count[]
- количество инициализированных элементов массива
- ^массив.count[all]
- общее количество элементов массива, включая неинициализированные
- ^массив.foreach[index;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
- перебирает все инициализированные элементы массива
- ^массив.for[index;value]{тело}[[разделитель]|{разделитель который выполняется перед непустым очередным не первым телом}]
- перебирает все элементы массива
- ^массив.at[first|last][[key|value|hash]]
- ^массив.at([-]число)[[key|value|hash]]
- доступ к элементу массива по порядковому номеру
- ^массив.set[first|last][значение]
- ^массив.set([-]число)[значение]
- установка значения элемента массива по порядковому номеру
- ^массив.compact[]
- удаление неинициализированных элементов массива
- ^массив.compact[undef]
- удаление неинициализированных и пустых элементов массива
- ^массив.sort[key;value]{{ключеделатель строка}|(ключеделатель число)}[[desc|asc]] default=asc
- сортировка массива
- $обратный_массив[^массив.reverse[]]
- возвращает новый массив из элементов исходного в обратном порядке
- $отобранное[^массив.select[key;value](выражение)[ $.limit(N) $.reverse(bool) ]]
- отбор элементов массива, для которых условие истинно
+ ^array::create[value;value;...]
+ creates an array with the given values or an empty array
+ ^array::copy[array or hash with numeric keys]
+ copies an array or a hash with numeric keys
+ ^array.add[array or hash with numeric keys]
+ adds elements from another array or hash, overwriting values for matching indexes
+ ^array.join[array or any hash]
+ appends elements from another array or hash to the end of the array
+ ^array.append[value;value;...]
+ appends elements to the end of the array
+ ^array.insert(index)[value;value;...]
+ inserts elements at the specified position in the array
+ ^array.left(n)
+ returns a new array of the first n elements
+ ^array.right(n)
+ returns a new array of the last n elements
+ ^array.mid(m;n)
+ returns a new array containing n initialized elements starting from position m
+ ^array.delete(index)
+ deletes an array element, leaving an empty spot
+ ^array.remove(index)
+ deletes an element and shifts subsequent elements to fill the gap
+ ^array.push[value]
+ adds an element to the end of the array
+ ^array.pop[]
+ returns the last element and removes it from the array
+ ^array.contain(index)
+ checks if an element exists at the given index (bool)
+ ^array::sql{query}[ $.sparse(false|true) $.distinct(false|true) $.limit(n) $.offset(n) $.type[hash|string|table] ]
+ creates an array based on a database query
+ $.sparse(false), default - create a normal array. Row values from the query are added sequentially
+ $.sparse(true) - create a sparse array. The first column must contain indexes
+ at which values will be placed (similar to ^hash::sql{})
+ result is an array of hash (keys=column names of the rest of the answer) or
+ string = each element's value is a string (need exactly two columns), or
+ table = each element's value is a table
+ ^array.keys[[column name for keys]]
+ a table of one 'key' column (or as provided) with the indexes of initialized elements
+ ^array.count[]
+ the number of initialized elements in the array
+ ^array.count[all]
+ the total number of elements, including uninitialized ones
+ ^array.foreach[index;value]{code}[[delimiter]|{delimiter executed before each non-empty non-first body}]
+ iterates over all initialized elements
+ ^array.for[index;value]{code}[[delimiter]|{delimiter executed before each non-empty non-first body}]
+ iterates over all elements
+ ^array.at[first|last][[key|value|hash]]
+ ^array.at([-]number)[[key|value|hash]]
+ accesses an array element by its ordinal number
+ ^array.set[first|last][value]
+ ^array.set([-]number)[value]
+ sets the value of an array element by ordinal number
+ ^array.compact[]
+ removes uninitialized elements
+ ^array.compact[undef]
+ removes uninitialized and empty elements
+ ^array.sort[key;value]{{string-key-maker}|(numeric-key-maker)}[[desc|asc]] default=asc
+ sorts the array
+ $reversed_array[^array.reverse[]]
+ returns a new array with elements in reverse order
+ $selected[^array.select[key;value](expression)[ $.limit(N) $.reverse(bool) ]]
+ selects array elements for which the condition is true
+
+date
+ date type can be used in expressions, substituting the number of days since epoch [1 January 1970 (UTC)], fractional
+ the string value is in local time, numerically in UTC, range from 0000-00-00 00:00:00 to 9999-12-31 23:59:59
+ by default the OS-defined timezone is used
+
+ ^date::now[]
+ ^date::now(days offset)
+ returns now+offset
+ ^date::today[]
+ date at 00:00:00 of the current day
+ ^date::today(integer days offset)
+ date at 00:00:00 of current day+offset
+ ^date::create(days since epoch)
+ ^date::create(year;month[;day[;hour[;minute[;second[;TZ]]]]])
+ ^date::create[date in format %Y-%m-%d %H:%M:%S]
+ convenient creation from a value from a database
+ format1: %Y[-%m[-%d[ %H[:%M[:%S]]]]]
+ format2: %H:%M[:%S]
+ ^date::create[date in format %Y-%m-%dT%H:%M[:%S]TZ]
+ for creation from ISO 8601 format
+ TZ format: Z(UTC) or +-hour[:minute] (offset from UTC)
+ ^date::unix-timestamp()
+ ^date.unix-timestamp[]
+ $date.year month day hour minute second weekday yearday(0...) daylightsaving TZ weekyear
+ TZ="" << local zone
+ $date.year month day hour minute second can be set to new values, others are read-only
+ ^date.double[] ^date.int[]
+ the number of days since epoch [1 January 1970 (UTC)], fractional or truncated
+ ^date.roll[year|month|day](+-offset)
+ shifts the date
+ ^date.roll[TZ;New zone]
+ says that the date is in such a timezone: affects .hour & Co
+ ^date:roll[TZ;New zone]
+ says that by default all dates are in that timezone
+ ^date.sql-string[[datetime|date|time]]
+ datetime or without parameter - %Y-%m-%d %H:%M:%S
+ date - %Y-%m-%d
+ time - %H:%M:%S
+ where published='^date.sql-string[]'
+ ^date:calendar[rus|eng](year;month)
+ returns an unnamed table, columns: 0..6, week, year
+ ^date:calendar[rus|eng](year;month;day)
+ returns a named table, columns: year, month, day, weekday
+ ^date:last-day(year;month)
+ returns the last day of the month
+ ^date.last-day[]
+ returns the last day of $date's month
+ ^date.gmt-string[]
+ Fri, 23 Mar 2001 09:32:23 GMT
+ ^date.iso-string[]
+ 2001-03-23T12:32:23+03
+
+file
+ $uploaded_file_from_post.name
+ $uploaded_file_from_post.size
+ $uploaded_file_from_post.text
+ ^file.save[text|binary;filename[;$.charset[which charset to save in]]]
+ ^file:delete[filename]
+ ^file:find[filename][{if not found}]
+ ^file:list[path[;pattern-string|pattern-regex]]
+ table with columns name dir
+ ^file:list[path;$.filter[pattern-string|pattern-regex] $.stat(true)]
+ table with columns name dir size [mca]date
+ ^file::load[text|binary;big.zip[;domain_press_release_2001_03_01.zip][;options]]
+ ^file::create[text|binary;filename;data]
+ ^file::create[text|binary;filename;data[;$.charset[charset of the created file] $.content-type[...]]]
+ ^file::create[string-or-file-content[;$.name[name] $.mode[text|binary] $.content-type[...] $.charset[...]]]
+ $loaded_file.size
+ $loaded_or_created_file.mode = text/binary
+ ^file::stat[filename]
+ $stated_or_loaded_file.size .adate .mdate .cdate
+ ^file::cgi[[text|binary;]filename[;env hash +options[;1cmd[;2line[;3ar[;4g[;5s]]]]]]]
+ any argument can be string or array of strings
+ the returned header is split into $fields
+ $status
+ $stderr
+ ^file::exec[[text|binary;]filename[;env hash[;1cmd[;2line[;3ar[;4g[;5s;...under unix max 50 args]]]]]]]
+ any argument can be string or array of strings
+ options:
+ $.stdin[text|file] if empty, disables automatic passing of HTTP-POST data
+ ^file:move[oldfilename;newfilename]
+ can rename and move directories [win32: but not across disk boundaries]
+ directories for dest are created with 775 permissions
+ source directory is removed if empty after move
+ ^file:copy[filename;copy_filename[; $.append(1) ]]
+ can only copy files
+ ^file:lock[filename]{code}
+ the file is created if necessary
+ locked
+ code executed
+ unlocked
+ ^file:dirname[/a/some.tar.gz|file]=/a (works like *nix command)
+ ^file:dirname[/a/b/|file]=/a (works like *nix command)
+ ^file:basename[/a/some.tar.gz|file]=some.tar.gz (like *nix)
+ ^file:basename[/a/b/|file]=b (like *nix)
+ ^file:justname[/a/some.tar.gz|file]=some.tar
+ ^file:justext[/a/some.tar.gz|file]=gz
+ /some/page.html: ^file:fullpath[a.gif] => /some/a.gif
+ ^file.sql-string[]
+ inside ^connect gives a correctly escaped string that can be used in queries
+ ^file::sql{query}[[ $.name[filename_for_download] $.content-type[user content-type] ]]
+ the query result should be "one row".
+ columns:
+ first column - data
+ if second exists - filename
+ if third - content-type
+ ^file.base64[ $.pad(bool) $.wrap(bool) $.url-safe(bool) ]
+ encode
+ ^file:base64[filename[; $.pad(bool) $.wrap(bool) $.url-safe(bool) ]]
+ encode
+ ^file::base64[encoded string[; $.pad(bool) $.strict(bool) $.url-safe(bool) ]]
+ decode
+ ^file::base64[mode;filename;encoded string[; $.content-type[...] $.pad(bool) $.strict(bool) $.url-safe(bool) ]]
+ decode
+ ^file:crc32[filename]
+ calculates crc32 of the specified file
+ ^file.crc32[]
+ calculates crc32 of the object
+ ^file.md5[], ^file:md5[filename]
+ returns the file's digest, 16 bytes as a string,
+ bytes in hex, contiguous, lowercase
+
+image
+ $image[^image::measure[DATA[; $.exif(bool) $.xmp(bool) $.xmp-charset[] $.video(bool) ]]]
+ checks the file extension case-insensitively
+ can measure gif, jpg, tiff, bmp, webp and mp4 (mov)
+ $image.exif << hash after measure jpeg with exif information and $.exif(true)
+ $image.exif.DateTime & co
+ [full list see https://exiftool.org/TagNames/EXIF.html]
+ numbers as int/double,
+ dates as date,
+ enumerations as hash with keys 0..count-1
+ $image.src .width .height
+ $image.line-width number=line width
+ $image.line-style string=line style '*** * '='*** * *** * *** * '
+ ^image.html[[hash]]
+
+ ^image::load[background.gif]
+ only gif so far
+ ^image::create(width X;height Y[;background color default white]])
+ ^image.line(x0;y0;x1;y1;0xffFFff)
+ ^image.fill(x;y;0xffFFff)
+ ^image.rectangle(x0;y0;x1;y1;0xffFFff)
+ ^image.bar(x0;y0;x1;y1;0xffFFff)
+ ^image.replace(hex-color1;hex-color2)[table x:y polygon_vertices]
+ ^image.polyline(color)[table x:y points]
+ ^image.polygon(color)[table x:y polygon_vertices]
+ ^image.polybar(color)[table x;y polygon_vertices]
+ ^image.font[set_of_letters;font_file.gif][(space_width[;char_width])]
+ the character height = image height/number of letters in the set
+ if char_width is specified, then monospaced, if 0, char_width = gif width
+ ^image.font[set_of_letters;font_file.gif;
+ $.space(space_width) // default = gif width
+ $.width(char_width) // see above, default proportional
+ $.spacing(letter_spacing) // default = 1
+ ]
+ ^image.text(x;y)[text] AS_IS
+ ^image.length[text] AS_IS
+ ^image.gif[optional filename]
+ encodes to FILE with content-type=image/gif the filename will be used by $response:download
+ ^image.arc(center x;center y;width;height;start in degrees;end in degrees;color)
+ ^image.sector(center x;center y;width;height;start in degrees;end in degrees;color)
+ ^image.circle(center x;center y;r;color)
+ ^image.copy[source](src x;src y;src w;src h;dst x;dst y[;dest w[;dest h[;tolerance]]])
+ if dest_w/dest_h are specified, resizes the piece
+ when reducing size, does resample
+ only suitable for simplifying low-color graphics like charts/pie,
+ not suitable for thumbnails
+ if dest_h is not specified, aspect ratio is kept
+ tolerance - a number [square distance in RGB space to the target color],
+ defining how greedy the color approximation from the palette is [default=150]
+ smaller - more accurate but colors run out quickly
+ larger - less accurate approximation, but covers a bigger part
+ ^image.pixel(x;y)[(color)]
+ get or set pixel color
+
+regex
+ in expression
+ logical value is always true
+ numerical value is equal to the number of bytes of the compiled pattern
+ ^regex::create[pattern-string|regex][[search options]]
+ ^pattern.size[]
+ number of bytes of the compiled pattern
+ if the value is very large - it is worth consulting pcre documentation and possibly rewriting the pattern
+ ^pattern.study_size[]
+ size of the study-structure. if == 0 - the pattern cannot be "studied"
+ $pattern.pattern
+ the text of the pattern
+ $pattern.options
+ the string with the original text of the options
+
+console
+ $console:timeout
+ $console:line
+ read/write string
+
+cookie
+ $cookie:name read old or newly set cookie
+ $cookie:name[value] for 90 days
+ $cookie:name[$.value[value] $.expires[VALUE] $.secure(true) $.domain[domain name] $.httponly(true)]
+ the expires field value can be 'session', a date, or a number of days (0days=forever)
+ if it's a date, it will be converted to "Sun, 25-Aug-2002 12:03:45 GMT"
+ $cookie:fields
+ hash with all cookies
+
+curl
+ ^curl:load[[
+ $.url[http://URL]
+ $.timeout(N)
+ $.ssl_verifypeer(0)
+ $.mode[text|binary] type of the created file
+ ]]
+ downloads a file from a remote server, can be called multiple times within one session;
+ any libcurl option can be specified, option names in lowercase without the CURLOPT_ prefix
+ ^curl:options[[
+ $.library[libcurl.so.4]
+ $.charset[UTF-8]
+ ...
+ ]]
+ subsequent ^curl:load calls inherit the specified options, the path to libcurl must be set before using curl
+ ^curl:session{code}
+ creates a cURL session, common options can be set, multiple downloads performed
+ ^curl:info[name], ^curl:info[]
+ information about the last request (a value or a hash)
+ ^curl:version[]
+ the version of the cURL library in use
+
+env
+ $env:variable
+ $env:fields hash with environment variables
+ $env:PARSER_VERSION parser version
form
- [берётся первый элемент из одноимённых из GET, потом первый из POST]
- $form:поле
+ [the first element with the same name is taken from GET, then from POST]
+ $form:field
string/file
$form:nameless
- поле со значением поля без имени "?value&...", "...&value&...", "...&value"
+ field with a value from a nameless parameter "?value&...", "...&value&...", "...&value"
$form:qtail
- строка со значением текста после второго "?xxxxx", если там не было ',' [imap]
+ string with the value after the second "?xxxxx" if there was no ',' [imap]
$form:fields
- hash со всеми полями формы
- $form:elements.поле
- array со всеми значениями поля - как строковыми, так и файловыми
- $form:tables.поле
- table с одним столбцом "field" со значениями "поля", для множественных значений
- $form:files.поле
- hash со значениями полей типа файл, ключи - 0, 1, ..., значение - файл
+ hash with all form fields
+ $form:elements.field
+ array with all values of the field - both string and file
+ $form:tables.field
+ table with one column "field" containing the values for multiple entries
+ $form:files.field
+ hash with file-type field values, keys - 0, 1, ..., value - file
$form:imap
- хеш с ключами 'x' и 'y' со значением ?1,2 приписки при использовании server-site image map
+ a hash with keys 'x' and 'y' with ?1,2 suffixes when using server-side image map
-env
- $env:переменная
- $env:fields хеш с переменными окружения
- $env:PARSER_VERSION версия парсера
-
-cookie
- $cookie:имя считать старое или свежезаданное
- $cookie:имя[значение] на 90 дней
- $cookie:имя[$.value[значение] $.expires[ЗНАЧЕНИЕ] $.secure(true) $.domain[имя домена] $.httponly(true)]
- значение поля expires может быть 'session', date, или число дней (0дней=session)
- если дата, она будет преобразована к формату "Sun, 25-Aug-2002 12:03:45 GMT"
- $cookie:fields
- hash со всеми cookies
-
-request
- $request:query
- $request:uri
- $request:document-root
- каталог, относительно которого считаются пути в parser, по-умолчанию = $env:DOCUMENT_ROOT
- $request:argv
- hash с параметрами коммандной строки. ключи 0, 1, ... [0 -- имя обрабатываемого файла]
- $request:charset
- кодировка исходного документа
- используется при upper/lower и match[][i]
- ПРЕДУПРЕЖДЕНИЕ: необходимо задать $request/response:charset до использования полей класса form
- $request:method
- метод запроса (GET|POST|PUT)
- $request:body
- тело POST-запроса в виде текста
- $request:body-file
- тело POST-запроса в виде файла
- $request:body-charset
- кодировка POST-запроса
- $request:headers
- хеш с заголовками запроса (без префикса HTTP_)
-
-response
- $response:поле[значение] и можно считать старое - $response:поле
- значение может быть string а может быть hash:
- $value[abc] field: {abc}<<часть
- $attribute[zzz] field: abc; {attribute=zzz}<<часть
- значение поля или атрибута может быть string или date
- если дата, она будет преобразована к формату "Sun, 25-Aug-2002 12:03:45 GMT"
- $response:headers
- накопленные поля
- $response:body[DATA]
- замещает стандартный ответ
- $response:download[DATA]
- замещает стандартный ответ, выставляет флаг, заставляющий browser предложить download
- $response:status
- ^response:clear[] забыть все заданные response поля
- $response:charset
- кодировка клиента т.е. та,
- 1) из которой будут перекодированы $form:поля после забирания из browser'а
- 2) в которую документ будет перекодирован перед отдаванием в browser
- 3) в которую будет перекодирован текст языка uri
- не добавляет к content-type ничего, если хочется, это надо сделать вручную
- ПРЕДУПРЕЖДЕНИЕ: необходимо задать $request/response:charset до использования полей класса form
+inet
+ ^inet:ntoa(long)
+ ^inet:aton[IP]
+ ^inet:name2ip[name][[ $.ipv[4|6|any] $.table(true) ]]
+ direct conversion of a name to an IP address
+ ^inet:ip2name[ip][ $.ipv[4|6|any] ]
+ reverse conversion from IP address to name
+ ^inet:hostname[]
+ host name
-regex
- в выражении
- логическое значение всегда равно true
- числовое значение равно количеству байт скомпилированного шаблона
- ^regex::create[шаблон-строка|regex][[опции поиска]]
- ^шаблон.size[]
- количество байт скомпилированного шаблона
- если значение очень большое - стоит почитать документацию по pcre и, возможно, переписать шаблон
- ^шаблон.study_size[]
- размер study-структуры. если==0 - шаблон не может быть "изучен"
- $шаблон.pattern
- текст шаблона
- $шаблон.options
- строка с исходным текстом опций
+json
+ ^json:parse[-json-string-[;
+ $.depth(maximum depth, default == 19)
+ $.double(false) disable built-in parsing of floating-point numbers (enabled by default)
+ in this case they will appear in the resulting object as strings
+ $.int(false) disable built-in parsing of integers (enabled by default)
+ in this case they will appear in the resulting object as strings
+ $.distinct[first|last|all] how duplicate keys in objects are handled
+ first - keep the first encountered element
+ last - keep the last encountered element
+ all - keep all elements. starting from the 2nd,
+ they get numeric suffixes (key_2 etc)
+ by default duplicate keys cause an exception
+ $.object[method-junction] user method[key;object], called for all parsed
+ objects and object keys; method returns a new object
+ $.array[method-junction] user method called for arrays
+ $.taint[taint language] sets the transformation language for all result strings
+ ]]
+ parses a json-string into a hash
-reflection
- ^reflection:create[класс;конструктор[;пара[;мет[;ры]]]]
- вызывает указанный конструктор класса (не более 100 параметров)
- ^reflection:create[ $.class[name] $.constructor[name] $.arguments[ $.1[па] $.2[рам] $.3[етры] ] ]
- вызывает указанный конструктор класса
- ^reflection:classes[]
- хеш со всеми классами. ключ = имя класса, значение бывает methoded (класс с методами) или void
- ^reflection:class[объект]
- класс переданного объекта
- ^reflection:class_name[объект]
- имя класса переданного объекта
- ^reflection:base[объект]
- родительский класс переданного объекта
- ^reflection:base_name[объект]
- имя родительского класса переданного объекта
- ^reflection:class_by_name[имя класса]
- получение класса по имени
- ^reflection:class_alias[имя класса;новое имя класса]
- задает псевдоним для указанного класса
- ^reflection:def[class;имя класса]
- проверка класса на существование
- ^reflection:methods[класс]
- хеш со списком методов указанного класса, значения - строки 'native' или 'parser'
- ^reflection:method[класс или объект;имя метода]
- возвращает junction-method класса или объекта
- ^reflection:filename[объект или класс или метод]
- возвращает имя файла, где определен объект, класс или метод
- ^reflection:fields[класс или объект]
- хеш со списком статических полей указанного класса или динамических полей указанного объекта
- ^reflection:fields_reference[объект]
- редактируемый хеш динамических полей указанного объекта
- ^reflection:field[класс или объект;имя поля]
- возвращает значение указанного поля класса или объекта. getter-ы игнорируются.
- ^reflection:copy[источник;назначение]
- копирует поля из одного объекта или класса в другой
- ^reflection:uid[класс или объект]
- возвращает идентификатор объекта или класса
- ^reflection:method_info[класс;метод]
- хеш с параметрами указанного метода класса
- $.inherited[класс] имя класса, где метод был определён (возвращается только если метод был определён в предке)
- $.overridden[класс] имя класса, где метод был определён (возвращается только если метод был определён в предке)
- для native классов возвращается хеш:
- .min_params(минимально необходимое число параметров)
- .max_params(максимально возможное число параметров)
- .call_type[dynamic|static|any]
- для parser классов возвращается хеш:
- ключ - номер параметра (0, 1, ...), значение - имя параметра
- ^reflection:dynamical[[object or class, caller if absent]]
- возвращает true, если метод был вызван из динамического контекста при передаче
- параметра возвращает true, если передан динамический объект, false если класс
- ^reflection:delete[класс или объект;имя переменной]
- удаляет переменную с указанным именем в указанном классе или объекте
- ^reflection:is[имя элемента;имя класса][[контекст]]
- аналог оператора 'is', позволяющий определить, является ли элемент кодом.
- ^reflection:tainting[[язык|tainted|optimized];строка]
- строка, в которой каждому символу исходной строки соотвествует символ с кодом преобразования
- ^reflection:stack[ $.args(false/true) $.locals(false/true) $.limit(n) $.offset(o)]
- текущее состояние стека вызовов методов на парсере
- ^reflection:mixin[источник; $.to[получатель] $.name[имя] $.methods(true/false) $.fields(true/false) $.overwrite(false/true) ]
- копирует в класс методы и поля другого класса
+ ^json:string[system or user object[;
+ $.skip-unknown(false) disable exception and output 'null' when serializing objects of types
+ other than void, bool, string, int, double, date, table, hash, and file
+ $.indent(true) format the resulting string with indentation according to nesting depth
+ $.date[sql-string|gmt-string|iso-string|unix-timestamp]
+ date output format, default = sql-string
+ $.table[object|array|compact]
+ format for tables, default=object
+ object: [{"c1":"v11","c2":"v12",...},{"c1":"v21","c2":"v22",...},...]
+ array: [["c1","c2",...] || null (for nameless),["v11","v12",...],...]
+ compact: ["v11" || ["v11","v12",...],...]
+ $.file[text|base64|stat] output file content in the specified mode (by default file content
+ is not included in output)
+ $.xdoc[hash] parameters for converting xdoc to string (as in ^xdoc.string[])
+ $.type[method-junction] any type can be output using a user method
+ that must take 3 parameters: key, object of that type, and options
+ of the ^json:string[] call
+ $._default[method] user method, called to output all user-class objects.
+ The method must take 3 parameters: key, object, and call options.
+ $._default[method name] method name of a user method, if present it will be called for serialization
+ $.void[null|string] undefined value will be output as null (default)
+ or as an empty string
+ ]]
+ serializes a system or user object into a json-string
mail
$mail.received=MESSAGE:
.from
.reply-to
.subject
- .date класса date
+ .date of class date
.message-id
.raw[
- .СЫРОЕ_ПОЛЬЗОВАТЕЛЬСКОЕ-ПОЛЕ-ЗАГОЛОВКА
+ .RAW_USER_HEADER_FIELD
]
- $.{text|html|file#}[ << нумеруется как и в mail:send (text, text2, ...) (file, file2, ...)
+ $.{text|html|file#}[ << numbered as in mail:send (text, text2, ...) (file, file2, ...)
$.content-type[
$.value[{text|...|x-unknown}/{plain|html|...|x-unknown}]
- [$.charset[windows-1251]] << в каком пришло, сейчас уже перекодировано
- $.ПОЛЬЗОВАТЕЛЬСКИЙ-ПАРАМЕТР-ЗАГОЛОВКА
+ [$.charset[windows-1251]] << in which it arrived, now already transcoded
+ $.USER_DEFINED_HEADER_FIELD
]
$.description
$.content-id
$.content-md5
$.content-location
.raw[
- .СЫРОЕ_ПОЛЬЗОВАТЕЛЬСКОЕ-ПОЛЕ-ЗАГОЛОВКА
+ .RAW_USER_HEADER_FIELD
]
- $.value[строка|FILE]
+ $.value[string|FILE]
]
$.message#[MESSAGE] (message, message2, ...)
^mail:send[
$.options[-odd]
- unix: строка, которая будет добавлена к команде запуска sendmail
- -odd означает "быстро поставь в очередь без проверки email"
- win32: игнорируется
- $.charset[кодировка заголовка и текстовых блоков]
+ unix: a string that will be added to the sendmail startup command
+ -odd means "quickly put in the queue without email checking"
+ win32: ignored
+ $.charset[the encoding of the headers and text blocks]
$.any-header-field
$.text[string]
$.text[
- $.any-header-field
- $.value[string]
+ $.any-header-field
+ $.value[string]
]
$.html{string}
$.html[
@@ -750,63 +901,63 @@ mail
$value[FILE]
]
]
- если charset указан, письмо перекодируется в этот charset
- content-type.charset не влияет на перекодирование
- после имени части может идти # число
+ if charset is specified, the email is transcoded to this charset
+ content-type.charset does not affect transcoding
+ after the part name a # number can follow
^mail:send[
-# по-умолчанию, совпадает с source encoding.
-# задаёт кодировку body
+# by default, matches the source encoding.
+# sets the body encoding
$.charset[windows-1251]
-# нет умолчания
+# no default
$.content-type[$.value[text/plain] $.charset[windows-1251]]
- $.from["вася" ]
- $.to["петя" ]
- $.subject[тема]
+ $.from["vasya" ]
+ $.to["petya" ]
+ $.subject[subject]
$.body[
- слова
+ text
]
]
- ^mail:send[$.header-field[] $.charset[кодировка письма] $.body[когда body не строка, а hash, отсылается multipart письмо]]
- если charset указан, письмо перекодируется в этот charset
- content-type.charset не влияет на перекодирование
- после имени части может идти целое число, части пойдут в порядке чисел.
- если body указан строкой, то это текст письма, никаких вложений.
- если body указан hash, то это части, будут собраны текстовые блоки, затем вложения
- это старый формат, поддерживается для обратной совместимости
- если имя части начинается со слова text, то это текстовый блок.
- если имя части начинается со слова file, то это вложение, формат задания:
+ ^mail:send[$.header-field[] $.charset[mail encoding] $.body[if body is not a string, but a hash, a multipart email is sent]]
+ if charset is specified, the email is transcoded to that charset
+ content-type.charset does not affect transcoding
+ after the part name, an integer can follow, parts go in numerical order.
+ if body is a string, then it's just the email text, no attachments.
+ if body is a hash, then these are parts, text blocks first, then attachments
+ this is the old format, supported for backward compatibility
+ if the part name begins with "text", it's a text block.
+ if the part name begins with "file", it's an attachment, format:
$file[$.format[uue|base64] $.value[DATA] $.name[user-file-name]]
- важно: при multipart не указывать content-type
+ important: for multipart do not specify content-type
^mail:send[
-# по-умолчанию, совпадает с source encoding
-# задаёт кодировку body
+# by default, matches the source encoding
+# sets the body encoding
$.charset[windows-1251]
-# нет умолчания
+# no default
$.content-type[$.value[text/plain] $.charset[windows-1251]]
- $.from["вася" ]
- $.to["петя" ]
- $.subject[тема]
+ $.from["vasya" ]
+ $.to["petya" ]
+ $.subject[subject]
$.body[
- слова
+ text
]
]
^mail:send[
- $.from["вася" ]
- $.to["петя" ]
- $.subject[тема]
+ $.from["vasya" ]
+ $.to["petya" ]
+ $.subject[subject]
$.body[
$.text[
-# задаёт кодировку body
+# sets the body encoding
$.charset[windows-1251]
-# нет умолчания
+# no default
$.content-type[$.value[text/plain] $.charset[windows-1251]]
- $.body[слова]
+ $.body[words]
]
-# для удобства можно указать только одну часть, при этом не будет multipart
+# for convenience you can specify only one part, then it won't be multipart
$.file[
$.value[^file::load[my beloved.doc]]
$.name[my beloved.doc]
@@ -818,138 +969,14 @@ mail
]
]
]
- для отправки под unix используется программа с параметрами, задаваемая
- $MAIL.sendmail[команда]
- если не будет задана, проверяется, доступна ли /usr/sbin/sendmail или
- /usr/lib/sendmail и, если доступна, то запускается с параметром "-t".
+ under unix, the program with arguments is used, set by
+ $MAIL.sendmail[command]
+ if not specified, checks if /usr/sbin/sendmail or
+ /usr/lib/sendmail is available and if so, runs with "-t".
- под Windows используется SMTP протокол, сервер задаётся
+ under Windows, SMTP protocol is used, server is set by
$MAIL.SMTP[smtp.domain.ru]
-image
- $картинка[^image::measure[DATA[; $.exif(bool) $.xmp(bool) $.xmp-charset[] $.video(bool) ]]]
- смотрит на .ext case insensitive,
- умеет мерить gif, jpg, tiff, bmp, webp и mp4 (mov)
- $картинка.exif << hash после measure jpeg с exif информацией и $.exif(true)
- $image.exif.DateTime & co
- [полный список см. https://exiftool.org/TagNames/EXIF.html]
- числа типа int/double,
- даты типа dateб
- перечисления в виде hash с ключами 0..count-1
- $картинка.src .width .height
- $картинка.line-width число=ширина линий
- $картинка.line-style строка=стиль линий '*** * '='*** * *** * *** * '
- ^картинка.html[[hash]]
-
- ^image::load[фон.gif]
- только gif пока
- ^image::create(размер X;размер Y[;цвет фона default белый]])
- ^картинка.line(x0;y0;x1;y1;0xffFFff)
- ^картинка.fill(x;y;0xffFFff)
- ^картинка.rectangle(x0;y0;x1;y1;0xffFFff)
- ^картинка.bar(x0;y0;x1;y1;0xffFFff)
- ^картинка.replace(hex-цвет1;hex-цвет2)[table x:y вершины_многоугольника]
- ^картинка.polyline(цвет)[table x:y точки]
- ^картинка.polygon(цвет)[table x:y вершины_многоугольника]
- ^картинка.polybar(цвет)[table x;y вершины_многоугольника]
- ^картинка.font[набор_букв;имя_файла_шрифта.gif][(ширина_пробела[;ширина_символа])]
- высота символа = высота картинки/количество букв в наборе
- если указана ширина_символа, то monospaced, если 0, то ширина_символа = ширине gif
- ^картинка.font[набор_букв;имя_файла_шрифта.gif;
- $.space(ширина_пробела) // по умолчанию = ширине gif
- $.width(ширина_символа) // см. выше, по умолчанию proportional
- $.spacing(расстояние между буквами) // по умолчанию = 1
- ]
- ^картинка.text(x;y)[текст_надписи] AS_IS
- ^картинка.length[текст_надписи] AS_IS
- ^картинка.gif[возможно, имя файла]
- кодирует в FILE с content-type=image/gif имя файла будет использовано при $response:download
- ^картинка.arc(center x;center y;width;height;start in degrees;end in degrees;color)
- ^картинка.sector(center x;center y;width;height;start in degrees;end in degrees;color)
- ^картинка.circle(center x;center y;r;color)
- ^картинка.copy[source](src x;src y;src w;src h;dst x;dst y[;dest w[;dest h[;tolerance]]])
- при заданных dest_w/dest_h делает изменение размера кусочка
- при уменьшении делает resample
- годится только для уменьшения простой[малоцветной] дребедени вроде графиков/pie,
- для thumbnais не годится
- при не указанном dest_h сохраняет aspect ratio
- tolerance - некое число[квадрат расстояния в RGB пространстве до искомого цвета],
- определяющее прожорливость выделялки цветов из палитры [default=150]
- меньше - точнее приближает цвета, но они быстро кончаются
- больше - неточно приближает цвет, но большей части хватит
- ^картинка.pixel(x;y)[(color)]
- узнать или задать цвет пиксела
-
-file
- $файл_из_post.name
- $файл_из_post.size
- $файлt_из_post.text
- ^файл.save[text|binary;имя файла[;$.charset[в какой кодировке сохраняем]]]
- ^file:delete[имя файла]
- ^file:find[имя файла][{когда не нашли}]
- ^file:list[путь[;шаблон-строка|шаблон-regex]]
- table с колонками name dir
- ^file:list[путь;$.filter[шаблон-строка|шаблон-regex] $.stat(true)]
- table с колонками name dir size [mca]date
- ^file::load[text|binary;big.zip[;domain_press_release_2001_03_01.zip][;опции]]
- ^file::create[text|binary;имя;data]
- ^file::create[text|binary;имя;data[;$.charset[кодировка букв в создаваемом файле] $.content-type[...]]]
- ^file::create[string-or-file-content[;$.name[имя] $.mode[text|binary] $.content-type[...] $.charset[...]]]
- $файл_который_был_loaded.size
- $файл_который_был_loaded_или_created.mode = text/binary
- ^file::stat[имя файла]
- $файл_который_был_stated_или_loaded.size .adate .mdate .cdate
- ^file::cgi[[text|binary;]имя файла[;env hash +options[;1cmd[;2line[;3ar[;4g[;5s]]]]]]]
- любой аргумент может быть строкой или массивом строк
- возвращённый заголовок рассыпается на $поля
- $status
- $stderr
- ^file::exec[[text|binary;]имя файла[;env hash[;1cmd[;2line[;3ar[;4g[;5s;...under unix max 50 args]]]]]]]
- любой аргумент может быть строкой или массивом строк
- options:
- $.stdin[текст|файл] если пусто, отключается автоматическое пересовывание данных HTTP-POST
- ^file:move[старое имя файла;новое имя файла]
- можно переименовывать и двигать каталоги[win32: но не через границу дисков]
- каталоги для dest создаются с правами 775
- каталог старого файла стирается, если после move он остаётся пуст
- ^file:copy[имя файла;имя копии файла[; $.append(1) ]]
- можно копировать только файлы
- ^file:lock[имя файла]{код}
- файл при необходимости создаётся
- блокируется
- выполняется код
- разблокируется
- ^file:dirname[/a/some.tar.gz|file]=/a (работает аналогично комманде *nix)
- ^file:dirname[/a/b/|file]=/a (работает аналогично комманде *nix)
- ^file:basename[/a/some.tar.gz|file]=some.tar.gz (работает аналогично комманде *nix)
- ^file:basename[/a/b/|file]=b (работает аналогично комманде *nix)
- ^file:justname[/a/some.tar.gz|file]=some.tar
- ^file:justext[/a/some.tar.gz|file]=gz
- /some/page.html: ^file:fullpath[a.gif] => /some/a.gif
- ^файл.sql-string[]
- внутри ^connect даст правильно escaped строку, которую можно в запрос отдать
- ^file::sql{query}[[ $.name[имя_файла_для_download] $.content-type[пользовательский content-type] ]]
- результат запроса должен быть "одна строка".
- колонки:
- первая колонка - данные
- если есть вторая - это имя файла
- если есть третья - это content-type
- ^файл.base64[ $.pad(bool) $.wrap(bool) $.url-safe(bool) ]
- encode
- ^file:base64[имя файла[; $.pad(bool) $.wrap(bool) $.url-safe(bool) ]]
- encode
- ^file::base64[encoded string[; $.pad(bool) $.strict(bool) url-safe(bool) ]]
- decode
- ^file::base64[mode;имя файла;encoded string[; $.content-type[...] $.pad(bool) $.strict(bool) url-safe(bool) ]]
- decode
- ^file:crc32[имя файла]
- вычисляет crc32 файла с указанным именем
- ^файл.crc32[]
- вычисляет crc32 объекта
- ^файл.md5[], ^file:md5[имя файла]
- выдает digest файла, длиной 16 байт в виде строки,
- где байты digest выданы в hex виде, впритык, в нижнем регистре
-
math
$math:PI
^math:round floor ceiling
@@ -959,144 +986,190 @@ math
^math:sin asin cos acos tan atan atan2
^math:degrees radians
^math:pow sqrt
- ^math:random(ширина диапазона)
- ^math:convert[number|файл](base-from;base-to)[[ $.format[string|file] ]]
- ^math:convert[number|файл][алфавит](base-to)[[ $.format[string|file] ]]
- ^math:convert[number|файл](base-from)[алфавит][[ $.format[string|file] ]]
- преобразует строку или файл с числом из одной системы исчисления в другую
- система счисления может быть задана алфавитом, числом от 2 до 16 (эквивалентно алфавиту 0123456789ABCDEF), числом 256 (все ASCII символы)
+ ^math:random(range_width)
+ ^math:convert[number|file](base-from;base-to)[[ $.format[string|file] ]]
+ ^math:convert[number|file][alphabet](base-to)[[ $.format[string|file] ]]
+ ^math:convert[number|file](base-from)[alphabet][[ $.format[string|file] ]]
+ converts a string or file with a number from one numeral system to another
+ the numeral system can be set by an alphabet, a number from 2 to 16 (equivalent to the alphabet 0123456789ABCDEF), or 256 (all ASCII characters)
^math:uuid[ $.lower(bool) $.solid(bool) ]
22C0983C-E26E-4169-BD07-77ECE9405BA5
- win32: пользуется cryptapi
- unix: пользуется /dev/urandom,
- если нет, /dev/random,
- если нет, rand
+ win32: uses cryptapi
+ unix: uses /dev/urandom,
+ if not present, /dev/random,
+ if not, rand
^math:uuid7[ $.lower(bool) $.solid(bool) ]
0193CBF0-7898-7000-A391-AC513CC15658
https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-version-7
^math:uid64[ $.lower(bool) ]
BA39BAB6340BE370
^math:md5[string]
- выдает digest строки, длиной 16 байт в виде строки,
- где байты digest выданы в hex виде, впритык, в нижнем регистре
+ returns the digest of the string, 16 bytes as a string,
+ bytes in hex, contiguous, lowercase
^math:crypt[password;salt]
- salt prefix $apr1$ вызывает встроенный MD5 алгоритм,
- если нет тела salt, оно создаётся случайным
- $1$ вызывает MD5 алгоритм функции OS 'crypt', если поддерживается.
- другие salt читайте документацию по функции OS 'crypt'.
+ salt prefix $apr1$ triggers built-in MD5 algorithm,
+ if salt body is empty, it is generated randomly
+ $1$ calls the OS 'crypt' MD5 algorithm if supported.
+ for other salts see OS 'crypt' documentation.
^math:crc32[string]
- вычисляет crc32 строки
+ calculates crc32 of the string
^math:sha1[string]
- ^math:digest[[md5|sha1|sha256|sha512];строка или файл][[ $.format[hex|base64|file] $.hmac[ключ строка|ключ файл] ]]
- объединяет в себе возможность работы с разными алгоритмами криптографического хеширования.
- $.hmac[ключ] для проверки целостности переданных данных
+ ^math:digest[[md5|sha1|sha256|sha512];string or file][[ $.format[hex|base64|file] $.hmac[key string|key file] ]]
+ combines the ability to use various cryptographic hashing algorithms.
+ $.hmac[key] for verifying the integrity of transmitted data
-inet
- ^inet:ntoa(long)
- ^inet:aton[IP]
- ^inet:name2ip[name][[ $.ipv[4|6|any] $.table(true) ]]
- прямое преобразование имени в IP адрес
- ^inet:ip2name[ip][ $.ipv[4|6|any] ]]
- обратное преобразование из IP адреса в имя
- ^inet:hostname[]
- имя хоста
+memory
+ ^memory:compact[]
+ collect garbage, freeing space for new data (warning: process memory is never released)
+ useful before XSL transform
+ ^memory:auto-compact(frequency)
+ sets automatic garbage collection frequency, from 0 (off) up to 5 (max)
-json
- ^json:parse[-json-строка-[;
- $.depth(максимальная глубина, default == 19)
- $.double(false) отключить встроенный парсинг чисел с плавающей точкой (по умолчанию включен)
- в этом случае они попадут в результирующий объект как строки
- $.int(false) отключить встроенный парсинг целых чисел (по умолчанию включен)
- в этом случае они попадут в результирующий объект как строки
- $.distinct[first|last|all] как будет происходить разбор дублирующихся ключей у объектов
- first - будет оставлен первый встретившийся элемент
- last - будет оставлен последний встретившийся элемент
- all - будут оставлены все элементы. при этом элементы, начиная со 2
- получат числовые суффиксы (key_2 итд)
- по умолчанию дублирующиеся ключи приведут к exception
- $.object[method-junction] пользовательский метод[ключ;объект], которому будут передаваться все разобранные
- объекты и ключи объекта, метод возвращает новый объект
- $.array[method-junction] пользовательский метод, которому будут передаваться массивы
- $.taint[язык преобразования] задаёт язык преобразования для всех строк результата
- ]]
- парсит json-строку в хеш
+reflection
+ ^reflection:create[class;constructor[;pa[;ra[;ms]]]]
+ calls the specified class constructor (no more than 100 parameters)
+ ^reflection:create[ $.class[name] $.constructor[name] $.arguments[ $.1[pa] $.2[ra] $.3[ms] ] ]
+ calls the specified class constructor
+ ^reflection:classes[]
+ a hash of all classes. key = class name, value can be methoded (a class with methods) or void
+ ^reflection:class[object]
+ the class of the given object
+ ^reflection:class_name[object]
+ the class name of the given object
+ ^reflection:base[object]
+ the parent class of the given object
+ ^reflection:base_name[object]
+ the parent class name of the given object
+ ^reflection:class_by_name[class name]
+ obtains the class by name
+ ^reflection:class_alias[class name;new class name]
+ sets an alias for the specified class
+ ^reflection:def[class;class name]
+ checks if the class exists
+ ^reflection:methods[class]
+ a hash with a list of methods of the specified class, values are strings 'native' or 'parser'
+ ^reflection:method[class or object;method name]
+ returns the junction-method of the class or object
+ ^reflection:filename[object or class or method]
+ returns the filename where the object, class or method is defined
+ ^reflection:fields[class or object]
+ a hash with the list of static fields of the specified class or dynamic fields of the specified object
+ ^reflection:fields_reference[object]
+ an editable hash of the dynamic fields of the specified object
+ ^reflection:field[class or object;field name]
+ returns the value of the specified field of the class or object. getters are ignored.
+ ^reflection:copy[source;destination]
+ copies fields from one object or class to another
+ ^reflection:uid[class or object]
+ returns the identifier of the object or class
+ ^reflection:method_info[class;method]
+ a hash with parameters of the specified class method
+ $.inherited[class] name of the class where the method was defined (returned only if the method was defined in an ancestor)
+ $.overridden[class] name of the class where the method was defined (returned only if the method was defined in an ancestor)
+ for native classes a hash is returned:
+ .min_params(minimum required number of parameters)
+ .max_params(maximum possible number of parameters)
+ .call_type[dynamic|static|any]
+ for parser classes a hash is returned:
+ key is parameter number (0, 1, ...), value is parameter name
+ ^reflection:dynamical[[object or class, caller if absent]]
+ returns true if the method was called from a dynamic context when passing
+ a parameter returns true if a dynamic object was passed, false if a class
+ ^reflection:delete[class or object;variable name]
+ deletes the variable with the specified name in the specified class or object
+ ^reflection:is[element name;class name][[context]]
+ analogous to the 'is' operator, allowing to determine if the element is code.
+ ^reflection:tainting[[language|tainted|optimized];string]
+ a string in which each character of the original string corresponds to a character with a transformation code
+ ^reflection:stack[ $.args(false/true) $.locals(false/true) $.limit(n) $.offset(o)]
+ the current state of the method call stack in the parser
+ ^reflection:mixin[source; $.to[target] $.name[name] $.methods(true/false) $.fields(true/false) $.overwrite(false/true)]
+ copies methods and fields from one class to another
- ^json:string[system or user object[;
- $.skip-unknown(false) отключить exception и выдавать 'null' при сериализации объектов с типами
- отличных от void, bool, string, int, double, date, table, hash и file
- $.indent(true) форматировать результирующую строку табуляциями по глубине вложенности
- $.date[sql-string|gmt-string|iso-string|unix-timestamp]
- формат вывода даты, по умолчанию -- sql-string
- $.table[object|array|compact]
- формат вывода таблицы, по умолчанию -- object
- object: [{"c1":"v11","c2":"v12",...},{"c1":"v21","c2":"v22",...},...]
- array: [["c1","c2",...] || null (for nameless),["v11","v12",...],...]
- compact: ["v11" || ["v11","v12",...],...]
- $.file[text|base64|stat] вывести тело файла в указанном виде (по умолчание тело файла
- не попадает в output)
- $.xdoc[hash] параметры преобразования xdoc в строку (как в ^xdoc.string[])
- $.тип[method-junction] любой тип можно вывести с помощью пользовательского метода, который
- должен принимать 3 параметра: ключ, объект данного типа и опции
- вызова ^json:string[]
- $._default[метод] пользовательский метод, будет вызываться для вывода всех объектов пользовательских
- классов. Метод должен принимать 3 параметра: ключ, объект и опции вызова.
- $._default[имя метода] имя пользователького метода, при его наличии он будет вызван для сериализации
- $.void[null|string] неопределенное значение будет выдано в виде null (по умолчанию)
- или пустой строки
- ]]
- сериализует системный или пользовательский объект в json-строку
+request
+ $request:query
+ $request:uri
+ $request:document-root
+ directory relative to which paths are considered in parser, default = $env:DOCUMENT_ROOT
+ $request:argv
+ hash with command-line parameters. keys 0, 1, ... [0 - name of the processed file]
+ $request:charset
+ the source document encoding
+ used in upper/lower and match[][i]
+ WARNING: you must set $request/response:charset before using form class fields
+ $request:method
+ request method (GET|POST|PUT)
+ $request:body
+ POST-request body as text
+ $request:body-file
+ POST-request body as a file
+ $request:body-charset
+ POST-request encoding
+ $request:headers
+ hash with request headers (without HTTP_ prefix)
-date
- время типа date можно использовать в выражениях, подставляет количество дней с epoch [1 января 1970 (UTC)], дробное
- строковое значение в местном времени, численное в UTC, диапазон от 0000-00-00 00:00:00 до 9999-12-31 23:59:59
- по умолчанию используется установленная средствами OS временная зона
+response
+ $response:field[value] and can read old - $response:field
+ the value can be string or hash:
+ $value[abc] field: {abc}<} старое имя 'set'
+ ::create[[URI]]{} old name 'set'
::create[[URI]][qualifiedName]
- URI default = disk path to requested document
- для каталогов конечный / обязателен
+ URI default = disk path to requested document
+ for directories a trailing / is mandatory
::create[file] can be usable:
$f[^file::load[binary;http://;some HTTP options here...]]
$x[^xdoc::create[$f]]
- ::load[file.xml[;опции]]
- .transform[rules.xsl|xdoc][[params hash]] выдаёт dom
- шаблон кешируется, кеш обновляется при изменении даты файла шаблона,
- или изменении даты файла "имя шаблона.stamp"[проверка даты stamp приоритетнее]
+ ::load[file.xml[;options]]
+ .transform[rules.xsl|xdoc][[params hash]] returns dom
+ the template is cached, cache is updated if the template file date changes,
+ or the date of "template_name.stamp" changes [stamp date check has priority]
- параметры передаются как есть, не xpath выражения
+ parameters are passed as is, not xpath expressions
.string[[output options]]
- .save[file.xml[;output options]] с шапкой
+ .save[file.xml[;output options]] with header
.file[[output options]] = file
- output options идентичны атрибутам xsl:output
- [исключение: игнорируется cdata-section-elements, нужно будет, сделаю]
- выдаёт media-type при подстановке $response:body[сюда]
+ output options are identical to xsl:output attributes
+ [exception: cdata-section-elements ignored]
+ returns media-type when substituting $response:body[here]
- если на документ ссылаются так:
+ if the document is referenced as:
parser://method/param/to/that/method
- то в качестве документа используется ^MAIN:method[/param/to/that/method]
- [примечание: в параметр всегда приходит лидирующая /, даже, если параметров вообще не было]
+ then ^MAIN:method[/param/to/that/method] is used as the document
+ [note: the parameter always comes with a leading /, even if there were no parameters]
xnode
DOM1 attributes:
@@ -1240,108 +1313,56 @@ xnode
boolean hasAttributes()
XPath:
- ^node.select[xpath/query/expression] = array of nodes,
+ ^node.select[xpath/query/expression] = array of nodes,
empty array if nothing found
^node.selectSingle[xpath/query/expression] = first node if any
^node.selectBool[xpath/query/expression] = bool if any or die
^node.selectNumber[xpath/query/expression] = double if any or die
^node.selectString[xpath/query/expression] = string if any or die
-memory
- ^memory:compact[]
- собрать мусор, освободив место под новые данные (предупреждение: память процесса никогда не освобождается)
- полезно делать перед XSL transform
- ^memory:auto-compact(частота сборки)
- задает режим автоматической сборки мусора, от 0 (выключена) до 5 (максимальная)
-
-status
- $status:sql
- cache table
- url time
- url time
- url time
- $status:stylesheet
- cache table
- file time
- file time
- file time
- $status:rusage hash
- utime user time used
- stime system time used
- maxrss max resident set size
- ixrss integral shared text memory size
- idrss integral unshared data size
- isrss integral unshared stack size
- tv_sec
- tv_usec
- $s[$status:rusage]
- ^s.tv_sec.format[%.0f].^s.tv_usec.format[%06.0f]
- $status:memory hash
- used
- includes some pages that were allocated but never written
- free
- ever_allocated_since_compact
- return the number of bytes allocated since the last collection
- ever_allocated_since_start
- return the total number of bytes [EVER(c)PAF] allocated in this process,
- never decreases
- $status:pid
- process id
- $status:tid
- thread id
- $status:mode
- режим работы, cgi|console|mail|httpd|apache|isapi
- $status:log-filename
- путь к журналу ошибок parser3.log
-
-console
- $console:timeout
- $console:line
- read/write строку
-
DATA::=string | file | hash
- hash вида
+ hash of the form
[
- $.file[имя файла на диске]
- $.name[имя файла для пользователя]
+ $.file[filename on disk]
+ $.name[filename for user]
$.mdate[date]
]
MAIN
- это класс, загружаемый на автомате из конфигурационного auto.p, кучи auto.p и запрашиваемого документа:
- конфигурационный auto.p
+ this is the class automatically loaded from the configuration auto.p, a bunch of auto.p and the requested document:
+ configuration auto.p
cgi:
- 1. или полный путь из переменной окружения CGI_PARSER_SITE_CONFIG или рядом с бинарником parser'а
+ 1. either full path from environment variable CGI_PARSER_SITE_CONFIG or next to parser binary
isapi: windows directory
apache module:
1) ParserConfig [can be in .htaccess]
- auto.p вниз от DOCUMENT_ROOT/ по дереву до каталога с обрабатываемым файлом включительно
- класс собирается из всех этих файлов, последующие становятся родителями предыдущих
- имя последнего загруженного MAIN, имён у предыдущих нет
-
- после загрузки MAIN класса вызывается его @main[]
- результат которого передаётся в его @postprocess[data] if($data is string) ...
- результат которого отдаётся пользователю
+ auto.p goes down from DOCUMENT_ROOT/ through the directory tree to the directory of the processed file, inclusive
+ the class is assembled from all these files, subsequent ones become parents of the previous ones
+ the name of the last loaded is MAIN, previous ones have no names
+
+ after loading MAIN class, its @main[] is called
+ the result is passed to its @postprocess[data] if($data is string) ...
+ the result is then returned to the user
-если встречается ошибка и try не задан, её можно красиво сообщить пользователю, определив
+if an error occurs and try is not specified, it can be nicely reported to the user by defining
@unhandled_exception[exception;stack]
- $exception.type строка "тип проблемы"
- $exception.file $exception.lineno $exception.colno файл, строка и позиция, где случилась проблема [если не запрещены при компиляции]
- $exception.source строка, из-за которой случилась проблема
- $exception.comment комментарий english
- stack табличка из колонок file line name,
- там лежат в обратном порядке имена[name] и места вызовов[file line] операторов/методов, приведших к ошибке.
+ $exception.type string "type of problem"
+ $exception.file $exception.lineno $exception.colno file, line and position where the problem occurred [if not disabled at compile time]
+ $exception.source line that caused the problem
+ $exception.comment English comment
+ stack table with columns file line name,
+ in reverse order the names[name] and places[file line] of the operators/methods that caused the error.
-при загрузке файла (file::load, table::load, xdoc::load) можно указать такое имя файла:
+when loading a file (file::load, table::load, xdoc::load) you can specify such a filename:
http://domain/document[?params<> создает http.status ошибку, это можно отключить, передав $.any-status(1)
- $.charset[кодировка удалённых документов по-умолчанию], если сервер вернёт content-type:charset - ОНА ПЕРЕБИВАЕТ
- $.response-charset[кодировка удалённых документов], не перебиваеся content-type:charset
- $.user[пользователь]
- $.password[пароль]
- file::load в дополнительные поля записывает
- ПОЛЕ:значение (имена полей ответа заглавными буквами)
- tables << хеш их ПОЛЕ->table с единственным столбцом "value"
- в таких таблицах можно брать повторяющиеся заголовки. например, несколько set-cookies
- todo:сделать отдельный cookies
-
-системные типы ошибок:
- parser.compile ^test[} компиляция (непарная скобка, ...)
- parser.runtime ^if(0). параметры (больше/меньше, чем нужно, не тех типов, ...)
+ default user-agent=parser3
+ by default, getting http status != 200 >> creates http.status error, can be disabled by $.any-status(1)
+ $.charset[default encoding of remote documents], if server returns content-type:charset - IT OVERRIDES
+ $.response-charset[encoding of remote documents], not overridden by content-type:charset
+ $.user[user]
+ $.password[password]
+ file::load writes additional fields
+ FIELD:value (response field names in uppercase)
+ tables << a hash of FIELD->table with a single column "value"
+ in such tables you can get repeating headers, e.g. multiple set-cookies
+ todo: make separate cookies
+
+system error types:
+ parser.compile ^test[} compilation (unmatched bracket, ...)
+ parser.runtime ^if(0). parameters (more/less than needed, wrong types, ...)
number.zerodivision ^eval(1/0) ^eval(1%0)
number.format ^eval(abc*5)
file.lock shared/exclusive lock error
@@ -1391,8 +1412,10 @@ MAIN
http.status ^file::load[http://ok/there] host found, connection accepted, status!=200
date.range ^date::create(10000;1;1) date out of valid range
-если в MAIN определён $SIGPIPE(1) то в случае, если обработка была прервана пользователем, сообщение
- об этом будет записано в parser3.log
+if $SIGPIPE(1) is defined in MAIN, then if processing was interrupted by the user, a message
+ about this is written to parser3.log
+
+if the method description explicitly contains the local variable result (there is also an implicit variable),
+ then the code for outputting whitespace literals does not get into the final bytecode
-если описание метода содержит локальную переменную result в явном виде (есть и неявная переменная)
- то код вывода пробельных литералов не попадает в конечный байт-код
+$Id: operators.txt,v 1.264 2024/12/20 19:24:17 moko Exp $