
Product
Introducing Socket Firewall Enterprise: Flexible, Configurable Protection for Modern Package Ecosystems
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.
RedAgate is static HTML | XML | SVG renderer.
You can start easily because we are using JSX and semantics similar to React.
Easily to bundle resources (images, stylesheets, fonts, scripts, ...) .
RedAgate.renderAsHtml() API and component lifecycle defer() 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).
$ npm install red-agate --save
Note
To import this from your code, you need to use
babel+webpackand importred-agate-*/modules/*paths.
(We have used theimportstatements for doing the tree-shaking. Theimportstatements in the.jsnot the.mjsfiles cannot import from the vanilla node.js.)You can also import from the
.mjsfile on a node with the--experimental-modulesoption enabled.
NOTICE:
Use withwebpack >= 5If 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: false, }, },On
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"'.
See live demo on browser (code) and Node.js example.
/** @jsx RedAgate.createElement */
import * as RedAgate from 'red-agate/modules/red-agate';
interface HelloProps extends RedAgate.ComponentProps {
name: string;
}
const Hello = (props: HelloProps) => {
return (<div>Hello, {props.name}!</div>);
};
RedAgate.renderAsHtml(<Hello name={'😈RedAgate😈'}/>)
.then(html => console.log(html))
.catch(error => console.log(error))
export interface IfProps extends RedAgate.ComponentProps {
condition: boolean;
}
export const If = (props: IfProps) => {
if (this.props.condition) return this.props.children;
else return [];
};
export interface IfProps extends RedAgate.ComponentProps {
condition: boolean;
}
export class If extends RedAgate.RedAgateComponent<IfProps> {
public constructor(props: IfProps) {
super(props);
}
// Equivalent to React's render() .
public transform() {
if (this.props.condition) return this.props.children;
else return [];
}
}
import { SvgCanvas } from 'red-agate-svg-canvas/modules/drawing/canvas/SvgCanvas';
import { Shape,
CONTEXT_SVG_CANVAS } from 'red-agate/modules/red-agate/tags/Shape';
export interface RectProps extends ShapeProps {
width: number;
height: number;
}
export const rectPropsDefault: RectProps = Object.assign({}, shapePropsDefault, {
width: 10,
height: 10
});
export class Rect extends Shape<RectProps> {
public constructor(props: RectProps) {
super(Object.assign({}, rectPropsDefault, props));
}
public render(contexts: Map<string, any>, children: string) {
const canvas: SvgCanvas = this.getContext(contexts, CONTEXT_SVG_CANVAS);
canvas.rect(0, 0, this.props.width, this.props.height);
return ``;
}
}
/** @jsx RedAgate.createElement */
import * as RedAgate from 'red-agate/modules/red-agate';
import { ForEach,
If,
Template } from 'red-agate/modules/red-agate/taglib';
import { Html5 } from 'red-agate/modules/red-agate/html';
import { Svg,
Group,
Rect,
Text,
GridLine,
SvgImposition } from 'red-agate/modules/red-agate/svg';
import { Font,
Image,
Style } from 'red-agate/modules/red-agate/bundler';
import { query } from 'red-agate/modules/red-agate/data';
import { Lambda } from 'red-agate/modules/red-agate/app';
import { HtmlRenderer } from 'red-agate/modules/red-agate/renderer';
interface FbaDetail {
id: string;
name: string;
condition: string;
}
interface PrintJob {
details: FbaDetail[];
}
const designerMode = true;
const font = "'Noto Sans', sans-serif";
const Fba = (props: {leaf: FbaDetail}) =>
<Template>
<Group x={0} y={0}>
<Text x={27} y={11.5}
textAlign="center" font={`11.5px 'Libre Barcode 128 Text', cursive`} fill
text={leaf.id} />
<Text x={4} y={18 + 3.5}
font={`3.5px ${font}`} fill
text={leaf.name} />
<Text x={4} y={22 + 3.5}
font={`3.5px ${font}`} fill
text={leaf.condition} />
</Group>
</Template>;
export const fbaA4ReportHandler: Lambda = (event: PrintJob, context, callback) => RedAgate.renderOnAwsLambda(
<Html5>
<head>
<title>FBA</title>
<link href="https://fonts.googleapis.com/css?family=Noto+Sans" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css?family=Libre+Barcode+128+Text" rel="stylesheet"/>
<Style src="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.css"/>
<Style src="https://cdnjs.cloudflare.com/ajax/libs/paper-css/0.3.0/paper.css"/>
<style dangerouslySetInnerHTML={{ __html: require('./fba-a4.style.css') }}/>
</head>
<body class="A4">
<ForEach items={query(event.details).groupEvery(40).select()}> { (items: FbaDetail[]) =>
<section class="sheet" style="position: relative; top: 0mm; left: 0mm;">
<Svg width={210 - 1} height={297 - 2} unit='mm'>
<SvgImposition items={items} paperWidth={210} paperHeight={297} cols={4} rows={10}> { (item: FbaDetail) =>
<Template>
<If condition={designerMode}>
<Rect x={0} y={0} width={210 / 4} height={297 / 10} lineWidth={0.5} stroke/>
<GridLine startX={0} startY={0} endX={210 / 4} endY={297 / 10} gridSize={5} bleed={0} lineWidth={0.1}/>
</If>
<Fba leaf={item} />
</Template> }
</SvgImposition>
</Svg>
</section> }
</ForEach>
</body>
</Html5>, callback);
const event = {
details: [{
// ...
}]
};
fbaA4ReportHandler(event /* PrintJob */, {} as any /* Context */, (error, result) => {
if (error) {
console.log(error);
} else {
console.log(result);
}
});
/** @jsx RedAgate.createElement */
import * as RedAgate from 'red-agate/modules/red-agate';
import { Html5 } from 'red-agate/modules/red-agate/html';
import { Lambda } from 'red-agate/modules/red-agate/app';
import { HtmlRenderer } from 'red-agate/modules/red-agate/renderer';
interface PrintJob { /* */ }
export const reportHandler: Lambda = (event: PrintJob, context, callback) => RedAgate.renderOnAwsLambda(
<Html5>
hello, { event.name }!
</Html5>, callback);
export const pdfHandler = HtmlRenderer.toPdfHandler(reportHandler, {}, {
width: '210mm',
height: '297mm',
printBackground: true,
});
pdfHandler(event /* PrintJob */, {} as any /* Context */, (error, result) => {
if (error) {
console.log(error);
} else {
console.log(result);
}
});
/** @jsx RedAgate.createElement */
import * as RedAgate from 'red-agate/modules/red-agate';
import { Html5 } from 'red-agate/modules/red-agate/html';
import { App } from 'red-agate/modules/red-agate/app';
export const billngReportHandler = (event: BillingPrintJob, context, callback) => RedAgate.renderOnAwsLambda(
<Html5>billng</Html5>, callback);
export const kanbanReportHandler = (event: KanbanPrintJob, context, callback) => RedAgate.renderOnAwsLambda(
<Html5>kanban</Html5>, callback);
App.route('/', (evt, ctx, cb) => cb(null, 'Hello, Node!'))
.route('/billing', billngReportHandler)
.route('/kanban', kanbanReportHandler)
.run({});
#!/usr/bin/env python3
import json
import os
import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/node_modules/red-agate/')
from redagate_lambda import call, LambdaInternalErrorException
if __name__ == '__main__':
from flask import Flask, abort
app = Flask(__name__)
@app.errorhandler(LambdaInternalErrorException)
def internal_error_handler(e):
return 'Internal Server Error', 500
@app.route('/billing')
def run_billing_report():
with open('./src/reports/billing.data.json') as f:
event = json.loads(f.read())
event['eventName'] = '/billing'
return call(command=["node", "dist/app.js"], event=event)
@app.route('/kanban')
def run_barcode_test_report():
with open('./src/reports/kanban.data.json') as f:
event = json.loads(f.read())
event['eventName'] = '/kanban'
return call(command=["node", "dist/app.js"], event=event)
port = int(os.environ['PORT']) if os.environ.get('PORT') is not None else None
app.run(debug=True, port=port)
/** @jsx react.createElement */
import * as react from 'react';
interface ReactHelloProps {
name: string;
}
export const ReactHello: React.SFC<ReactHelloProps> = (props) => {
return (<span>Hello, {props.name}!</span>);
};
/** @jsx RedAgate.createElement */
import * as RedAgate from 'red-agate/modules/red-agate';
import { Html5 } from 'red-agate/modules/red-agate/html';
import { ReactHost } from 'red-agate-react-host/modules/react-host';
import { ReactHello } from './hello';
import { createElement as $ } from 'react';
RedAgate.renderAsHtml(
<Html5>
<ReactHost element={$(ReactHello, {name: '😎React😎'})} />
</Html5>)
.then(html => console.log(html))
.catch(error => console.log(error))
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.
| 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, ... |
/** @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 orstring[/* 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: stringlambda: 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: anylambda?: 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. |
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. |
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.
ISC
Copyright (c) 2017, Shellyl_N and Authors.
FAQs
Static HTML|XML|SVG renderer using JSX, suitable for report output.
We found that red-agate demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Socket Firewall Enterprise is now available with flexible deployment, configurable policies, and expanded language support.

Security News
Open source dashboard CNAPulse tracks CVE Numbering Authorities’ publishing activity, highlighting trends and transparency across the CVE ecosystem.

Product
Detect malware, unsafe data flows, and license issues in GitHub Actions with Socket’s new workflow scanning support.