nehan
v7.8.15
Published
Html layout engine for paged-media written in Typescript
Maintainers
Readme
nehan
Introduction
Dynamic html layout engine for paged-media written by Typescript.
Install
npm install nehanDemo
See Nehan Reader at Chrome Web Store.
How to use Nehan Reader
- Install Nehan Reader.
- Goto any site you want to read as paged-media.
- Click the browser action button
- Then you'll see paged site.
Example
See example directory.
Usage
simple usage with no styling
import { PagedNehanDocument } from 'nehan';
const $result = document.querySelector("#result");
new PagedNehanDocument("<h1>hello, nehan!</h1>", {}).render({
onPage: (ctx) => {
const evaluatedPage = ctx.caller.getPage(ctx.page.index);
$result.appendChild(evaluatedPage.dom);
$result.appendChild(document.createElement("hr"));
},
onComplete: (ctx) => {
console.log(`finished! ${ctx.time}msec`);
}
});render with style
import { PagedNehanDocument, CssStyleSheet } from 'nehan';
const $result = document.querySelector("#result");
new PagedNehanDocument("<h1>hello, nehan!</h1>", {
styleSheets:[
new CssStyleSheet({
"body":{
writihgMode:"horizontal-tb", // or "vertical-rl"
fontSize:"16px",
padding: "1em",
measure: "640px", // means 'width' in horizontal-tb, 'height' in vertical-rl.
extent: "480px" // means 'height' in horizontal-tb, 'width' in vertical-rl.
},
"h1":{
marginAfter: "1em", // means 'margin-bottom' in horizontal-tb, 'margin-left' in vertical-rl
paddingStart: "0.5em" // means 'padding-left' in horizontal-tb, 'padding-top' in vertical-rl
}
}
]
}).render({
onPage: (ctx) => {
const evaluatedPage = ctx.caller.getPage(ctx.page.index);
$result.appendChild(evaluatedPage.dom);
$result.appendChild(document.createElement("hr"));
},
onComplete: (ctx) => {
console.log(`finished! ${ctx.time}msec`);
}
});About logical size
To handle documents that are independent of the character direction, we use the logical size.
measuremeans the size in the inline direction.extentmeans the size in the block direction.
logical-size - physical-size table
| logical-size\writing-mode | horizontal-tb | vertical-rl | vertical-lr | | ------------------------- | ------------- | ------------- | ------------- | | measure | width | height | height | | extent | height | width | width |
About logical direction
To handle documents that are independent of the character direction, we use the logical direction.
startmeans inline level heading direction.endmeans inline level trailing direction.beforemeasn block level heading direction.aftermeans block level trailing direction.
Example1 (logical-margin - physical-margin table)
| logical-direction\writing-mode | horizontal-tb | vertical-rl | vertical-lr | | ------------------------------ | ------------- | ------------- | ------------- | | margin-start | margin-left | margin-top | margin-top | | margin-end | margin-right | margin-bottom | margin-bottom | | margin-before | margin-top | margin-right | margin-left | | margin-after | margin-bottom | margin-left | margin-right |
The same is true for padding and border(border-xxx-width, border-xxx-color, border-xxx-style).
Example2 (logical-border-radius - physical-border-radius table)
| logical-direction\writing-mode | horizontal-tb | vertical-rl | vertical-lr | | ------------------------------ | ------------- | ------------- | ------------- | | border-before-start-radius | border-top-left-radius | border-top-right-radius | border-top-left-radius | | border-before-end-radius | border-top-right-radius | border-bottom-right-radius | border-bottom-left-radius | | border-after-end-radius | border-bottom-right-radius | border-bottom-left-radius | border-bottom-right-radius | | border-after-start-radius | border-bottom-left-radius | border-top-left-radius | border-top-right-radius |
Shothanded logical property
If you set margin like margin:1em 2em 3em 4em, then it means margin-before:1em, margin-end:2em, margin-after:3em, margin-start:4em.
If you set margin like margin:1em 2em 3em, then it means margin-before:1em, margin-end:2em, margin-after:3em, margin-start:2em.
If you set margin like margin:1em 2em, then it means margin-before:1em, margin-end:2em, margin-after:1em, margin-start:2em.
If you set margin like margin:1em, then it means margin-before:1em, margin-end:1em, margin-after:1em, margin-start:1em.
The same is true for padding and border(border-xxx-width, border-xxx-color, border-xxx-style).
Dynamic Style
You can define functional value for each selector(css property name is !xxx).
In following example, all elements that matches .require-xx will cause page-break if rest block size(restExtent) is smaller than xxpx.
import { CssStyleSheet, DynamicStyleContext, CssDeclarationBlock } from 'nehan';
function requiredExtent(requiredSize: number) {
return (ctx: DynamicStyleContext): CssDeclarationBlock | undefined => {
if (!ctx.parentContext) {
return undefined;
}
const restExtent = ctx.parentContext.restExtent;
if (restExtent >= requiredSize) {
return undefined; // enough block size is left!
}
// restExtent < requiredSize(not enough block size left)
return { "page-break-before": "always" };
};
}
const myStyleSheet = new CssStyleSheet({
".require-60": {
"!dynamic": requiredExtent(60)
}
});DOM generation hook
You can define dom generation hook for each selector element like this(css property name is @xxx).
import { CssStyleSheet, DomCallbackContext } from 'nehan';
const myStyleSheet = new CssStyleSheet({
".foo": {
"@create": (ctx: DomCallbackContext) => {
ctx.dom.onclick = (e) => {
alert(`${ctx.selector} is clicked!`); // .foo is clicked!
};
}
}
});Plugins
Development
npm run build and library is generated in dist directory.
License
MIT
