RedAgate
Static HTML | XML | SVG renderer using JSX, suitable for report output.
RedAgate is static HTML | XML | SVG renderer.
You can start easily because we are using JSX and semantics similar to React.
Advantages:
-
Easily to bundle resources (images, stylesheets, fonts, scripts, ...) .
RedAgate.renderAsHtml()
API and component lifecycledefer()
method return promise objects.
You can use standard Tag-Libs (e.g. Image, Style, Font, SingleFont, Script, Asset) to bundle them. -
Many standard Tag-Libs (e.g. If, Repeat, ForEach, Template, Html5, Svg, SVG shapes, Barcodes (QR Code, Code39, Code128, EAN/UPC, ITF, NW7/Codabar, postal barcode) and complex objects) are bundled.
-
Html5 Canvas API is available in the sub tree of the Svg component.
-
Running on both server side (Node.js) and modern browsers (Chrome, Firefox, Safari, Edge).
Install
$ npm install red-agate --save
Note
To import this from your code, you need to use
babel
+webpack
and importred-agate-*/modules/*
paths.
(We have used theimport
statements for doing the tree-shaking. Theimport
statements in the.js
not the.mjs
files cannot import from the vanilla node.js.)You can also import from the
.mjs
file on a node with the--experimental-modules
option enabled.
NOTICE:
Use withwebpack >= 5
If you get the error:
Module not found: Error: Can't resolve '(importing/path/to/filename)' in '(path/to/node_modules/path/to/dirname)' Did you mean '(filename).js'?`
Add following setting to your
webpack.config.js
.test: /\.m?js/resolve:fullySpecified: falseOn
webpack >= 5
, the extension in the request is mandatory for it to be fully specified if the origin is a '.mjs' file or a '.js' file where the package.json contains '"type": "module"'.
Usage
See live demo on browser (code) and Node.js example.
Hello, world:
/** @jsx RedAgate.createElement */; ; RedAgate.renderAsHtml.thenconsole.loghtml.catchconsole.logerror
Defining element by using lambda:
;
Defining element by using component:
Defining SVG element by using component:
;; ;
Complete example:
/** @jsx RedAgate.createElement */;;;;;;;; ;;; ;
; fbaA4ReportHandlerevent /* PrintJob */, as any /* Context */,;
Render html into PDF:
/** @jsx RedAgate.createElement */;;;; ; ; pdfHandlerevent /* PrintJob */, as any /* Context */,;
Call from another process:
/** @jsx RedAgate.createElement */;;; ; ; App.route'/',cbnull, 'Hello, Node!' .route'/billing', billngReportHandler .route'/kanban', kanbanReportHandler .run;
#!/usr/bin/env python3 import jsonimport osimport sys from redagate_lambda import call, LambdaInternalErrorException if __name__ == '__main__': from flask import Flask, abort app = return 'Internal Server Error', 500 with as f: event = = '/billing' return with as f: event = = '/kanban' return port = if is not None else None
Mix react elements:
/** @jsx react.createElement */; ;
/** @jsx RedAgate.createElement */;; ;;; RedAgate.renderAsHtml.thenconsole.loghtml.catchconsole.logerror
We provide ES6 module files under red-agate*/modules/*
path.
You can get the benefits of tree shaking when using webpack.
Instead, you can also import the whole by simply specifying red-agate*
as the import path.
Component Lifecycle
call order | method | description |
---|---|---|
0 | earlyConstruct(): void |
This method is marker and it will be NEVER called. If it defined, constructor will be called in createElement() .Otherwise constructor will be called in render???() APIs. |
1 | constructor(props) / lambda(props) |
Construct a component. If it is lambda, transform myself and children DOM tree. |
2 | transform(): RedAgateNode |
Transform myself and children DOM tree. This method is equivalent to render() of React method. |
3 | defer(): Promise<any> |
Wait for asynchronous resources. |
4 | beforeRender( contexts: Map<string, any> ): void |
Get contexts provided by parent elements. Preparing something for child elements. |
5 | render( contexts: Map<string, any>, children: string ): string |
Return rendering result as string. |
6 | afterRender( contexts: Map<string, any> ): void |
Clean up contexts, graphic states, ... |
APIs
/** @jsx RedAgate.createElement */
import * as RedAgate from 'red-agate/modules/red-agate'
method | description |
---|---|
RedAgate.createElement( type: ComponentFactory<P>, props: P or null or undefined, ...children: RedAgateNode[] ): RedAgateElement<P> |
Create a element. This function is called from JSX compiled code. |
RedAgate.renderAsHtml( element: RedAgateNode ): Promise<string> |
Render elements to string. |
RedAgate.render( element: RedAgateNode, container: HTMLElement, callback?: ( html: string or null, error: any or null ) => void ): void |
Render elements and apply to DOM. |
RedAgate.renderOnAwsLambda( element: RedAgateNode, callback: ( error: any or null, result: any or null ) => void ): void |
Render elements to string. Return result via AWS lambda callback. |
RedAgate.renderOnExpress( element: RedAgateNode, req: any, res: any ): void |
Render elements to string. Return result via Express web server callback. |
import { query } from 'red-agate/modules/red-agate/data'
method | description |
---|---|
query( data: T[] ): Query<T> |
Transform an array. |
Query<T>#orderBy( condition: Array<string or string[ /* colName: string, ('asc' or 'desc') */ ]> or ((a: T, b: T) => number) ): Query<T> |
Sort an array. |
Query<T>#groupBy( condition: string[ /* colName: string */ ] or ((a: T, b: T, index: number, array: T[]) => boolean) ): Query<T[]> |
Grouping and transform an array. |
Query<T>#groupEvery( n: number or { single: number, first?: number, intermediate: number, last?: number } ): Query<T[]> |
Grouping and transform an array. |
Query<T>#where( fn: ( value: T, index: number, array: T[] ) => boolean ): Query<T> |
Filter an array. |
Query<T>#select<R>( fn?: ( value: T, index: number, array: T[] ) => R ): Array<R or T> |
Map an array. |
import { App } from 'red-agate/modules/red-agate/app'
method | description |
---|---|
App.cli( options: string[] handler: ( opts: Map<string, string> ) => void ): App |
Add CLI routing. If options[i] starts with ? it is a optional parameter.If options[i] ends with * it is a wildcard. |
App.route( name: string lambda: Lambda ): App |
Add routing to lambda.name parameter is used as routing path.When request event is received call the lambda that name equals to event.eventName . |
App.run( context: any lambda?: Lambda ): App |
Run routing. event is received from stdin as JSON and send response to stdout. Exit process by calling exit() when response is ended.If lambda is specified, ignore route() and call lambda . |
import { Lambdas } from 'red-agate/modules/red-agate/app'
method | description |
---|---|
Lambdas.pipe( handler1: Lambda, handler2: Lambda ): Lambda |
Pipe 2 lambdas. Return a composite function that piping 2 lambdas. 2nd lambda's event is 1st lambda's callback result . |
import { HtmlRenderer } from 'red-agate/modules/red-agate/renderer'
$ npm install puppeteer --save
method | description |
---|---|
HtmlRenderer.toPdf( html: string or Promise<string>, navigateOptions: any, pdfOptions: any ): Promise<Buffer> |
Render HTML into PDF using puppeteer. See puppeteer#page.goto about navigateOptions .See puppeteer#page.pdf about pdfOptions . |
HtmlRenderer.toImage( html: string or Promise<string>, navigateOptions: any, imageOptions: any ): Promise<Buffer> |
Render HTML into image using puppeteer. See puppeteer#page.goto about navigateOptions .See puppeteer#page.screenshot about imageOptions . |
HtmlRenderer.toPdfHandler( handler: Lambda, navigateOptions: any, pdfOptions: any ): Lambda |
Create composite function returning pdf as callback result. |
HtmlRenderer.toImageHandler( handler: Lambda, navigateOptions: any, imageOptions: any ): Lambda |
Create composite function returning image as callback result. |
Standard Tag-Libs
red-agate/modules/red-agate/taglib
tag | description |
---|---|
Repeat | Loop N times. |
ForEach | Iterate an array. |
If | Conditional branch. |
Do | Call a lambda function when createElement . |
Facet | Grouping child elements. Give a name to group. |
Template | Synonym for Facet . |
red-agate/modules/red-agate/bundler
tag | description |
---|---|
Asset | Fetch a external resource. Fetched resource is referred from other tags. |
Image | Fetch a external image resource. |
Script | Fetch a external script resource. |
Style | Fetch a external stylesheet resource. |
Font | Synonym for Style . |
SingleFont | Fetch a external single font-family font resource. |
red-agate/modules/red-agate/html
tag | description |
---|---|
Html4_01_Strict | Output doctype declaration and html tag. |
Html4_01_Transitional | Output doctype declaration and html tag. |
Html4_01_Frameset | Output doctype declaration and html tag. |
Xhtml1_0_Strict | Output doctype declaration and html tag. |
Xhtml1_0_Transitional | Output doctype declaration and html tag. |
Xhtml1_0_Frameset | Output doctype declaration and html tag. |
Html5 | Output doctype declaration and html tag. |
Xml | Output xml declaration. |
HtmlImposition | Impose pages in a physical page. |
red-agate/modules/red-agate/svg
tag | description |
---|---|
Svg | Output svg tag.Children can use a Canvas context. |
Ambient | Change current graphic state properties. |
Arc | Draw an arc. |
Canvas | Call a lambda function and draw by using Canvas context object. |
Circle | Draw a circle. |
Curve | Draw bezier curve(s). |
GridLine | Draw grid lines for design time. |
Group | Group children. Output g tag. |
Line | Draw line(s). |
Path | Group path fragments (e.g. Arc, Circle, Curve, Line, Rect, ...) . |
Pie | Draw a pie. |
Polygon | Draw a polygon. |
Rect | Draw a rectangle. |
RoundRect | Draw a rounded rectangle. |
SvgAssetFragment | Append raw SVG tags into defs . |
SvgFragment | Append raw SVG tags. |
Text | Draw text line(s). |
SvgImposition | Impose pages in a physical page. |
red-agate/modules/red-agate/printing
tag | description |
---|---|
PrinterMarksProps | Draw printer marks (crop mark, bleed mark, center mark, fold mark). |
red-agate-barcode/modules/barcode/(Code39|Code128|Ean|Itf|JapanPostal|Nw7|Qr)
$ npm install red-agate-barcode --save
tag | description |
---|---|
Code39 | Draw a CODE39 barcode. |
Code128 | Draw a CODE128 barcode. (GS1-128 is available) |
Ean13 | Draw a EAN-13 (GTIN-13 / JAN-13) barcode. |
Ean8 | Draw a EAN-8 (GTIN-8 / JAN-8) barcode. |
Ean5 | Draw a EAN-5 (JAN-5) barcode. |
Ean2 | Draw a EAN-2 (JAN-2) barcode. |
UpcA | Draw a UPC-A (GTIN-12) barcode. |
UpcE | Draw a UPC-E barcode. |
Itf | Draw a ITF barcode. (GTIN-14 is available) |
JapanPostal | Draw a Japan Post Customer barcode. |
Nw7 | Draw a NW7 (Codabar) barcode. |
Qr | Draw a QR Code (model 2) barcode. |
red-agate-react-host/modules/react-host
$ npm install react --save$ npm install react-dom --save$ npm install red-agate-react-host --save
tag | description |
---|---|
ReactHost | Host a react element and render as static markup. |
Configurations for building application
If you want to use red-agate w/o jsx pragma comment (/** @jsx RedAgate.createElement */
),
You should configure tsconfig
or .babelrc
for building JSX.
Prease see typescript docs
, babel docs
or example.
FAQ
- Can I receive element events (e.g. onclick) ?
- No. RedAgate is static renderer. Please use React, Vue, Riot, Angular, knockout, ...
- Can I change DOM via API after rendered to real DOM?
- No. Please use React, Vue, Riot, Angular, knockout, ...
- Can I build print preview window by using RedAgate?
- paper-css may help you to build print previews.
- Can I output rendered result as PDF, PNG, or other formats?
- Please use puppeteer via HtmlRenderer.toPdf() and HtmlRenderer.toImage().
- Or you can convert from html to any formats using other libraries
(e.g.
html-pdf (wrapper of PhantomJS), wkhtmltopdf) .
License
ISC
Copyright (c) 2017, Shellyl_N and Authors.