(WPF, FlowDocument)
Простой LISPоподобный язык для генерации отчетов. Получает данные из JSON-строки и генерит FlowDocument, пригодный для экспорта в pdf-файл. Получает контролировать отчет вплоть до черточки, что очень любят метрологи :-)
Описание синтаксиса
Разметка отчетов очень похожа на язык Lisp со следующим синтаксисом:
(fun param1 param2 ...), где fun - название функции или оператора
Весь язык разметки делится на две части: сам RLisp и ReportDSL действующий поверх него
поддерживаются следующие операторы:
def - определение переменных и функций
list - определяем какой-то список
loop - цикл (loop a in (list 1 2 3 4 5) (? a "; ") ) выводит в консоль 1; 2; 3; 4; 5;
арифметические действия +,-,*,/ - сложение/вычитание/умножение/деление (+ 1 2 3) равно 6
? - вывод в консоль. В данной реализации, вывод в консоль используется для дальнейшей компиляции документа
if else - условный оператор следующий код выдаст "не двойка" (def a 3) ;определяем переменную со значением три (if (= a 2) (? "двойка") else (? "не двойка") )
json - получить переменную из json например, есть json-строка = {arr: {p1: "ppp", p2: "222"}} (? (json arr.p2)) выведет "222" для доступа к элементам массивам, используем [?] json-строка такая: { arr:[ {x:1, y: 2}, {x:3, y: 4}, {x:5, y: 6}, ] }
(? (json arr[0].y)) ;выведет "2"
(loop a in (json arr)
(? a.x "; ")
) ;выведет 1; 3; 5
ОПРЕДЕЛЕНИЕ ФУНКЦИЙ
определим функцию, которая выводит строку "я - f1" и возвращает сумму двух параметров (def (f1 a b) (? "я - f1") (+ a b) )
вызывать так: (f1 3 5)
Если количество параметров неизвестно, то все они попадают в последнее выражение тела функции: (def (f2) (? "я - f2") (+) )
(f2 1 2 3 4) ;напечатает "я - f2" и вернет 10
если нужно указать конкретное место, куда будут вставлены параметры, используется оператор "..." (многоточие)
рассмотрим, для примера, функцию, которая рисует ячейку таблицы с бордюром (эти функции рассмотрим позже)
(def (my-cell)
(cell (:border 1 1 1 1)
(par)
)
)
если мы будем передавать в нее параметры, все они попадут в выражение cell (после par)
Т.е. в результате получим такую разметку
(cell (:border 1 1 1 1)
(par)
параметр 1
параметр 2
...
)
Это приведет к ошибке компиляции шаблона.
Чтобы этого не произошло, перепишем функцию так:
(def (my-cell)
(cell (:border 1 1 1 1)
(par ...) ;многоточие - сюда будут попадать все параметры
)
)
вызов (my-cell "1. " "иванов") преобразуется в такую разметку:
(cell (:border 1 1 1 1)
(par "1. " "иванов")
)