osrl - 1/3

This commit is contained in:
babayaga 2025-12-30 16:33:03 +01:00
parent 14eeeaaf94
commit 81b58002c5
735 changed files with 100487 additions and 0 deletions

View File

@ -0,0 +1,85 @@
{
"name": "@plastichub/osr-discourse",
"description": "",
"version": "0.1.9",
"typings": "index.d.ts",
"publishConfig": {
"access": "public"
},
"module": "main.js",
"main": "main.js",
"bin": {
"osr-discourse": "main.js"
},
"dependencies": {
"@iarna/toml": "^2.2.5",
"@plastichub/core": "^0.2.5",
"@plastichub/fs": "^0.13.39",
"@plastichub/osr-cache": "^0.4.7",
"@plastichub/osr-cli-commons": "^0.5.1",
"@plastichub/osr-commons": "^0.3.3",
"@plastichub/osr-fs-utils": "^0.1.4",
"@plastichub/osrl": "file:../osrl",
"@types/markdown-it": "^12.2.3",
"@types/node": "^14.17.5",
"@types/yargs": "^17.0.11",
"axios": "^0.27.2",
"bluebird": "^3.7.2",
"chalk": "^2.4.1",
"cheerio": "^1.0.0-rc.12",
"chokidar": "^3.5.3",
"download": "^8.0.0",
"env-var": "^7.1.1",
"escape-html": "^1.0.3",
"fast-glob": "^3.3.0",
"filenamify": "^4.3.0",
"find-up": "^5.0.0",
"front-matter": "^4.0.2",
"generate-password": "^1.7.0",
"glob-base": "^0.3.0",
"isomorphic-unfetch": "^4.0.2",
"js-base64": "^3.7.2",
"js-beautify": "^1.14.9",
"json-to-pretty-yaml": "^1.2.2",
"markdown-it": "^13.0.1",
"md5": "^2.3.0",
"moment": "^2.29.4",
"native-promise-pool": "^3.19.0",
"pretty": "^2.0.0",
"querystring": "^0.2.1",
"request": "^2.88.2",
"sanitize-filename": "^1.6.3",
"showdown": "^2.1.0",
"simple-git": "^3.19.1",
"slugify": "^1.6.6",
"tslog": "^3.3.4",
"turndown": "^7.1.2",
"typescript": "^4.3.5",
"uri-js": "^4.4.1",
"yargs": "^17.5.1"
},
"scripts": {
"test": "tsc; mocha --full-trace mocha \"spec/**/*.spec.js\"",
"test-with-coverage": "istanbul cover node_modules/.bin/_mocha -- 'spec/**/*.spec.js'",
"lint": "tslint --project=./tsconfig.json",
"build": "tsc -p . --declaration",
"dev": "tsc -p . --declaration -w",
"typings": "tsc --declaration",
"docs": "npx typedoc src/index.ts",
"dev-test-watch": "mocha-typescript-watch",
"typesafe-i18n": "typesafe-i18n",
"link-dev": "sh scripts/link-dev.sh"
},
"homepage": "https://git.osr-plastic.org/plastichub/lib-content",
"repository": {
"type": "git",
"url": "https://git.osr-plastic.org/plastichub/lib-content.git"
},
"engines": {
"node": ">= 14.0.0"
},
"license": "BSD-3-Clause",
"keywords": [
"typescript"
]
}

View File

@ -0,0 +1,12 @@
# http://editorconfig.org
root = true
[*]
indent_style = tab
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

5
packages/osrl/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/node_modules
/coverage
*.log
.DS_Store
clear_history.sh

5
packages/osrl/.npmignore Normal file
View File

@ -0,0 +1,5 @@
./docs
./scripts
./tests
./examples
./documentation

10
packages/osrl/.travis.yml Normal file
View File

@ -0,0 +1,10 @@
language: node_js
node_js:
- "9"
script:
- npm run test
after_success:
- ./node_modules/.bin/codecov

164
packages/osrl/.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,164 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Grunt - Docs",
"skipFiles": [
"<node_internals>/**"
],
"program": "${env:APPDATA}\\npm\\node_modules\\grunt\\bin\\grunt",
"cwd": "${workspaceRoot}",
"args": [
"compile:content-en",
"--verbose=false",
"--watchContent=true",
"--cache=false",
"--logLevel=debug",
"--stack"
],
"outFiles": [
"${workspaceFolder}/**/*.js"
],
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**"
],
"outputCapture": "std"
},
{
"type": "node",
"request": "launch",
"name": "lang:compile:expand - i18n",
"skipFiles": [],
"program": "${workspaceFolder}\\main.js",
"outFiles": [
"${workspaceFolder}/**/*.js"
],
"cwd": "${workspaceFolder}",
"args": [
"compile",
"--language=osr",
"--debug=true",
"--expand=true",
"--product=asterix",
"--source=\"./examples/library/osr/bazar/root-i18n.html\"",
"--output=\"${root}/${product}/bazar/output-i18n.html\"",
"--root=\"./examples/library\"",
"--profile='${root}/.osrl.json'",
"--plugins='${root}/osr/plugins'",
"--env='bazar'",
"--stdout=true",
"--targetLanguage=de",
"--sourceLanguage=en"
],
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**"
],
"outputCapture": "std"
},
{
"type": "node",
"request": "launch",
"name": "lang:compile:osr-ai",
"program": "${workspaceFolder}\\main.js",
"outFiles": [
"${workspaceFolder}/**/*.js"
],
"cwd": "${workspaceFolder}",
"args": [
"compile",
"--language=osr",
"--expand=true",
"--testvar=asterix",
"--source='./tests/osr-ai/open-ai-test.md'",
"--output='./tests/osr-ai/open-ai-test.out.md'",
"--root='./tests/open-ai'",
"--format2=html",
"--stdout=true",
"--var-area=sentmenat",
"--logLevel=trace"
],
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**"
],
"outputCapture": "std"
},
{
"type": "node",
"request": "launch",
"name": "lang:compile:template",
"skipFiles": [],
"program": "${workspaceFolder}\\main.js",
"outFiles": [
"${workspaceFolder}/**/*.js"
],
"cwd": "${workspaceFolder}",
"args": [
"compile",
"--language=osr",
"--expand=true",
"--source=\"./tests/templates/source.md\"",
"--template=\"./tests/templates/template.md\"",
"--output=\"./tests/templates/output.md\"",
"--root=\"./tests/templates\"",
"--profile='${OSR_ROOT}/osr-templates/osrl/.osrl.json'",
"--plugins='${root}/osr/plugins'",
"--env='library'",
"--format2=html",
"--stdout=true",
"--trace='${SRC_DIR}/${SRC_NAME}-trace.json'",
"--logLevel=trace",
"--var-area=Sentmenat",
"--var-location=(Spain,Barcelona)",
],
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**"
],
"outputCapture": "std"
},
{
"type": "node",
"request": "launch",
"name": "lang:compile:plugins",
"skipFiles": [],
"program": "${workspaceFolder}\\main.js",
"outFiles": [
"${workspaceFolder}/**/*.js"
],
"cwd": "${workspaceFolder}",
"args": [
"compile",
"--language=osr",
"--expand=true",
"--source=\"./tests/plugins/source.md\"",
"--template=\"./tests/plugins/template.md\"",
"--output=\"./tests/plugins/output.md\"",
"--root=\"./tests/templates\"",
"--profile='${OSR_ROOT}/osr-templates/osrl/.osrl.json'",
"--plugins='${root}/osr/plugins'",
"--env='library'",
"--format2=html",
"--stdout=true",
"--logLevel=trace",
"--var-area=Sentmenat",
"--var-location=(Spain,Barcelona)",
"--targetLanguage=es",
"--sourceLanguage=en"
],
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**"
],
"outputCapture": "std"
}
]
}

6
packages/osrl/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"cSpell.words": [
"cacache",
"plastichub"
]
}

22
packages/osrl/Engine.d.ts vendored Normal file
View File

@ -0,0 +1,22 @@
import { Liquid } from './liquidjs/liquid';
import { IObjectLiteral } from '@plastichub/core';
export { sync as dir } from '@plastichub/fs/dir';
import { Context } from './conf/bootstrap';
import { IOptions } from './types';
export declare const getEngine: () => Engine;
export declare const getContext: () => Context;
export declare class LiquidEx extends Liquid {
owner: Engine;
}
export declare class Engine {
constructor(options: IOptions);
engine: LiquidEx;
options: IOptions;
variables: IObjectLiteral;
expressionCache: IObjectLiteral;
global: any;
context: Context;
stats: any;
render(sourceFile: string, vars: IObjectLiteral): Promise<any>;
parse(string: string, vars: any, iterations?: number): Promise<any>;
}

207
packages/osrl/Engine.js Normal file

File diff suppressed because one or more lines are too long

28
packages/osrl/LICENSE Normal file
View File

@ -0,0 +1,28 @@
The "New" BSD License
*********************
Copyright (c) 2015 - 2016, xblox
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the xblox nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

108
packages/osrl/README.md Normal file
View File

@ -0,0 +1,108 @@
# Content & Expression Engine based on Liquid (JS Implementation)
## Installation
```sh
# local
npm install @plastichub/osrl
#global
npm -g @plastichub/osrl
# CLI help
osrl compile --help
```
### References
- [LiquidJS Docs](https://liquidjs.com/api/classes/liquid_.liquid.html)
- [Liquid Docs - Shopify](https://shopify.github.io/liquid/)
### Usage
Please find examples in ['./examples](./examples)
## Todos
- [ ] Filter/Tags
- [x] Datasources
- [x] Google Sheet
- [x] Local Sheet
- see [exceljs](https://github.com/exceljs/exceljs)
- [x] CSV
- [x] selectors
- [ ] Iterators (scopes)
- [ ] Enums
- [ ] CSS Parser
- [ ] Files / Refs / Variables
- [ ] PDF tables, see [site:tabula](https://github.com/tabulapdf/tabula)
- [ ] JS
- [x] Bind Datasources in local scope
- [x] Default bootstrap
- [x] Plastichub
- [-] OSR
- [x] Default functions: unit conv, string manipulation
- [x] User Plugins
- [x] Refine Engine for scoping
- [ ] RT Security
- Options
- [Secure VM (native)](https://github.com/laverdet/isolated-vm)
- [VM2](https://github.com/patriksimek/vm2#debugging-a-sandboxed-code)
- [ ] fix fucking globals
- [ ] run plugins in cached vm.Script contexts
- [-] Multi Env
- [x] support multi env in profiles
- [x] Settings / Profile
- [-] should read local profil per consumed directory within ```include``` calls
- [-] Instrumentation
- add support for clinic.js | clinic.doctor
- [ ] Platform / Services
- [x] Discourse - API (related, category feed, custom search, topic acc)
- [-] Magento - API (related, components, configurations, options)
- [-] Media Wiki
- [-] CSCart API
- [ ] Documentation
- [ ] Auto - JS Bootstrap docs
- [ ] Generate documented tests
- [ ] Watcher
- [x] OSRL commons (plugins)
- [x] Partials cache
- [x] osr-cache
- [-] VFS & RQL
- [-] OSR-Search
- [-] consume/provide elastic-search queries
- [ ] PDF mining : https://pypi.org/project/pdfminer/
- [x] basics
- [x] new include tag 'emerge' based on the original 'include'
- [x] context/implicit: evaluate conditional statement as variable
- [-] implicit: forward output format (New: AST/partials), gives format agnostic results
- [-] explicit: cache expiration (=>osr-tasks)
- [ ] track i/o access in context meta db
- [ ] i/o: re-impl. old vfs/service API
- [-] output masking via profile json(-get) paths
- [-] support pandoc for input/output pre/post processing
- [x] OSR-i18n
- [x] tags
- [ ] typings
- [ ] partials => store
- [ ] OSR-AI
- [x] prompt tags
- [ ] Doxygen
- [ ] Binaries
- [ ] Pipes
- [ ] Watcher
- [ ] watch glob
- [ ] Targets
- [ ] Logging
- [ ] Typescript
## References
- https://docs.asciidoctor.org/
- https://github.com/asciidoctor/asciidoctor.js
- [MDAST & Co](https://github.com/syntax-tree/mdast-util-to-markdown)
- https://www.npmjs.com/package/link-preview-js
- https://github.com/microlinkhq/metascraper
- https://github.com/arcetros/scrape-recipe-schema/blob/main/src/index.ts
- https://github.com/digitalbazaar/jsonld.js

45
packages/osrl/_cli.d.ts vendored Normal file
View File

@ -0,0 +1,45 @@
import * as CLI from 'yargs';
import { IOptions } from './types';
export declare const defaultOptions: (yargs: CLI.Argv) => CLI.Argv<{
format: string;
} & {
source: unknown;
} & {
template: unknown;
} & {
language: string;
} & {
bootstrap: unknown;
} & {
variables: string;
} & {
trace: string;
} & {
output: string;
} & {
disable: unknown;
} & {
profile: string;
} & {
envVariables: string | boolean;
} & {
stdout: string | boolean;
} & {
dry: string | boolean;
} & {
introspect: unknown;
} & {
env: unknown;
} & {
alt: boolean;
} & {
plugins: unknown;
} & {
targetLanguage: string;
} & {
sourceLanguage: string;
} & {
logLevel: string;
}>;
export declare const sanitize: (argv: any) => IOptions | boolean;
export declare const defaults: () => void;

169
packages/osrl/_cli.js Normal file

File diff suppressed because one or more lines are too long

0
packages/osrl/body.md Normal file
View File

4
packages/osrl/commands/compile.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
import * as CLI from 'yargs';
import { IOptions } from '../types';
export declare const targets: (f: string, options: IOptions) => any[];
export declare const register: (cli: CLI.Argv) => CLI.Argv<{}>;

File diff suppressed because one or more lines are too long

2
packages/osrl/commands/init.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
import * as CLI from 'yargs';
export declare const register: (cli: CLI.Argv) => CLI.Argv<{}>;

View File

@ -0,0 +1,40 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.register = void 0;
const index_1 = require("../index");
const _cli_1 = require("../_cli");
const sheets_1 = require("../lib/net/sheets");
let options = (yargs) => (0, _cli_1.defaultOptions)(yargs);
// node ./main.js init google-sheets --sheet='1oVEiGH4o3SV-mAA3Mb-WNVJMyYl4VMxLjWjrSw_ipJY' --range='Parts!B4:B5'
const initGSheets = (sheet, range) => __awaiter(void 0, void 0, void 0, function* () {
return (0, sheets_1.read)(sheet, range);
});
const register = (cli) => {
return cli.command('init <verb>', 'Initialize specific language features', options, (argv) => __awaiter(void 0, void 0, void 0, function* () {
if (argv.help) {
return;
}
const verb = argv.verb;
if (!verb) {
index_1.logger.error(`You need to specify a verb`);
}
if (verb === 'google-sheets') {
const sheet = argv.sheet;
const range = argv.range;
initGSheets(sheet, range).then((d) => {
index_1.logger.info('done google auth | sheet result', d);
});
}
}));
};
exports.register = register;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kcy9pbml0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUNBLG9DQUFrQztBQUNsQyxrQ0FBeUM7QUFDekMsOENBQXlDO0FBRXpDLElBQUksT0FBTyxHQUFHLENBQUMsS0FBZSxFQUFFLEVBQUUsQ0FBQyxJQUFBLHFCQUFjLEVBQUMsS0FBSyxDQUFDLENBQUM7QUFFekQsaUhBQWlIO0FBRWpILE1BQU0sV0FBVyxHQUFHLENBQU8sS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO0lBQ3ZDLE9BQU8sSUFBQSxhQUFJLEVBQUMsS0FBSyxFQUFDLEtBQUssQ0FBQyxDQUFBO0FBQzVCLENBQUMsQ0FBQSxDQUFBO0FBRU0sTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFhLEVBQUUsRUFBRTtJQUN0QyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLHVDQUF1QyxFQUFFLE9BQU8sRUFBRSxDQUFPLElBQW1CLEVBQUUsRUFBRTtRQUM5RyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDWCxPQUFPO1NBQ1Y7UUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ3ZCLElBQUcsQ0FBQyxJQUFJLEVBQUM7WUFDTCxjQUFNLENBQUMsS0FBSyxDQUFDLDRCQUE0QixDQUFDLENBQUM7U0FDOUM7UUFFRCxJQUFHLElBQUksS0FBRyxlQUFlLEVBQUM7WUFDdEIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUN6QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQ3pCLFdBQVcsQ0FBQyxLQUFLLEVBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFDLEVBQUU7Z0JBQy9CLGNBQU0sQ0FBQyxJQUFJLENBQUMsaUNBQWlDLEVBQUUsQ0FBQyxDQUFFLENBQUM7WUFDdkQsQ0FBQyxDQUFDLENBQUE7U0FDTDtJQUNMLENBQUMsQ0FBQSxDQUFDLENBQUM7QUFDUCxDQUFDLENBQUM7QUFsQlcsUUFBQSxRQUFRLFlBa0JuQiJ9

37
packages/osrl/conf/bootstrap.d.ts vendored Normal file
View File

@ -0,0 +1,37 @@
/// <reference types="node" />
import { IBaseOptions, IProcessingNode } from '@plastichub/fs/interfaces';
import { ArrayIterator } from '@plastichub/core/iterator';
import { IObjectLiteral } from '@plastichub/core';
export interface Context extends IObjectLiteral {
markdownTable: (data: any, options?: any) => string;
cacache: any;
cheerio: any;
TOML: any;
frontmatter: any;
logger: any;
config: any;
PATHS: any;
fs: {
findUp: any;
iterator: (from: string, options: IBaseOptions) => ArrayIterator<IProcessingNode>;
glob: (path: string, options: any) => string[];
slash: (s: string) => string;
EIteratorFlags: {
MODE: 2;
TIMES: 4;
SYMLINKS: 8;
FILE_SIZE: 16;
DIRECTORY_SIZE: 32;
CHECKSUM: 64;
MIME: 128;
};
sizeToString: (size: number) => string;
dir: (dir: any, glob: any) => string[];
path: any;
exists: (path: string) => boolean | string;
resolve: (path: string, alt: boolean, vars: IObjectLiteral) => string[];
write: (path: string, content: string) => void;
read: (path: string, type: string) => string | Buffer;
};
}
export declare const context: Context;

79
packages/osrl/conf/bootstrap.js vendored Normal file
View File

@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.context = void 0;
const path = require("path");
const index_1 = require("../lib/index");
const __1 = require("../");
const StringUtils = require("../lib/StringUtils");
const HexUtils = require("../lib/HexUtils");
const Arrays = require("../lib/arrays");
const Primitives = require("../lib/primitives");
const markdown_1 = require("../lib/markdown");
const fm = require("front-matter");
const fs_1 = require("../lib/fs");
const osr_commons_1 = require("@plastichub/osr-commons");
const iterator_1 = require("@plastichub/fs/iterator");
const exists_1 = require("@plastichub/fs/exists");
const write_1 = require("@plastichub/fs/write");
const read_1 = require("@plastichub/fs/read");
const osr_commons_2 = require("@plastichub/osr-commons");
const env = require("env-var");
const os = require("os");
const fs = require("fs");
const crypto = require("crypto");
const cheerio = require("cheerio");
const bluebird_1 = require("bluebird");
const cacache = require("cacache");
const js_beautify_1 = require("js-beautify");
const convert = require('convert-units');
const fg = require('fast-glob');
const findUp = require('find-up');
const hljs = require('highlight.js');
const prettyHtml = require('json-pretty-html').default;
const prettyJSON = require('json-format-highlight');
const TOML = require('@iarna/toml');
const TOMLParser = require('@iarna/toml/lib/toml-parser.js');
const xlsx = require('node-xlsx');
const YAML = require('json-to-pretty-yaml');
exports.context = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ convert: convert }, StringUtils), HexUtils), Arrays), Primitives), { markdownTable: markdown_1.markdownTable,
md2html: markdown_1.md2html,
cacache,
cheerio,
logger: __1.logger, config: (0, osr_commons_1.CONFIG_DEFAULT)(), PATHS: osr_commons_1.DEFAULT_ROOTS, TOML: {
parse: TOML.parse,
stringify: TOML.stringify,
parser: TOMLParser
}, frontmatter: fm, YAML,
resolveConfig: index_1.resolveConfig,
prettyHtml,
prettyJSON,
html_beautify: js_beautify_1.html_beautify,
BPromise: bluebird_1.Promise,
hljs, xlsx: {
build: xlsx.build,
parse: xlsx.parse
}, path, fs: Object.assign(Object.assign({ findUp: findUp, iterator: iterator_1.sync, glob: fg, slash: fs_1.forward_slash, EIteratorFlags: {
MODE: 2,
TIMES: 4,
SYMLINKS: 8,
FILE_SIZE: 16,
DIRECTORY_SIZE: 32,
CHECKSUM: 64,
MIME: 128
}, sizeToString: fs_1.sizeToString, dir: (dir, glob) => fg.sync(glob, { dot: true, cwd: dir, absolute: true }) }, fs), { path,
exists: exists_1.sync,
resolve: osr_commons_2.resolve,
write: write_1.sync, read: read_1.sync }), os: Object.assign({ env: env }, os), crypto: Object.assign(Object.assign({}, crypto), { encrypt: (text, password, algorithm = 'aes-256-cbc') => {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, password, iv);
let crypted = cipher.update(text, 'utf8', 'hex');
crypted += cipher.final('hex');
return crypted;
}, decrypt: (text, password, algorithm = 'aes-128-ecb') => {
const iv = crypto.randomBytes(16);
const decipher = crypto.createCipheriv(algorithm, password, iv);
let dec = decipher.update(text, 'hex', 'utf8');
dec += decipher.final('utf8');
return dec;
} }) });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdHN0cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbmYvYm9vdHN0cmFwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUE0QjtBQUM1Qix3Q0FBNEM7QUFDNUMsMkJBQTRCO0FBQzVCLGtEQUFpRDtBQUNqRCw0Q0FBMkM7QUFDM0Msd0NBQXVDO0FBQ3ZDLGdEQUErQztBQUMvQyw4Q0FBd0Q7QUFDeEQsbUNBQWtDO0FBQ2xDLGtDQUF1RDtBQUN2RCx5REFBdUU7QUFFdkUsc0RBQTBEO0FBQzFELGtEQUFzRDtBQUN0RCxnREFBb0Q7QUFDcEQsOENBQWtEO0FBRWxELHlEQUFpRDtBQUdqRCwrQkFBK0I7QUFDL0IseUJBQXdCO0FBQ3hCLHlCQUF3QjtBQUN4QixpQ0FBZ0M7QUFDaEMsbUNBQWtDO0FBQ2xDLHVDQUE4QztBQUM5QyxtQ0FBa0M7QUFDbEMsNkNBQTJDO0FBRTNDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQTtBQUN4QyxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUE7QUFDL0IsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0FBQ2pDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUMsQ0FBQTtBQUNwQyxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxPQUFPLENBQUE7QUFDdEQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixDQUFDLENBQUE7QUFDbkQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFBO0FBQ25DLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFBO0FBQzVELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQTtBQUNqQyxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQTtBQXVDOUIsUUFBQSxPQUFPLDJFQUNuQixPQUFPLEVBQUUsT0FBTyxJQUNiLFdBQVcsR0FDWCxRQUFRLEdBQ1IsTUFBTSxHQUNOLFVBQVUsS0FDYixhQUFhLEVBQWIsd0JBQWE7SUFDYixPQUFPLEVBQVAsa0JBQU87SUFDUCxPQUFPO0lBQ1AsT0FBTztJQUNQLE1BQU0sRUFBTixVQUFNLEVBQ04sTUFBTSxFQUFFLElBQUEsNEJBQWMsR0FBRSxFQUN4QixLQUFLLEVBQUUsMkJBQWEsRUFDcEIsSUFBSSxFQUFFO1FBQ0wsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO1FBQ2pCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztRQUN6QixNQUFNLEVBQUUsVUFBVTtLQUNsQixFQUNELFdBQVcsRUFBRSxFQUFFLEVBQ2YsSUFBSTtJQUNKLGFBQWEsRUFBYixxQkFBYTtJQUNiLFVBQVU7SUFDVixVQUFVO0lBQ1YsYUFBYSxFQUFiLDJCQUFhO0lBQ2IsUUFBUSxFQUFSLGtCQUFRO0lBQ1IsSUFBSSxFQUNKLElBQUksRUFBRTtRQUNMLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztRQUNqQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7S0FDakIsRUFDRCxJQUFJLEVBQ0osRUFBRSxnQ0FDRCxNQUFNLEVBQUUsTUFBTSxFQUNkLFFBQVEsRUFBRSxlQUFRLEVBQ2xCLElBQUksRUFBRSxFQUFFLEVBQ1IsS0FBSyxFQUFFLGtCQUFhLEVBQ3BCLGNBQWMsRUFBRTtZQUNmLElBQUksRUFBRSxDQUFDO1lBQ1AsS0FBSyxFQUFFLENBQUM7WUFDUixRQUFRLEVBQUUsQ0FBQztZQUNYLFNBQVMsRUFBRSxFQUFFO1lBQ2IsY0FBYyxFQUFFLEVBQUU7WUFDbEIsUUFBUSxFQUFFLEVBQUU7WUFDWixJQUFJLEVBQUUsR0FBRztTQUNULEVBQ0QsWUFBWSxFQUFFLGlCQUFZLEVBQzFCLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBTyxJQUM3RSxFQUFFLEtBQ0wsSUFBSTtRQUNKLE1BQU0sRUFBTixhQUFNO1FBQ04sT0FBTyxFQUFQLHFCQUFPO1FBQ1AsS0FBSyxFQUFMLFlBQUssRUFDTCxJQUFJLEVBQUUsV0FBVyxLQUVsQixFQUFFLGtCQUNELEdBQUcsRUFBRSxHQUFHLElBQ0wsRUFBRSxHQUVOLE1BQU0sa0NBQ0YsTUFBTSxLQUNULE9BQU8sRUFBRSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsU0FBUyxHQUFHLGFBQWEsRUFBRSxFQUFFO1lBQ3RELE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDbEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzlELElBQUksT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNqRCxPQUFPLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvQixPQUFPLE9BQU8sQ0FBQztRQUNoQixDQUFDLEVBQ0QsT0FBTyxFQUFFLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxTQUFTLEdBQUcsYUFBYSxFQUFFLEVBQUU7WUFDdEQsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNsQyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUE7WUFDL0QsSUFBSSxHQUFHLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLEdBQUcsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzlCLE9BQU8sR0FBRyxDQUFDO1FBQ1osQ0FBQyxPQUVGIn0=

46
packages/osrl/config.js Normal file
View File

@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TASK_LOG_DIRECTORY = exports.TASK_COMPILE_CONTENT_CACHE = exports.TASK_CONFIG_LOG_DIRECTORY = exports.ENABLED_PRODUCTS = exports.OSRL_LANG_FLAVOR = exports.OSRL_PROFILE = exports.OSRL_MODULE_NAME = exports.PRODUCTS_TARGET_SRC = exports.PRODUCT_HUGO_TEMPLATE = exports.OSRL_ENVIRONMENT = exports.OSRL_ENV_DEV = exports.OSRL_ENV = exports.IS_DEV = exports.PRODUCT_DIR = exports.PRODUCT_CONFIG = exports.PRODUCT_ROOT = exports.I18N_SOURCE_LANGUAGE = exports.I18N_STORE = exports.I18N_STORE_EN = exports.LANGUAGES_ALL = exports.LANGUAGES = exports.TRANSLATE_CONTENT = exports.OSR_ROOT = void 0;
const path = require("path");
const fs_1 = require("@plastichub/osr-commons");
const OSR_ROOT = () => path.resolve((0, fs_1.resolve)("${OSR_ROOT}"));
exports.OSR_ROOT = OSR_ROOT;
// Supported languages
exports.TRANSLATE_CONTENT = true; // translate regular pages
exports.LANGUAGES = ['de'];
exports.LANGUAGES_ALL = ['de', 'fr', 'es'];
// i18n constants
exports.I18N_STORE_EN = "${cwd}/i18n-store/store-en.json";
const I18N_STORE = (root, lang) => `${root}/i18n-store/store-${lang}.json`;
exports.I18N_STORE = I18N_STORE;
exports.I18N_SOURCE_LANGUAGE = 'en';
// Product compiler
const PRODUCT_ROOT = () => path.resolve((0, fs_1.resolve)("${OSR_ROOT}/products"));
exports.PRODUCT_ROOT = PRODUCT_ROOT;
const PRODUCT_CONFIG = (product) => path.resolve((0, fs_1.resolve)("${OSR_ROOT}/products/${product}/config.json", false, {
product
}));
exports.PRODUCT_CONFIG = PRODUCT_CONFIG;
const PRODUCT_DIR = (product) => path.resolve((0, fs_1.resolve)("${OSR_ROOT}/products/${product}", false, {
product
}));
exports.PRODUCT_DIR = PRODUCT_DIR;
exports.IS_DEV = true;
exports.OSRL_ENV = 'library';
exports.OSRL_ENV_DEV = 'hugo-debug';
exports.OSRL_ENVIRONMENT = exports.IS_DEV ? exports.OSRL_ENV_DEV : exports.OSRL_ENV;
exports.PRODUCT_HUGO_TEMPLATE = './osr/hugo/root.html';
exports.PRODUCTS_TARGET_SRC = './src/content/en/retail';
// OSRL - Language
exports.OSRL_MODULE_NAME = 'osrl-docs';
exports.OSRL_PROFILE = '${root}/.osrl.json';
exports.OSRL_LANG_FLAVOR = 'osr';
// Products
exports.ENABLED_PRODUCTS = "./config/machines.json";
// Tasks
exports.TASK_CONFIG_LOG_DIRECTORY = './config/';
// Task: compile:content
exports.TASK_COMPILE_CONTENT_CACHE = true;
// Task - Logging
exports.TASK_LOG_DIRECTORY = './logs/';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidGFza3MvY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUE0QjtBQUM1Qix1REFBd0Q7QUFFakQsTUFBTSxRQUFRLEdBQUcsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFBLFlBQU8sRUFBQyxhQUFhLENBQUMsQ0FBQyxDQUFBO0FBQXJELFFBQUEsUUFBUSxZQUE2QztBQUVsRSxzQkFBc0I7QUFDVCxRQUFBLGlCQUFpQixHQUFHLElBQUksQ0FBQSxDQUFDLDBCQUEwQjtBQUNuRCxRQUFBLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO0FBQ2xCLFFBQUEsYUFBYSxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQTtBQUUvQyxpQkFBaUI7QUFDSixRQUFBLGFBQWEsR0FBRyxpQ0FBaUMsQ0FBQTtBQUN2RCxNQUFNLFVBQVUsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxxQkFBcUIsSUFBSSxPQUFPLENBQUE7QUFBcEUsUUFBQSxVQUFVLGNBQTBEO0FBQ3BFLFFBQUEsb0JBQW9CLEdBQUcsSUFBSSxDQUFBO0FBRXhDLG1CQUFtQjtBQUNaLE1BQU0sWUFBWSxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBQSxZQUFPLEVBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFBO0FBQWxFLFFBQUEsWUFBWSxnQkFBc0Q7QUFDeEUsTUFBTSxjQUFjLEdBQUcsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUN4QyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsWUFBTyxFQUFDLDZDQUE2QyxFQUFFLEtBQUssRUFDdkU7SUFDRSxPQUFPO0NBQ1IsQ0FBQyxDQUFDLENBQUE7QUFKTSxRQUFBLGNBQWMsa0JBSXBCO0FBRUksTUFBTSxXQUFXLEdBQUcsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUN6QyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsWUFBTyxFQUFDLGlDQUFpQyxFQUFFLEtBQUssRUFDM0Q7SUFDRSxPQUFPO0NBQ1IsQ0FBQyxDQUFDLENBQUE7QUFKVSxRQUFBLFdBQVcsZUFJckI7QUFFVSxRQUFBLE1BQU0sR0FBRyxJQUFJLENBQUE7QUFDakIsUUFBQSxRQUFRLEdBQUcsU0FBUyxDQUFBO0FBQ3BCLFFBQUEsWUFBWSxHQUFHLFlBQVksQ0FBQTtBQUMzQixRQUFBLGdCQUFnQixHQUFHLGNBQU0sQ0FBQyxDQUFDLENBQUMsb0JBQVksQ0FBQyxDQUFDLENBQUMsZ0JBQVEsQ0FBQTtBQUNuRCxRQUFBLHFCQUFxQixHQUFHLHNCQUFzQixDQUFBO0FBQzlDLFFBQUEsbUJBQW1CLEdBQUcseUJBQXlCLENBQUE7QUFFNUQsa0JBQWtCO0FBQ0wsUUFBQSxnQkFBZ0IsR0FBRyxXQUFXLENBQUE7QUFDOUIsUUFBQSxZQUFZLEdBQUcsb0JBQW9CLENBQUE7QUFDbkMsUUFBQSxnQkFBZ0IsR0FBRyxLQUFLLENBQUE7QUFFckMsV0FBVztBQUNFLFFBQUEsZ0JBQWdCLEdBQUcsd0JBQXdCLENBQUE7QUFFeEQsUUFBUTtBQUNLLFFBQUEseUJBQXlCLEdBQUcsV0FBVyxDQUFBO0FBRXBELHdCQUF3QjtBQUNYLFFBQUEsMEJBQTBCLEdBQUcsSUFBSSxDQUFBO0FBRTlDLGlCQUFpQjtBQUNKLFFBQUEsa0JBQWtCLEdBQUcsU0FBUyxDQUFBIn0=

2
packages/osrl/constants.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export declare const MODULE_NAME = "OSRL";
export declare const PROFILE_FILE_NAME = ".osrl.json";

View File

@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PROFILE_FILE_NAME = exports.MODULE_NAME = void 0;
exports.MODULE_NAME = `OSRL`;
exports.PROFILE_FILE_NAME = `.osrl.json`;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBYSxRQUFBLFdBQVcsR0FBRyxNQUFNLENBQUE7QUFDcEIsUUFBQSxpQkFBaUIsR0FBRyxZQUFZLENBQUEifQ==

View File

@ -0,0 +1,12 @@
Source Language2 : en
Target Language2 : de
```json
{
}
```

View File

@ -0,0 +1,40 @@
## Example : List all major cities of Spain, as JSON Array, then iterate over it to retrieve tourist attractions
## [ Madrid ](/Madrid)
- [Royal Palace of Madrid](https://www.patrimonionacional.es/en/real-sitio/palacios/royal-palace-madrid)
- [Prado Museum](https://www.museodelprado.es/en)
- [Retiro Park](https://www.esmadrid.com/en/tourist-information/parque-del-retiro)
- [Plaza Mayor](https://www.esmadrid.com/en/tourist-information/plaza-mayor)
- [Puerta del Sol](https://www.esmadrid.com/en/tourist-information/puerta-del-sol)
- [Thyssen-Bornemisza Museum](https://www.museothyssen.org/en)
- [Santiago Bernabéu Stadium](https://www.realmadrid.com/en/santiago-bernabeu-stadium)
- [Temple of Debod](https://www.esmadrid.com/en/tourist-information/templo-debod)
- [Gran Vía](https://www.esmadrid.com/en/tourist-information/gran-via)
- [Plaza de Cibeles](https://www.esmadrid.com/en/tourist-information/fuente-de-la-cibeles)
- [Reina Sofia Museum](https://www.museoreinasofia.es/en)
- [Mercado de San Miguel](https://www.mercadodesanmiguel.es/en/)
- [El Rastro](https://www.esmadrid.com/en/shopping/el-rastro)
- [Plaza de España](https://www.esmadrid.com/en/tourist-information/plaza-de-espana)
- [National Archaeological Museum](http://www.man.es/man/en/home)
## [ Barcelona ](/Barcelona)
- [La Sagrada Familia](https://sagradafamilia.org)
- [Park Güell](https://www.parkguell.cat)
- [Casa Batlló](https://www.casabatllo.es)
- [La Rambla](https://www.barcelona.com/barcelona_directory/monuments/la_rambla)
- [Gothic Quarter (Barri Gòtic)](https://www.barcelona.com/barcelona_directory/monuments/gothic_quarter)
- [Camp Nou](https://www.fcbarcelona.com/en/club/facilities/camp-nou)
- [Magic Fountain (Font Màgica)](https://www.barcelona.cat/en/what-to-do-in-bcn/magic-fountain/magic-fountain)
- [Montjuïc Hill](https://www.barcelona.com/barcelona_directory/monuments/montjuic)
- [Palau de la Música Catalana](https://www.palaumusica.cat)
- [Casa Milà (La Pedrera)](https://www.lapedrera.com)
- [Picasso Museum](https://www.museupicassobcn.org)
- [Barcelona Cathedral](https://www.catedralbcn.org)
- [Barceloneta Beach](https://www.barcelona-tourist-guide.com/en/attractions/barceloneta.html)
- [Poble Espanyol](https://www.poble-espanyol.com)
- [Tibidabo Amusement Park](https://www.tibidabo.cat/en)
- [Hospital de Sant Pau](https://www.santpaubarcelona.org)
- [Arc de Triomf](https://www.barcelona.com/barcelona_directory/monuments/arc_de_triomphe)
- [Mercat de Sant Josep de la Boqueria (La Boqueria Market)](https://www.boqueria.barcelona)

View File

@ -0,0 +1,12 @@
Source Language2 : en
Target Language2 : de
```json
{
}
```

View File

@ -0,0 +1,105 @@
### Create a SVG Animation
- argument `skip` : skip existing results (only works with `dst` specified).
```js
[% osr-ai model:"gpt-4o" skip:true gui:true logLevel:"warn" filters:"code,trim" dst:"${SRC_DIR}/${SRC_NAME}.svg" %]
Create a 4 balls, rotating around the outside of a cube, as SVG
- no comments
- scale it to 400x400px
- add another ball bouncing against the inside walls of the cube
[% osr-ai-end %]
```
<svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<style>
.rotating-ball {
animation: rotate 4s linear infinite;
}
.bouncing-ball {
animation: bounce 2s infinite;
}
@keyframes rotate {
0% { transform: translate(200px, 200px) rotate(0deg) translate(100px) rotate(0deg); }
100% { transform: translate(200px, 200px) rotate(360deg) translate(100px) rotate(-360deg); }
}
@keyframes bounce {
0% { transform: translate(50px, 50px) }
25% { transform: translate(350px, 50px) }
50% { transform: translate(350px, 350px) }
75% { transform: translate(50px, 350px) }
100% { transform: translate(50px, 50px) }
}
</style>
<rect x="0" y="0" width="400" height="400" fill="none" stroke="black" />
<circle class="rotating-ball" cx="0" cy="0" r="20" fill="red" />
<circle class="rotating-ball" style="animation-delay: -1s;" cx="0" cy="0" r="20" fill="blue" />
<circle class="rotating-ball" style="animation-delay: -2s;" cx="0" cy="0" r="20" fill="green" />
<circle class="rotating-ball" style="animation-delay: -3s;" cx="0" cy="0" r="20" fill="yellow" />
<circle class="bouncing-ball" cx="0" cy="0" r="20" fill="purple" />
</svg>
### Create an animated solar system
```js
[% osr-ai model:"gpt-4o" skip:false gui:true logLevel:"warn" filters:"code,trim" dst:"${SRC_DIR}/${SRC_NAME}-solar.svg" %]
Simluate the solar system, as SVG
- Each planet should open the link to Wikipedia.
- all planets rotate around the sun (center), animated, slow, add a thin line for the orbit
- Add a legend with basic information : size, weight, age, make sure it fits in the screen
- compact the code, no comments
- make it all fit to 600x600px
All as SVG, no comments
[% osr-ai-end %]
```
<svg width="600" height="600" viewBox="0 0 600 600" xmlns="http://www.w3.org/2000/svg" style="background-color:black;border:1px solid black">
<circle cx="300" cy="300" r="20" fill="yellow"/>
<circle cx="420" cy="300" r="0.5" stroke="gray"/>
<circle cx="420" cy="300" r="4" fill="gray">
<animateTransform attributeName="transform" type="rotate" from="0 300 300" to="360 300 300" dur="10s" repeatCount="indefinite"/>
<a xlink:href="https://en.wikipedia.org/wiki/Mercury_(planet)"/>
</circle>
<circle cx="360" cy="300" r="0.5" stroke="gray"/>
<circle cx="360" cy="300" r="7" fill="gainsboro">
<animateTransform attributeName="transform" type="rotate" from="0 300 300" to="360 300 300" dur="20s" repeatCount="indefinite"/>
<a xlink:href="https://en.wikipedia.org/wiki/Venus"/>
</circle>
<circle cx="320" cy="300" r="0.5" stroke="gray"/>
<circle cx="320" cy="300" r="8" fill="blue">
<animateTransform attributeName="transform" type="rotate" from="0 300 300" to="360 300 300" dur="30s" repeatCount="indefinite"/>
<a xlink:href="https://en.wikipedia.org/wiki/Earth"/>
</circle>
<circle cx="284" cy="300" r="0.5" stroke="gray"/>
<circle cx="284" cy="300" r="5" fill="red">
<animateTransform attributeName="transform" type="rotate" from="0 300 300" to="360 300 300" dur="40s" repeatCount="indefinite"/>
<a xlink:href="https://en.wikipedia.org/wiki/Mars"/>
</circle>
<circle cx="230" cy="300" r="0.5" stroke="gray"/>
<circle cx="230" cy="300" r="14" fill="orange">
<animateTransform attributeName="transform" type="rotate" from="0 300 300" to="360 300 300" dur="50s" repeatCount="indefinite"/>
<a xlink:href="https://en.wikipedia.org/wiki/Jupiter"/>
</circle>
<circle cx="170" cy="300" r="0.5" stroke="gray"/>
<circle cx="170" cy="300" r="12" fill="khaki">
<animateTransform attributeName="transform" type="rotate" from="0 300 300" to="360 300 300" dur="60s" repeatCount="indefinite"/>
<a xlink:href="https://en.wikipedia.org/wiki/Saturn"/>
</circle>
<circle cx="110" cy="300" r="0.5" stroke="gray"/>
<circle cx="110" cy="300" r="10" fill="lightblue">
<animateTransform attributeName="transform" type="rotate" from="0 300 300" to="360 300 300" dur="70s" repeatCount="indefinite"/>
<a xlink:href="https://en.wikipedia.org/wiki/Uranus"/>
</circle>
<circle cx="50" cy="300" r="0.5" stroke="gray"/>
<circle cx="50" cy="300" r="9" fill="blue">
<animateTransform attributeName="transform" type="rotate" from="0 300 300" to="360 300 300" dur="80s" repeatCount="indefinite"/>
<a xlink:href="https://en.wikipedia.org/wiki/Neptune"/>
</circle>
</svg>

7
packages/osrl/debug.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
export declare const log: (msg: string, d?: any) => void;
export declare const info: (msg: string, d?: any) => void;
export declare const error: (msg: string, d?: any) => void;
export declare const warn: (msg: string, d?: any) => void;
export declare const debug: (msg: string, d?: any) => void;
export declare const inspect: (msg: string, d?: any, pretty?: boolean) => void;
export declare const spinner: (msg: string) => any;

27
packages/osrl/debug.js Normal file
View File

@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.spinner = exports.inspect = exports.debug = exports.warn = exports.error = exports.info = exports.log = void 0;
const chalk_1 = require("chalk");
const ora = require("ora");
// tslint:disable-next-line:no-var-requires
const jsome = require('jsome');
jsome.level.show = true;
const glog = console.log;
const log = (msg, d) => glog(chalk_1.default.magenta(msg), d || '');
exports.log = log;
const info = (msg, d) => glog(chalk_1.default.green(msg), d || '');
exports.info = info;
const error = (msg, d) => glog(chalk_1.default.red(msg), d || '');
exports.error = error;
const warn = (msg, d) => glog(chalk_1.default.yellow(msg), d || '');
exports.warn = warn;
const debug = (msg, d) => glog(chalk_1.default.blue(msg), d || '');
exports.debug = debug;
const inspect = (msg, d = null, pretty = true) => {
glog(chalk_1.default.blue(msg));
d && jsome(d);
};
exports.inspect = inspect;
const spinner = (msg) => ora(msg);
exports.spinner = spinner;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVidWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzcmMvZGVidWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsaUNBQXlDO0FBQ3pDLDJCQUEyQjtBQUMzQiwyQ0FBMkM7QUFDM0MsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQy9CLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN4QixNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDO0FBQ2xCLE1BQU0sR0FBRyxHQUFHLENBQUMsR0FBVyxFQUFFLENBQU8sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQWxFLFFBQUEsR0FBRyxPQUErRDtBQUN4RSxNQUFNLElBQUksR0FBRyxDQUFDLEdBQVcsRUFBRSxDQUFPLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUFqRSxRQUFBLElBQUksUUFBNkQ7QUFDdkUsTUFBTSxLQUFLLEdBQUcsQ0FBQyxHQUFXLEVBQUUsQ0FBTyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7QUFBaEUsUUFBQSxLQUFLLFNBQTJEO0FBQ3RFLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBVyxFQUFFLENBQU8sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQWxFLFFBQUEsSUFBSSxRQUE4RDtBQUN4RSxNQUFNLEtBQUssR0FBRyxDQUFDLEdBQVcsRUFBRSxDQUFPLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUFqRSxRQUFBLEtBQUssU0FBNEQ7QUFDdkUsTUFBTSxPQUFPLEdBQUcsQ0FBQyxHQUFXLEVBQUUsSUFBUyxJQUFJLEVBQUUsU0FBa0IsSUFBSSxFQUFFLEVBQUU7SUFDMUUsSUFBSSxDQUFDLGVBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN0QixDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLENBQUMsQ0FBQztBQUhXLFFBQUEsT0FBTyxXQUdsQjtBQUNLLE1BQU0sT0FBTyxHQUFHLENBQUMsR0FBVyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7QUFBcEMsUUFBQSxPQUFPLFdBQTZCIn0=

View File

@ -0,0 +1,26 @@
{
"folders": [
{
"path": "."
},
{
"path": "../osr-tasks"
},
{
"path": "../osr-i18n"
},
{
"path": "../osr-cli-commons"
},
{
"path": "../osr-log"
},
{
"path": "../osr-commons"
},
{
"path": "../osr-sync"
}
],
"settings": {}
}

375
packages/osrl/dist/main/main.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,28 @@
# Integration
## Integration: [Alt-Tap Salamand](https://www.altap.cz/) - Custom Menus
To use OSRL in custom menus, as follows
![](./assets/integration-as-custom-menu.PNG)
1. install osrl via ```npm i -g @plastichub/osrl```
2. Register a new custom menu (press F9 on any file)
![](./assets/integration-as-custom-menu-register.PNG)
**command** : ```osrl```
**Arguments** : ```compile --alt=true --debug --source="$(FullName)" --output="&{SRC_DIR}/&{SRC_NAME}.+(osrl)"```
Here explained,
```sh
compile # compile command
--alt=true # use alternate tokenizer, '&' instead of '$' to prevent collisions with Alt-Tab's own variable designator
--debug=true # be verbose
--source="$(FullName)" # use Alt-Tab's variable for the current selected file
--output="&{SRC_DIR}/&{SRC_NAME}.md" # the output destination path
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@ -0,0 +1,159 @@
### Default modules
```ts
import * as StringUtils from '../lib/StringUtils';
import * as HexUtils from '../lib/HexUtils';
import * as Arrays from '../lib/arrays';
import * as Primitives from '../lib/primitives';
import { markdownTable, md2html } from '../lib/markdown';
import { images, forward_slash, sizeToString } from '../lib/fs'
const fg = require('fast-glob');
const YAML = require('json-to-pretty-yaml');
const convert = require('convert-units');
const TOML = require('@iarna/toml');
const TOMLParser = require('@iarna/toml/lib/toml-parser.js');
const findUp = require('find-up');
const xlsx = require('node-xlsx');
import { sync as iterator } from '@plastichub/fs/iterator';
import { sync as exists } from '@plastichub/fs/exists';
import * as env from 'env-var';
import * as os from 'os';
import * as fs from 'fs';
import * as crypto from 'crypto';
import * as cheerio from 'cheerio';
import { IgApiClient } from 'instagram-private-api';
const prettyHtml = require('json-pretty-html').default;
const hljs = require('highlight.js');
import * as Discourse from '../plugins/discourser';
import { Promise as BPromise } from 'bluebird';
import * as download from 'download';
import * as elasticsearch from '@elastic/elasticsearch';
import * as cacache from 'cacache';
import { IObjectLiteral } from '../types';
import { IBaseOptions, IProcessingNode } from '@plastichub/fs/interfaces';
import { ArrayIterator } from '@plastichub/core/iterator';
import { git_log, git_status, changelog } from '../lib/git/log';
const prettyJSON = require('json-format-highlight');
export interface Context extends IObjectLiteral {
markdownTable: (data: any, options?: any) => string;
images: (src: string) => string[];
cacache: any;
cheerio: any;
elasticsearch: any;
git: any;
TOML: any,
fs: {
findUp: any,
iterator: (from: string, options: IBaseOptions) => ArrayIterator<IProcessingNode>
glob: (path: string, options: any) => string[],
slash: (s: string) => string,
EIteratorFlags: {
MODE: 2,
TIMES: 4,
SYMLINKS: 8,
FILE_SIZE: 16,
DIRECTORY_SIZE: 32,
CHECKSUM: 64,
MIME: 128
},
sizeToString: (size: number) => string;
dir: (dir, glob) => string[];
path: any,
exists: (path: string) => boolean | string,
images: (path: string) => string[]
}
}
```
### Default context - expanded
```ts
convert: convert,
...StringUtils,
...HexUtils,
...Arrays,
...Primitives,
markdownTable,
md2html,
images,
cacache,
cheerio,
elasticsearch,
IgApiClient,
TOML: {
parse: TOML.parse,
stringify: TOML.stringify,
parser: TOMLParser
},
ig: {
feed: ig_feed
},
Discourse,
YAML,
resolveConfig,
prettyHtml,
prettyJSON,
download,
BPromise,
hljs,
git: {
log: git_log,
status: git_status,
print_log: changelog
},
xlsx: {
build: xlsx.build,
parse: xlsx.parse
},
path,
fs: {
findUp: findUp,
iterator: iterator,
glob: fg,
slash: forward_slash,
EIteratorFlags: {
MODE: 2,
TIMES: 4,
SYMLINKS: 8,
FILE_SIZE: 16,
DIRECTORY_SIZE: 32,
CHECKSUM: 64,
MIME: 128
},
sizeToString: sizeToString,
dir: (dir, glob) => fg.sync(glob, { dot: true, cwd: dir, absolute: true }) as [],
...fs,
path,
exists,
images
},
os: {
env: env,
...os
},
crypto: {
...crypto,
encrypt: (text, password, algorithm = 'aes-256-cbc') => {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, password, iv);
let crypted = cipher.update(text, 'utf8', 'hex');
crypted += cipher.final('hex');
return crypted;
},
decrypt: (text, password, algorithm = 'aes-128-ecb') => {
const iv = crypto.randomBytes(16);
const decipher = crypto.createCipheriv(algorithm, password, iv)
let dec = decipher.update(text, 'hex', 'utf8');
dec += decipher.final('utf8');
return dec;
}
}
```

View File

@ -0,0 +1,307 @@
# Native - types & mappings
- Number - Int
- Number - Float
- String
- Date -> (string)
- TimeStamp -> (uint)
- Duration -> (uint)
- Struct -> (uiid string to resolve type)
- Type -> string (type type information)
- Ref -> struct [string|string, struct<any>]
- Vector2D -> struct [Float,Float]
- Vector3D -> struct [Float,Float,Float]
- BBox -> struct [Vector3D,Vector3D]
- Quaternion -> struct [Float,Float,Float,Float]
- Flags -> map<string, ulong>
- Expression -> string | struct [string|RegEx, options:flags]
- Boolean
- Options -> struct [flags|struct<any>]
- Url -> string
- Url-Scheme -> struct [Url,options:struct<any>]
- Asset -> struct [Url-Scheme, options:struct<any>]
- Selector > Expression | struct [Expression,options:struct<any>]
- Symbol -> ulong
- Type -> struct[string,Symbol] (type type information)
- Value -> Symbol
- Values -> map<string,value>
- Attribute -> struct [Type, Value]
- Parameter -> struct [Type,Value]
- Operation -> Symbol
- ParameterOperation -> struct [Value,Value,Operation]
- Template -> string | struct [Type|Selector,options:struct<any>]
- Arguments -> struct <any> | [...any]
## Examples
```md
# My Item
## Details
<template name="item_detail" arguments="showReferences=false">
Some text ...
</template>
<values comment="external and static values">
<value name="bushing-sheet" value="13PuCx8zKUjXvofFYBGzoOYog7UHpvLzCgxMLF9INnr8"/>
<value name="bushing-summary" value="0"/>
<value name="TOTAL" value="3"/>
<value name="Avg" value="g-sheet://<%bushing-sheet%>/<%bushing-summary%>/D11"/>
</values>
<attributes>
<attribute name="roundtrip" value="<% TOTAL / 3 %>"/>
</attributes>
```
## Url schemes
### Google sheet value
**short code** : g-sheet
**brief** : Obtains value(s) in expressions (anywhere) from Google sheets.
**parameters** : We pass trough all Google API / Url parameters. See [more](https://webapps.stackexchange.com/questions/44473/link-to-a-cell-in-a-google-sheets-via-url).
**examples**
```md
Estimated cost : <% VariableName / g-sheet://id/gid/range %>
```
### PP Search
**short code** : search
**brief** :
Returns a collection of *PP Search* results
**parameters**
We pass trough all Url parameters but the more common format is :
search://source/query/options
search://source/query/except={author=anonymous}
**examples**
```md
Display forum search results inline with preview
<search name="filament" query="filament" sources="Forum|Academy|Wiki">
<option name="display" value="inline"/>
<option name="preview" value="true"/>
<options for="google">
<options for google api here>
</options>
<options for="amazon">
<options for amazon api here>
</options>
<options for="forum">
<options for forum here>
</options>
</search>
```
### VFS
**short code** : vfs
**brief**
Short code to display or reference files or folders on various
virtual file systems as Github, local or SSH
**parameters**
We pass trough all VFS parameters but the more common format is :
vfs://mount/file
vfs://mount/root folder/sub folder/filename.md?display=inline|reference
**examples**
```md
Display the content of another file
<vfs name="my-file-definition" path="readme.md" mount="workspace" options="display=inline">
<option name="display" value="inline">
<option name="processor" value="HTML">
<!-->Set option for version selection - only provided by certain VFSs as Github<-->
<option for="github">
<option name="branch" value="#development">
</option>
</vfs>
Display the list of files in a folder
```md
<vfs name="my-file-definition" path="some folder" mount="workspace" options="display=inline, layout=grid">
<option name="display" value="inline">
<option name="processor" value="HTML">
</vfs>
```
It's recommended to store the definitions instead in the template's store file
and then use the reference just. Override arguments is possible as well
```md
<vfs ref="CAD files" options="display=inline, layout=list"/>
```
## Filters
**short code** : filter
**brief** :
Short code to filter out content using the built-in expression engine or markup friendly expressions
```md
<filter operation="equal" value1="user.group" value2="administrator">
admin stuff here
</filter>
<filter expression="{% user.group == administrator %}">
admin stuff here
</filter>
```
For repeating filters and using them as Url arguments, it's advised to store them
in the template's store file.
```md
<filter name="kingpin" expression="{% user.group == administrator %}">
{%content%}
</filter>
<text filter="kingpin">
trust me, and only me !
</text>
```
## Parameter Operations
**short code** : operation
**brief**
In some cases content or values are not in the right format. This system provides per type a set of parameter operations which has 3 inputs : operation, value1 & value2 (optional).
```html
<filter expression="<% system.config.units === 'metric' %>" >
The thing is
<operation op="meter" value1="200"/>
<%system.config.units%> high ..
</filter>
```
## Replace
**short code** : replace
**private**
**brief**
Way to modify anything - should be used as last resort only.
```html
<replace name="named object" or classes="object, template" or selector="" attribute="attribute to change" path="inner path, ie: jsonpath" expression="">
the replacement
</replace>
```
## remote
**short code** : remote
**private**
**brief**
Returns remote content
```html
<remote name="name for later" site="url" parser="jsdom|cheerio|json" selector="some CSS or $ selector" query="inner query, ie: jsonpath">
<option name="some url parameter to add - easier here" value=""/>
</remote>
```
## Resource
**short code** : resource
**brief**
Pull in HTML and system related resources
```html
<resource name="name for later" enabled="{% system.config.debug %}" src="URL|PATH|VFS" type="CSS|SCRIPT-HEAD|SCRIPT-BODY|SCRIPT"/>
```
## Extension
**short code** : extension
**brief**
Extension points enable extending existing templates for 3th party additions
```html
<extension for="welding-skill" place="after|before|**first**|last">
my extra content
</extension>
```
In a template
```html
<list name="welding-skill">
<!--extension will be placed here-->
<requirement>{%MIG_WELDING_LABEL%}</requirement>
</list>
```
<hr/>
Implicit & inherited base attributes:
- *view* : shorthand filter to make the node only visible for a certain compiler target
- *widget* : widget class
- *widgetOptions* : named widget options
- *filter* : named filter
- *id* : unique auto id "tag-name|counter"
- *vfs* : if set content will be loaded from this url
- *name* : if set, this unique name registers the object in the global class instance map. this attribute
is being also used for wiring extensions.
- *acl* : default's to any
- *remote* : if set, content will be loaded from this url
- as well all HTML attributes

View File

@ -0,0 +1,617 @@
## Unit conversion
Here's how you move between the metric units for volume:
```js
convert(1).from('l').to('ml');
// 1000
```
Jump from imperial to metric units the same way:
```js
convert(1).from('lb').to('kg');
// 0.4536... (tested to 4 significant figures)
```
Just be careful not to ask for an impossible conversion:
```js
convert(1).from('oz').to('fl-oz');
// throws -- you can't go from mass to volume!
```
You can ask `convert-units` to select the best unit for you. You can also optionally explicitly exclude orders of magnitude or specify a cut off number for selecting the best representation.
```js
convert(12000).from('mm').toBest();
// { val: 12, unit: 'm', plural: 'Meters' } (the smallest unit with a value above 1)
convert(12000).from('mm').toBest({ exclude: ['m'] });
// { val: 1200, unit: 'cm', plural: 'Centimeters' } (the smallest unit excluding meters)
convert(900).from('mm').toBest({ cutOffNumber: 10 });
// { val: 90, unit: 'cm', plural: 'Centimeters' } (the smallest unit with a value equal to or above 10)
convert(1000).from('mm').toBest({ cutOffNumber: 10 });
// { val: 100, unit: 'cm', plural: 'Centimeters' } (the smallest unit with a value equal to or above 10)
```
You can get a list of the measures available to the current instance with `.measures`
```js
convert().measures();
// [ 'length', 'mass', 'volume', ... ]
const differentConvert = configureMeasurements({
volume,
mass,
length,
area,
});
differentConvert().measures();
// [ 'length', 'mass', 'volume', 'area' ]
```
If you ever want to know the possible conversions for a unit, just use `.possibilities`
```js
convert().from('l').possibilities();
// [ 'ml', 'l', 'tsp', 'Tbs', 'fl-oz', 'cup', 'pnt', 'qt', 'gal' ]
convert().from('kg').possibilities();
// [ 'mcg', 'mg', 'g', 'kg', 'oz', 'lb' ]
```
You can also get the possible conversions for a measure:
```js
convert().possibilities('mass');
// [ 'mcg', 'mg', 'g', 'kg', 'oz', 'lb', 'mt', 't' ]
```
You can also get the all the available units:
```js
convert().possibilities();
// [ 'mm', 'cm', 'm', 'in', 'ft-us', 'ft', 'mi', 'mcg', 'mg', 'g', 'kg', 'oz', 'lb', 'mt', 't', 'ml', 'l', 'tsp', 'Tbs', 'fl-oz', 'cup', 'pnt', 'qt', 'gal', 'ea', 'dz' ];
```
To get a detailed description of a unit, use `describe`
```js
convert().describe('kg');
/*
{
abbr: 'kg',
measure: 'mass',
system: 'metric',
singular: 'Kilogram',
plural: 'Kilograms',
}
*/
```
To get detailed descriptions of all units, use `list`.
```js
convert().list();
/*
[{
abbr: 'kg',
measure: 'mass',
system: 'metric',
singular: 'Kilogram',
plural: 'Kilograms',
}, ...]
*/
```
You can also get detailed descriptions of all units for a measure:
```js
convert().list('mass');
/*
[{
abbr: 'kg',
measure: 'mass',
system: 'metric',
singular: 'Kilogram',
plural: 'Kilograms',
}, ...]
*/
```
Custom Measures
---------------
It's possible to define custom measures if the ones packaged aren't what you need:
```js
import configureMeasurements from 'convert-units';
const customMeasure = {
systems: {
A: {
a: {
name: {
singular: 'a',
plural: 'as',
},
// to_anchor: The factor used to reach the base unit
// The base unit should have a to_anchor value of 1
// Eg. 1 a -> al = 1a * 1e-1 (to_anchor of al) = 10 al
to_anchor: 1,
},
al: {
name: {
singular: 'al',
plural: 'als',
},
to_anchor: 1e-1,
},
},
B: {
b: {
name: {
singular: 'b',
plural: 'bs',
},
to_anchor: 1,
},
bl: {
name: {
singular: 'bl',
plural: 'bls',
},
to_anchor: 1e-1,
},
},
C: {
c: {
name: {
singular: 'c',
plural: 'cs',
},
to_anchor: 1,
},
cl: {
name: {
singular: 'cl',
plural: 'cls',
},
to_anchor: 1e-1,
},
},
},
anchors: {
A: {
// unit a -> unit b
B: {
ratio: 2,
},
// unit a -> unit c
C: {
ratio: 3,
},
},
B: {
// unit b -> unit a
A: {
ratio: 1 / 2,
},
// unit b -> unit c
C: {
ratio: 3 / 2,
},
},
C: {
// unit c -> unit a
A: {
ratio: 1 / 3,
},
// unit c -> unit b
B: {
ratio: 2 / 3,
},
},
},
};
const convert = configureMeasurements({ customMeasure });
convert(1).from('a').to('bl')
// 20
```
The order of opperations goes as follows:
```js
// a -> bl
let v = 1 // 1 a
let a_to_anchor = 1 // systems.A.a.to_anchor
let r = v * a_to_anchor
// r = 1 a
let ratio = 2 // anchors.A.B.ratio
r *= ratio
// r = 2 b
let bl_to_anchor = 1e-1 // systems.B.bl.to_anchor
r /= b_to_anchor
// r = 20 bl
```
It's also possible to extend existing measures:
```ts
import configureMeasurements, {
length,
LengthSystems,
LengthUnits,
Measure
} from 'convert-units';
type NewLengthUnits = LengthUnits | 'px';
const DPI = 96;
const extendedLength: Measure<LengthSystems, NewLengthUnits> = {
systems: {
metric: {
...length.systems.metric,
px: {
name: {
singular: 'Pixel',
plural: 'Pixels',
},
to_anchor: 0.0254 / DPI,
},
},
imperial: {
...length.systems.imperial,
},
},
anchors: {
...length.anchors,
},
};
const convert = configureMeasurements<'length', LengthSystems, NewLengthUnits>(
{ length: extendedLength }
);
convert(4).from('cm').to('px');
// 151.18110236220474
```
Migrating from Old API
---------------------
This only applies if moving from `<=2.3.4` to `>=3.x`.
`index.js`
```js
import convert from 'convert-units';
convert(1).from('m').to('mm');
convert(1).from('m').to('ft');
```
The code above could be changed to match the following:
`index.js`
```js
import convert from './convert'; // defined below
convert(1).from('m').to('mm');
convert(1).from('m').to('ft');
```
`convert.js`
```js
import configureMeasurements, { allMeasures } from 'convert-units';
export default configureMeasurements(allMeasures);
```
Typescript
----------
Defining types can provide the benefit of exposing issues while working on your application.
```ts
import configureMeasurements, {
AllMeasures,
allMeasures,
AllMeasuresSystems,
AllMeasuresUnits,
area,
AreaSystems,
AreaUnits,
length,
LengthSystems,
LengthUnits,
} from 'convert-units';
// Meausres: The names of the measures being used
type Measures = 'length' | 'area';
// Systems: The systems being used across all measures
type Systems = LengthSystems | AreaSystems;
// Units: All the units across all measures and their systems
type Units = LengthUnits | AreaUnits;
const convert = configureMeasurements<Measures, Systems, Units>({
length,
area,
});
convert(4).from('m').to('cm');
// 400
// If you'd like to use all the packages measures that can be done like so
const convertAll = configureMeasurements<
AllMeasures,
AllMeasuresSystems,
AllMeasuresUnits
>(allMeasures);
convertAll(4).from('m2').to('cm2');
// 400000
```
Request Measures & Units
-----------------------
All new measures and additional units are welcome! Take a look at [`src/definitions`](https://github.com/convert-units/convert-units/tree/main/src/definitions) to see some examples.
Packaged Units
--------------
### Length
* nm
* μm
* mm
* cm
* m
* km
* in
* yd
* ft-us
* ft
* fathom
* mi
* nMi
### Area
* mm2
* cm2
* m2
* ha
* km2
* in2
* ft2
* ac
* mi2
### Mass
* mcg
* mg
* g
* kg
* oz
* lb
* mt
* t
### Volume
* mm3
* cm3
* ml
* l
* kl
* m3
* km3
* tsp
* Tbs
* in3
* fl-oz
* cup
* pnt
* qt
* gal
* ft3
* yd3
### Volume Flow Rate
* mm3/s
* cm3/s
* ml/s
* cl/s
* dl/s
* l/s
* l/min
* l/h
* kl/s
* kl/min
* kl/h
* m3/s
* m3/min
* m3/h
* km3/s
* tsp/s
* Tbs/s
* in3/s
* in3/min
* in3/h
* fl-oz/s
* fl-oz/min
* fl-oz/h
* cup/s
* pnt/s
* pnt/min
* pnt/h
* qt/s
* gal/s
* gal/min
* gal/h
* ft3/s
* ft3/min
* ft3/h
* yd3/s
* yd3/min
* yd3/h'
### Temperature
* C
* F
* K
* R
### Time
* ns
* mu
* ms
* s
* min
* h
* d
* week
* month
* year
### Frequency
* Hz
* mHz
* kHz
* MHz
* GHz
* THz
* rpm
* deg/s
* rad/s
### Speed
* m/s
* km/h
* mph
* knot
* ft/s
### Pace
* s/m
* min/km
* s/ft
* min/mi
### Pressure
* Pa
* hPa
* kPa
* MPa
* bar
* torr
* psi
* ksi
### Digital
* b
* Kb
* Mb
* Gb
* Tb
* B
* KB
* MB
* GB
* TB
### Illuminance
* lx
* ft-cd
### Parts-Per
* ppm
* ppb
* ppt
* ppq
### Voltage
* V
* mV
* kV
### Current
* A
* mA
* kA
### Power
* W
* mW
* kW
* MW
* GW
* PS
* Btu/s
* ft-lb/s
* hp
### Apparent Power
* VA
* mVA
* kVA
* MVA
* GVA
### Reactive Power
* VAR
* mVAR
* kVAR
* MVAR
* GVAR
### Energy
* Wh
* mWh
* kWh
* MWh
* GWh
* J
* kJ
### Reactive Energy
* VARh
* mVARh
* kVARh
* MVARh
* GVARh
### Angle
* deg
* rad
* grad
* arcmin
* arcsec
### Charge
* c
* mC
* μC
* nC
* pC
### Force
* N
* kN
* lbf
### Acceleration
* g (g-force)
* m/s2
### Pieces
* pcs
* bk-doz
* cp
* doz-doz
* doz
* gr-gr
* gros
* half-dozen
* long-hundred
* ream
* scores
* sm-gr
* trio

6
packages/osrl/examples/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/node_modules
/coverage
*.log
.DS_Store
xcredentials.json
token.json

View File

@ -0,0 +1,69 @@
## Javascript Support
### Option 1: Run a Javascript file via filter
```liquid
JS Result : {{"./test.js" | jseval }}
```
Where ['./test.js']('./test.js') is:
```js
exports.default = function (engine) {
console.log('hello');
return 'cool!';
}
```
***Output***
```html
JS Result : cool!
```
**Remarks**
- Paths are resolved via Liquid standard options ```options.root``` where './test.js' is being appended to any of the roots listed in ```options.root```
### Option 2: Run a Javascript expression
```liquid
JS Expression Result : {{"2+2 + someNumber" | jsexp }}
```
***Output***
```html
JS Expression Result : 6
```
**Remarks**
- ```someNumber``` is being added to the expression in top as standard variable, using the Liquid parse option arguments, eg :
```ts
const template_ = read(`${machine_path}/templates/site/test-js.html`) as string;
let vars = {
name: '{{test}}',
test: '{{other}}',
other: 'alice',
show: false,
someNumber: 2
};
let options = {
root: [
`${machine_path}/`,
`${machine_path}/templates/site/`,
`${machine_path}/templates/shared/`
],
toHTML: false
}
let e = new Engine(options);
e.parse(template_, vars, 5).then(console.log);
return;
```

View File

@ -0,0 +1,5 @@
# Examples
- [Basics config and parsing](./basic.md)
- Running [Javascript files or expressions](./Javascript.md)
- Custom tags: Google sheets

View File

@ -0,0 +1,33 @@
node ./main.js compile \
--debug=true \
--source='${root}/osr/bazar/root.html' \
--root='../../ph3/products' \
--product=$1 \
--profile='${root}/.osrl.json' \
--output='${root}/${product}/bazar/output.html' \
--plugins='${root}/osr/plugins' \
--env='bazar' \
--format='html' \
--stdout=false \
node ./main.js compile \
--debug=true \
--source='${root}/osr/bazar/preview.osr' \
--root='../../ph3/products' \
--product=$1 \
--profile='${root}/.osrl.json' \
--output='${root}/${product}/bazar/output_preview.html' \
--env='bazar' \
--format='html' \
--stdout=false \
node ./main.js compile \
--debug=true \
--source='${root}/osr/bazar/post.osr' \
--root='../../ph3/products' \
--product=$1 \
--profile='${root}/.osrl.json' \
--output='${root}/${product}/bazar/output_final.html' \
--env='bazar' \
--format='html' \
--stdout=false \

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="433px" height="500px" viewBox="0 0 433 500" version="1.1"><g id='iconGroup'>
<defs>
<linearGradient id="linear0" gradientUnits="userSpaceOnUse" x1="110.5376" y1="55.4357" x2="89.9709" y2="67.8113" gradientTransform="matrix(2.484912,0,0,2.484706,0,0.287026)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear1" gradientUnits="userSpaceOnUse" x1="118.8238" y1="50.9557" x2="139.6052" y2="38.98" gradientTransform="matrix(2.484912,0,0,2.484706,0,0.287026)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear2" gradientUnits="userSpaceOnUse" x1="104.9271" y1="5.0433" x2="84.3605" y2="17.4189" gradientTransform="matrix(1.242456,-2.151756,2.151934,1.242353,7.36379,363.027049)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear3" gradientUnits="userSpaceOnUse" x1="113.2133" y1="0.5634" x2="133.9947" y2="-11.4123" gradientTransform="matrix(1.242456,-2.151756,2.151934,1.242353,7.36379,363.027049)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear4" gradientUnits="userSpaceOnUse" x1="145.7629" y1="-25.0117" x2="125.1963" y2="-12.6361" gradientTransform="matrix(-1.242456,-2.151756,2.151934,-1.242353,325.213657,538.020435)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear5" gradientUnits="userSpaceOnUse" x1="154.0491" y1="-29.4916" x2="174.8305" y2="-41.4673" gradientTransform="matrix(-1.242456,-2.151756,2.151934,-1.242353,325.213657,538.020435)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear6" gradientUnits="userSpaceOnUse" x1="192.2092" y1="-4.6743" x2="171.6426" y2="7.7013" gradientTransform="matrix(-2.484912,0,0,-2.484706,635.699983,350.273797)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear7" gradientUnits="userSpaceOnUse" x1="200.4954" y1="-9.1543" x2="221.2768" y2="-21.13" gradientTransform="matrix(-2.484912,0,0,-2.484706,635.699983,350.273797)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear8" gradientUnits="userSpaceOnUse" x1="197.8197" y1="45.718" x2="177.2531" y2="58.0936" gradientTransform="matrix(-1.242456,2.151756,-2.151934,-1.242353,628.336194,-12.466225)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear9" gradientUnits="userSpaceOnUse" x1="206.1059" y1="41.2381" x2="226.8873" y2="29.2624" gradientTransform="matrix(-1.242456,2.151756,-2.151934,-1.242353,628.336194,-12.466225)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear10" gradientUnits="userSpaceOnUse" x1="156.9839" y1="75.773" x2="136.4172" y2="88.1486" gradientTransform="matrix(1.242456,2.151756,-2.151934,1.242353,310.486327,-187.459611)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
<linearGradient id="linear11" gradientUnits="userSpaceOnUse" x1="165.2701" y1="71.2931" x2="186.0515" y2="59.3174" gradientTransform="matrix(1.242456,2.151756,-2.151934,1.242353,310.486327,-187.459611)">
<stop offset="0" style="stop-color:rgb(33.333333%,54.509804%,18.431373%);stop-opacity:1;"/>
<stop offset="1" style="stop-color:rgb(59.607843%,78.039216%,22.745098%);stop-opacity:1;"/>
</linearGradient>
</defs>
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(59.607843%,78.039216%,22.745098%);fill-opacity:1;" d="M 164.253906 374.730469 L 82.25 422.191406 L 0 374.730469 L 0 279.816406 L 82.003906 232.359375 L 164.003906 279.816406 Z M 82.25 387.40625 L 134.183594 357.339844 L 134.183594 297.210938 L 82.25 267.144531 L 30.316406 297.210938 L 30.316406 357.339844 Z M 82.25 387.40625 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(59.607843%,78.039216%,22.745098%);fill-opacity:1;" d="M 432.625 219.933594 L 350.621094 267.394531 L 268.617188 219.933594 L 268.617188 125.019531 L 350.621094 77.5625 L 432.625 125.019531 Z M 350.621094 232.605469 L 402.554688 202.542969 L 402.554688 142.414062 L 350.621094 112.347656 L 298.6875 142.414062 L 298.6875 202.542969 Z M 350.621094 232.605469 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(59.607843%,78.039216%,22.745098%);fill-opacity:1;" d="M 164.253906 219.933594 L 82.25 267.394531 L 0 219.933594 L 0 125.019531 L 82.003906 77.5625 L 164.003906 125.019531 Z M 82.25 232.605469 L 134.183594 202.542969 L 134.183594 142.414062 L 82.25 112.347656 L 30.066406 142.414062 L 30.066406 202.542969 Z M 82.25 232.605469 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(59.607843%,78.039216%,22.745098%);fill-opacity:1;" d="M 298.4375 452.257812 L 216.1875 499.710938 L 134.183594 452.257812 L 134.183594 357.339844 L 216.1875 309.878906 L 298.191406 357.339844 Z M 216.1875 464.925781 L 268.121094 434.863281 L 268.121094 374.730469 L 216.1875 344.667969 L 164.253906 374.730469 L 164.253906 434.863281 Z M 216.1875 464.925781 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(59.607843%,78.039216%,22.745098%);fill-opacity:1;" d="M 298.4375 142.414062 L 216.1875 189.871094 L 134.183594 142.414062 L 134.183594 47.496094 L 216.1875 0.289062 L 298.191406 47.742188 Z M 216.1875 155.082031 L 268.371094 125.019531 L 268.371094 64.890625 L 216.1875 35.074219 L 164.253906 65.136719 L 164.253906 125.269531 Z M 216.1875 155.082031 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(59.607843%,78.039216%,22.745098%);fill-opacity:1;" d="M 432.625 374.730469 L 350.621094 422.191406 L 268.617188 374.730469 L 268.617188 279.816406 L 350.621094 232.359375 L 432.625 279.816406 Z M 350.375 387.40625 L 402.308594 357.339844 L 402.308594 297.210938 L 350.375 267.394531 L 298.4375 297.457031 L 298.4375 357.585938 Z M 350.375 387.40625 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear0);" d="M 268.371094 125.019531 L 268.371094 159.804688 L 216.1875 189.871094 L 216.1875 155.082031 Z M 268.371094 125.019531 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear1);" d="M 298.4375 107.875 L 350.621094 77.5625 L 350.621094 112.347656 L 298.4375 142.414062 Z M 298.4375 107.875 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear2);" d="M 134.183594 142.660156 L 164.253906 159.804688 L 164.253906 219.933594 L 134.183594 202.542969 Z M 134.183594 142.660156 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear3);" d="M 134.183594 107.875 L 134.183594 47.496094 L 164.253906 64.890625 L 164.253906 125.269531 Z M 134.183594 107.875 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear4);" d="M 82.25 267.394531 L 112.070312 250 L 164.5 280.066406 L 134.433594 297.457031 Z M 82.25 267.394531 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear5);" d="M 52.183594 250 L 0 219.933594 L 30.066406 202.542969 L 82.25 232.605469 Z M 52.183594 250 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear6);" d="M 164.5 374.730469 L 164.253906 340.195312 L 216.4375 310.128906 L 216.4375 344.667969 Z M 164.5 374.730469 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear7);" d="M 134.433594 392.125 L 82.25 422.191406 L 82.25 387.652344 L 134.433594 357.339844 Z M 134.433594 392.125 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear8);" d="M 298.4375 357.339844 L 268.371094 340.195312 L 268.371094 279.816406 L 298.4375 297.210938 Z M 298.4375 357.339844 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear9);" d="M 298.4375 392.125 L 298.4375 452.257812 L 268.371094 435.109375 L 268.371094 374.730469 Z M 298.4375 392.125 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear10);" d="M 350.375 232.605469 L 320.554688 250 L 268.371094 219.933594 L 298.4375 202.542969 Z M 350.375 232.605469 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:url(#linear11);" d="M 380.441406 250 L 432.871094 280.066406 L 402.554688 297.457031 L 350.375 267.144531 Z M 380.441406 250 "/>
</g>
</g></svg>

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -0,0 +1,184 @@
## Basic usage
In this example, it's parsing test.html and all included partials :
- it's resolving variables recursively
- resolves parts.csv to a Markdown table
- resolves markdown.md.liquid' to HTML
```js
const parse = require('../index').parseText;
const path = require('path')
const read = require('@plastichub/fs/read').sync;
const template_ = read(`test.html`);
let vars = {
name: '{{test}}', // resolved in test
test: '{{other}}', // resolved in other
other: 'alice',
show: true,
items: ['first', 'second'],
objects: [{ att: 'first att' }, { att: 'second att' }],
recurse_test: true,
globals: {
test: 1
}
};
parse(template_, vars, 5, {
root: [
path.resolve('./')
],
toHTML:false
}).then(console.log);
```
**Output**
```md
### Test Array:
Item[items] = first
Item[items] = second
### Test Array with Objects
item[att] = first att
item[att] = second att
--- footer.html content ---
### Markdown test
<p>--- markdown.md.liquid to HTML test ---</p>
<h3 id="someheading">Some heading</h3>
### CSV Test
| Part Nr. | Description | Configuration |
|----------|------------------|---------------------------------------------------|
| | | |
| 1 | Heatbands | 250W ΓÇô 220V \| 110V \| OD:35mm \| Height : 6cm |
| 2 | PID Controller | InkBird 100-VH alice |
| 3 | Power Switch | IP55 Grade |
| 4 | Solid Round Bar | 25mm diameter / 50 cm long |
| 5 | Rack | Module-3 \| 3cm x 3 cm x 50 cm |
| 6 | Plunger | 25mm diameter / 38 cm long |
| 7 | Gear Brackets | 14 cm x 2 cm x 7 cm \| Aluminium \| 25 mm Bushing |
| 8 | Car ΓÇô Jack | 20 x 15 cm Mould Plate |
| 9 | Barrel | 35cm \| ID: 25 mm \| OD: 35 mm |
| 10 | Nozzle Interface | M20 / 12 mm bore |
| 11 | Nozzle | M20 / 12 mm bore with inset cone |
| | | |
```
With toHTML:true
```html
<h3 id="testarray">Test Array:</h3>
<pre><code>Item[items] = first
Item[items] = second
</code></pre>
<h3 id="testarraywithobjects">Test Array with Objects</h3>
<pre><code>item[att] = first att
item[att] = second att
</code></pre>
<p>--- footer.html content ---</p>
<h3 id="markdowntest">Markdown test</h3>
<p>--- markdown.md.liquid to HTML test ---</p>
<h3 id="someheading">Some heading</h3>
<h3 id="csvtest">CSV Test</h3>
<table>
<thead>
<tr>
<th>Part Nr.</th>
<th>Description</th>
<th>Configuration</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>1</td>
<td>Heatbands</td>
<td>250W ΓÇô 220V | 110V | OD:35mm | Height : 6cm</td>
</tr>
<tr>
<td>2</td>
<td>PID Controller</td>
<td>InkBird 100-VH alice</td>
</tr>
<tr>
<td>3</td>
<td>Power Switch</td>
<td>IP55 Grade</td>
</tr>
<tr>
<td>4</td>
<td>Solid Round Bar</td>
<td>25mm diameter / 50 cm long</td>
</tr>
<tr>
<td>5</td>
<td>Rack</td>
<td>Module-3 | 3cm x 3 cm x 50 cm</td>
</tr>
<tr>
<td>6</td>
<td>Plunger</td>
<td>25mm diameter / 38 cm long</td>
</tr>
<tr>
<td>7</td>
<td>Gear Brackets</td>
<td>14 cm x 2 cm x 7 cm | Aluminium | 25 mm Bushing</td>
</tr>
<tr>
<td>8</td>
<td>Car ΓÇô Jack</td>
<td>20 x 15 cm Mould Plate</td>
</tr>
<tr>
<td>9</td>
<td>Barrel</td>
<td>35cm | ID: 25 mm | OD: 35 mm</td>
</tr>
<tr>
<td>10</td>
<td>Nozzle Interface</td>
<td>M20 / 12 mm bore</td>
</tr>
<tr>
<td>11</td>
<td>Nozzle</td>
<td>M20 / 12 mm bore with inset cone</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
```

View File

@ -0,0 +1,23 @@
const path = require('path')
const read = require('@plastichub/fs/read').sync;
// const template = read(path.resolve(`./google-sheet-source.md`));
const template = read(path.resolve(`./test-js.html`));
const engine = require('../Engine').Engine;
const Engine = new engine({
root: [process.cwd()],
toHTML: false,
keepOutputType: true,
trimTagRight: false,
trimTagLeft: false,
trimOutputRight: false,
trimOutputLeft: false,
// language: 'liquid',
language:'osr'
});
Engine.parse(template, {
someVariable: 'test',
ROOT: process.cwd(),
someNumber:2
}, 0).then(console.log);

View File

@ -0,0 +1,28 @@
const Liquid = require('liquidjs');
const engine = new Liquid.Liquid();
const path = require('path')
const read = require('@plastichub/fs/read').sync;
const template = path.resolve(`./test-js.html`);
const template_ = read(template);
console.log('template',template_);
debugger;
const scope = {
test: '{{other}}',
other: 'other'
};
let parse = engine.parse(template_);
const rendered = engine.render(parse, scope, {}, true).then(console.log);
// console.log('t',tags);
try {
} catch (e) {
console.error(e);
}

View File

@ -0,0 +1 @@
--- footer.html content ---

View File

@ -0,0 +1,55 @@
Template Start
{% assign my_variable = false %}
{% assign my_number = 2 %}
{% assign google_sheet_id = '1oVEiGH4o3SV-mAA3Mb-WNVJMyYl4VMxLjWjrSw_ipJY' %}
{% assign google_range_multi = 'Parts!B13:B14' %}
{% assign google_range_named = 'ElenaMargin' %}
{% capture my_capture %}I am being captured.{% endcapture %}
{% capture my_array %}{{ '[{"name":"test"}]' | jsexp }}{% endcapture %}
{% if test %}
{{test}}
{%endif%}
JS Expression Result : { "Some Invalid Expression" | jsexp }
JS Expression Result 1Kg to lb : {{ "convert(1).from('kg').to('lb')" | jsexp }}
JS Expression Result : {{ "capitalize('uh')" | jsexp }}
JS Expression Result : {{ "tail([2, 3])" | jsexp }}
JS Expression Result : {{ "2+2 " | jsexp }}
JS Result : {{"./test.js" | jseval }}
## Custom tags
### Google - Sheet - Range with iterator
{% googlesheet 'MY_DATASOURCE', id: google_sheet_id, range: google_range_multi , path:'$', assign:'TEST_VAR' %}
{% for item in TEST_VAR %}
{{item}}
{% endfor %}
Convert to mardown tables:
[[ "markdownTable(TEST_VAR)" | jsexp ]]
Convert to mardown tables and then to html:
{{ "md2html(markdownTable(TEST_VAR))" | jsexp }}
### Google - Sheet - single value
Google Sheet Named Value: {% googlesheet 'MY_DATASOURCE', id: google_sheet_id, range: google_range_named %}
Template End
Scope : {{ 'console.dir(global.scope)' | jsexp }}

View File

@ -0,0 +1,54 @@
# Support for Google - Sheets
Reading values from Google sheets can be done as follows
```liquid
{% googlesheet 'MY_DATASOURCE', id: '1oVEiGH4o3SV-mAA3Mb-WNVJMyYl4VMxLjWjrSw_ipJY', range: 'Parts!B4:B5', path:'$', assign:'TEST_VAR' %}
{% for item in TEST_VAR %}
{{item}}
{% endfor %}
```
**Parameters**
- 'MY_DATASOURCE' : is just a name, currently used to cache the connection for later usage
- ```'id'``` : the Google Sheet ID (see browser address bar)
- ```'range'``` : the range in the sheet, eg: 'NamedField', or a particular range on a specific sheet : 'Parts!B4:B5'
- ```'path'``` : optional, a jsonpath query (check [jsonpath online editor](https://jsonpath.com/))
- ```'assign'``` : optional, assign the result to a new variable. in this case, the tag returns nothing !
**Example** [see source in './google-sheet-source.md'](./google-sheet-source.md)
**Output**
```markdown
Template Start
JS Expression Result : 4
JS Result : cool ! my_number = 2
JS Expression Result : { "Some Invalid Expression" | jsexp }
JS Expression Result 1Kg to lb : 2.2046244201837775
JS Expression Result : Uh
JS Expression Result : 3
## Custom tags
### Google - Sheet - Range with iterator
120x60 x 3
120x60
### Google - Sheet - single value
Google Sheet Named Value: 479
Template End
```

View File

@ -0,0 +1,25 @@
{% capture my_images %}
{{ 'images_rel("${ROOT}/assets/","${ROOT}")' | jsexp }}
{% endcapture %}
My Images : {{my_images}}
{% for item in my_images %}
item : {{item}}
{% endfor %}
Scope : {{ 'JSON.stringify(scope,null,2)' | jsexp }}
[% js %]
<script>
let images = images_rel("${ROOT}/assets/", "${ROOT}");
return images.map((i)=>`image : ${i}`).join('\n');
</script>
[%endjs%]
[% js %]
<script>
return YAML.stringify(scope);
</script>
[%endjs%]

View File

@ -0,0 +1,35 @@
{
"includes": [
"${root}/osr",
"${root}/osr/bazar"
],
"variables": {
"PRODUCT_ROOT": "${root}/${product}/",
"abs_url": "https://plastic-hub.com/",
"CACHE": "${root}/cache/",
"CACHE_URL": "${abs_url}/cache/",
"GIT_REPO": "https://git.osr-plastic.org/osr-plastic/pp-next"
},
"env": {
"bazar": {
"includes": [
"${root}/osr",
"${root}/osr/widgets",
"${root}/osr/bazar"
],
"variables": {
"abs_url": "https://dev.osr-plastic.org/"
}
},
"bazar-release": {
"includes": [
"${root}/osr",
"${root}/osr/widgets",
"${PRODUCT_ROOT}"
],
"variables": {
"abs_url": "https://plastic-hub.com/"
}
}
}
}

View File

@ -0,0 +1,199 @@
CERN Open Hardware Licence Version 2 - Permissive
Preamble
CERN has developed this licence to promote collaboration among
hardware designers and to provide a legal tool which supports the
freedom to use, study, modify, share and distribute hardware designs
and products based on those designs. Version 2 of the CERN Open
Hardware Licence comes in three variants: this licence, CERN-OHL-P
(permissive); and two reciprocal licences: CERN-OHL-W (weakly
reciprocal) and CERN-OHL-S (strongly reciprocal).
The CERN-OHL-P is copyright CERN 2020. Anyone is welcome to use it, in
unmodified form only.
Use of this Licence does not imply any endorsement by CERN of any
Licensor or their designs nor does it imply any involvement by CERN in
their development.
1 Definitions
1.1 'Licence' means this CERN-OHL-P.
1.2 'Source' means information such as design materials or digital
code which can be applied to Make or test a Product or to
prepare a Product for use, Conveyance or sale, regardless of its
medium or how it is expressed. It may include Notices.
1.3 'Covered Source' means Source that is explicitly made available
under this Licence.
1.4 'Product' means any device, component, work or physical object,
whether in finished or intermediate form, arising from the use,
application or processing of Covered Source.
1.5 'Make' means to create or configure something, whether by
manufacture, assembly, compiling, loading or applying Covered
Source or another Product or otherwise.
1.6 'Notice' means copyright, acknowledgement and trademark notices,
references to the location of any Notices, modification notices
(subsection 3.3(b)) and all notices that refer to this Licence
and to the disclaimer of warranties that are included in the
Covered Source.
1.7 'Licensee' or 'You' means any person exercising rights under
this Licence.
1.8 'Licensor' means a person who creates Source or modifies Covered
Source and subsequently Conveys the resulting Covered Source
under the terms and conditions of this Licence. A person may be
a Licensee and a Licensor at the same time.
1.9 'Convey' means to communicate to the public or distribute.
2 Applicability
2.1 This Licence governs the use, copying, modification, Conveying
of Covered Source and Products, and the Making of Products. By
exercising any right granted under this Licence, You irrevocably
accept these terms and conditions.
2.2 This Licence is granted by the Licensor directly to You, and
shall apply worldwide and without limitation in time.
2.3 You shall not attempt to restrict by contract or otherwise the
rights granted under this Licence to other Licensees.
2.4 This Licence is not intended to restrict fair use, fair dealing,
or any other similar right.
3 Copying, Modifying and Conveying Covered Source
3.1 You may copy and Convey verbatim copies of Covered Source, in
any medium, provided You retain all Notices.
3.2 You may modify Covered Source, other than Notices.
You may only delete Notices if they are no longer applicable to
the corresponding Covered Source as modified by You and You may
add additional Notices applicable to Your modifications.
3.3 You may Convey modified Covered Source (with the effect that You
shall also become a Licensor) provided that You:
a) retain Notices as required in subsection 3.2; and
b) add a Notice to the modified Covered Source stating that You
have modified it, with the date and brief description of how
You have modified it.
3.4 You may Convey Covered Source or modified Covered Source under
licence terms which differ from the terms of this Licence
provided that:
a) You comply at all times with subsection 3.3; and
b) You provide a copy of this Licence to anyone to whom You
Convey Covered Source or modified Covered Source.
4 Making and Conveying Products
You may Make Products, and/or Convey them, provided that You ensure
that the recipient of the Product has access to any Notices applicable
to the Product.
5 DISCLAIMER AND LIABILITY
5.1 DISCLAIMER OF WARRANTY -- The Covered Source and any Products
are provided 'as is' and any express or implied warranties,
including, but not limited to, implied warranties of
merchantability, of satisfactory quality, non-infringement of
third party rights, and fitness for a particular purpose or use
are disclaimed in respect of any Source or Product to the
maximum extent permitted by law. The Licensor makes no
representation that any Source or Product does not or will not
infringe any patent, copyright, trade secret or other
proprietary right. The entire risk as to the use, quality, and
performance of any Source or Product shall be with You and not
the Licensor. This disclaimer of warranty is an essential part
of this Licence and a condition for the grant of any rights
granted under this Licence.
5.2 EXCLUSION AND LIMITATION OF LIABILITY -- The Licensor shall, to
the maximum extent permitted by law, have no liability for
direct, indirect, special, incidental, consequential, exemplary,
punitive or other damages of any character including, without
limitation, procurement of substitute goods or services, loss of
use, data or profits, or business interruption, however caused
and on any theory of contract, warranty, tort (including
negligence), product liability or otherwise, arising in any way
in relation to the Covered Source, modified Covered Source
and/or the Making or Conveyance of a Product, even if advised of
the possibility of such damages, and You shall hold the
Licensor(s) free and harmless from any liability, costs,
damages, fees and expenses, including claims by third parties,
in relation to such use.
6 Patents
6.1 Subject to the terms and conditions of this Licence, each
Licensor hereby grants to You a perpetual, worldwide,
non-exclusive, no-charge, royalty-free, irrevocable (except as
stated in this section 6, or where terminated by the Licensor
for cause) patent license to Make, have Made, use, offer to
sell, sell, import, and otherwise transfer the Covered Source
and Products, where such licence applies only to those patent
claims licensable by such Licensor that are necessarily
infringed by exercising rights under the Covered Source as
Conveyed by that Licensor.
6.2 If You institute patent litigation against any entity (including
a cross-claim or counterclaim in a lawsuit) alleging that the
Covered Source or a Product constitutes direct or contributory
patent infringement, or You seek any declaration that a patent
licensed to You under this Licence is invalid or unenforceable
then any rights granted to You under this Licence shall
terminate as of the date such process is initiated.
7 General
7.1 If any provisions of this Licence are or subsequently become
invalid or unenforceable for any reason, the remaining
provisions shall remain effective.
7.2 You shall not use any of the name (including acronyms and
abbreviations), image, or logo by which the Licensor or CERN is
known, except where needed to comply with section 3, or where
the use is otherwise allowed by law. Any such permitted use
shall be factual and shall not be made so as to suggest any kind
of endorsement or implication of involvement by the Licensor or
its personnel.
7.3 CERN may publish updated versions and variants of this Licence
which it considers to be in the spirit of this version, but may
differ in detail to address new problems or concerns. New
versions will be published with a unique version number and a
variant identifier specifying the variant. If the Licensor has
specified that a given variant applies to the Covered Source
without specifying a version, You may treat that Covered Source
as being released under any version of the CERN-OHL with that
variant. If no variant is specified, the Covered Source shall be
treated as being released under CERN-OHL-S. The Licensor may
also specify that the Covered Source is subject to a specific
version of the CERN-OHL or any later version in which case You
may apply this or any later version of CERN-OHL with the same
variant identifier published by CERN.
7.4 This Licence shall not be enforceable except by a Licensor
acting as such, and third party beneficiary rights are
specifically excluded.

View File

@ -0,0 +1,10 @@
# vars
- Alle Teile werden mit modernen CNC- und Handmaschinen präzise gefertigt
- Sanftes und präzises Eintauchen
- Der Stößel hat eine austauschbare Bronzespitze
- 2 Formschnittstellen: Konus für Presse und M20-Gewindeschnittstelle
- Hitzeschild und Isolierung
#end

View File

@ -0,0 +1,89 @@
<hr />
<p>title: Tests - Basics
nav: kb
menu:
kb:
parent: tests
weight: 20
toc: true
nb: 3</p>
<h2 id="fcat54">fCat: 54</h2>
<h1 id="vars">vars</h1>
<ul>
<li>
<p>sCat : [sCat]</p>
</li>
<li>
<p>DST_DIR: ./examples/library/asterix/bazar</p>
</li>
<li>
<p>fCat : 54</p>
</li>
</ul>
<table>
<thead>
<tr>
<th></th>
<th>Standard</th>
<th>XMAX</th>
</tr>
</thead>
<tbody>
<tr>
<td>Weight</td>
<td>40 Kg</td>
<td>70 Kg</td>
</tr>
<tr>
<td>Package Dimensions</td>
<td>110 x 20 x 55 cm</td>
<td>60 x 20 x 140 cm</td>
</tr>
<tr>
<td>Plunger Diameter</td>
<td>25 mm</td>
<td>30 mm</td>
</tr>
<tr>
<td>Usable Barrel Length</td>
<td>35cm</td>
<td>52 cm</td>
</tr>
<tr>
<td>Supported Voltage</td>
<td>220V / 110V</td>
<td>220V / 110V</td>
</tr>
<tr>
<td>Input Flake Size</td>
<td>Small - Medium</td>
<td>Small - Medium</td>
</tr>
<tr>
<td>Plastic Shot Size</td>
<td>180 Gramm / 170ml</td>
<td>300 Gramm / 255ml</td>
</tr>
<tr>
<td>Transmission</td>
<td>1:1 * 50cm lever (3 solid sticks)</td>
<td>1:2 * 80cm lever (4 solid sticks)</td>
</tr>
<tr>
<td>Mold Interface</td>
<td>M20 thread / Cone Nozzle</td>
<td>M22 thread / Cone Nozzle</td>
</tr>
<tr>
<td>Heatbands</td>
<td>4 (250W) / Ceramic</td>
<td>6 (250W) / Brass</td>
</tr>
<tr>
<td>Temperature Controller</td>
<td>1 Inkbird</td>
<td>2 Inkbird</td>
</tr>
</tbody>
</table>
<p>product features . md</p>

View File

@ -0,0 +1,41 @@
{
"slug": "asterix-sm-morren",
"name": "Asterix - JW-Machines",
"category": "shredder",
"status": "rev-1",
"code": "ASM",
"version": "1.1",
"product_parts": "${abs_url}/${product_rel}/drawings/parts.jpg",
"product_dimensions": "${abs_url}/${product_rel}/drawings/dimensions.jpg",
"product_perspective": "${abs_url}/${product_rel}/renderings/perspective.jpg",
"download": "http://files.osr-plastic.org/files/machines/shredder/${slug}/",
"firmware": "http://files.osr-plastic.org/firmware/http://files.osr-plastic.org/files/firmware/asterix_max/",
"showParts":false,
"forumCategory":false,
"cscartId":2,
"authors": [
{
"name": "PlasticHub S.L.",
"url": "${author_link}"
},
{
"name": "Jason Knight",
"url": "https://www.mandin.earth/"
},
{
"name": "Jeffrey Wiecherink",
"url": "https://jw-machines.com"
}
],
"osr": {
"version": "0.3"
},
"production": {
"cam": [
{
"name": "Base-Plate",
"url": "https://a360.co/3F1eDdS"
}
]
}
}

View File

@ -0,0 +1,9 @@
product_id: asterix-jw
preview: ${product_preview}
_buy: "mailto:sales@plastic-hub.com?subject=Inquiry%20-%20${slug}"
teaser: "OSR - Mini - Shredder - ''"
products: false
overview_drawing: true
featuresText: true

Binary file not shown.

View File

@ -0,0 +1,23 @@
# Precious Plastic Shredder - version 3.5
Modified PreciousPlastic shredder for vending usage
### Shredder modifications:
- stronger housing
- 32mm hexbar
- 30mm shaft
- UCFL206 Bearings
### Features
- Auto-Plunger
- Auto-Reverse
- Safety door
- Optional : auto-Stop/Shred (uses optical sensor)
### CAD Todos
- [ ] Integrate M32 locknuts
- [ ] Add M32 thread(s) on axle

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

View File

@ -0,0 +1,9 @@
High Quality Dual Axis Shredder
## Features
- Jam detection / Auto-Reverse
- Rigid, flexible and modular framework enabling hacking and extensions
- Electronics and wiring according to standards
- Auto-Stop after being idle
- Visual feedback

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
<div class="ty-grid-list__item" style="float:left;border-color: #c5c5c5;width: 300px;display: inline-block;border-width: 1px;">
<a href="${link}">
<img height="200px" src="${image}" style="border-radius: 4px;">
<br />
<h5 style="text-align: center;">${name}</h5>
</a>
</div>

View File

@ -0,0 +1,20 @@
[% include "product_variables.osr" %]
[%js%]
const _pathIn = path.resolve(PRODUCT_ROOT + './bazar/output.html');
const product = readFile(_pathIn);
const $ = cheerio.load(product, {
xmlMode: true
});
$('a').each(function () {
$(this).attr("style", "color:#4C74B9");
})
$('table').each(function () {
$(this).attr("style", "display:table;width:auto;margin-left:auto;margin-right:auto");
})
return $.html()
[%endjs%]

View File

@ -0,0 +1,29 @@
[% include "product_variables.osr" %]
[%js%]
const _pathIn = path.resolve(PRODUCT_ROOT + './bazar/output.html');
const product = readFile(_pathIn);
const $ = cheerio.load(product, {
xmlMode: true
});
$('a').each(function () {
$(this).attr("style", "color:#4C74B9");
})
$('table').each(function () {
$(this).attr("style", "display:table;width:auto;margin-left:auto;margin-right:auto");
})
/*
$('img').each(function () {
$(this).css({
"border-radius" : "4px"
});
})
*/
let output = readFile('${root}/osr/bazar/product_begin.html');
output = substitute(output, {product:$.html()});
return output;
[%endjs%]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
- All parts are precision manufactured, using modern CNC and manual machines
- Smooth and precise plunging experience
- The plunger has a replaceable bronze tip
- 2 mold interfaces: cone for press, and M20 thread interface
- Heat-shield and insulation

View File

@ -0,0 +1,10 @@
[% capture my_images %]
[%- render "product_features.md" -%]
[% endcapture %]
# vars
[[ my_images | i18n]]
[%- i18n -%][%- i18n-end -%]
#end

View File

@ -0,0 +1,27 @@
---
title: Tests - Basics
nav: kb
menu:
kb:
parent: tests
weight: 20
toc: true
nb: 3
fCat: 54
---
# vars
[% capture sCat %][[fCat]][% endcapture %]
- sCat : [sCat]
- DST_DIR: [[DST_DIR]]
- fCat : [[fCat]]
[% render "xlsx.osr" file:"./specs.xlsx" html:true cat:[sCat] %]
[%- i18n %]
[%- include "product_features.md" -%]
[%- i18n-end %]

View File

@ -0,0 +1,55 @@
[% include "product_variables.osr" %]
[% include "body.md" %]
[% include "header_notice.osr" %]
[% include "${PRODUCT_ROOT}/header_notice.osr" %]
<div style="clear:both">
[% include "product_overview_drawings.osr" %]
</div>
<div style="padding:16px;text-align: center;">
<div class="ty-vendor-plans">
<div class="ty-grid-list__item" style="float: left;border: 1px gray;">
<h4 id="authors">Specification</h4>
[% include "product_specs.osr" html:true %]
</div>
<div class="ty-grid-list__item" style="float: left;text-align: left;border: 1px gray;">
[% if config.show.authors %]
[% include "authors_html.osr" authors:product.authors showHeader:true %]
[%endif%]
</div>
</div>
</div>
[% include "product_resources.osr" %]
<hr/>
[% include "product_showreel.osr" %]
[% if config.show.others %]
[% include "other_products.osr" %]
[%endif%]
[% if config.show.howtos %]
[% include "product_howtos.osr" %]
[%endif%]
[% include "social_links.osr" %]
[% include "vendor_instagram.osr" %]
[% if config.show.debug %]
[% include "product_debug.osr" %]
[%endif%]
[%js%]
[%endjs%]

Binary file not shown.

View File

@ -0,0 +1,21 @@
[% js %]
console.log('fCat', cat);
console.log('file', file);
const _path = lookup(file);
const h = html;
if (!fs.exists(_path)) {
console.error("file doesn't exists", file);
// try global item config (temp, for moulds)
if (global.private && global.private.specs) {
data = markdownTable(global.private.specs);
return md2html(data);
}
return '';
} else {
const t = global;
let data = xlsx.parse(_path);
data[0].data = data[0].data.filter((d) => !!d.length);
data = markdownTable(data[0].data);
return md2html(data);
}
[% endjs %]

View File

@ -0,0 +1,11 @@
[%js%]
const _path = substitute(`${cwd}/${product_rel}/${path}`);
console.log(_path);
if(fs.images(_path).length)
{
const t = html.thumbs(`${abs_url}/${product_rel}/${path}`,_path);
return `<h4 style="text-align:center">${name}</h4>${t}`;
}else{
console.log(_path + 'doesnt exists');
}
[%endjs%]

View File

@ -0,0 +1,11 @@
[%js%]
const _path = substitute(`${cwd}/${product_rel}/${path}`);
console.log(_path + ' _com');
if(fs.images(_path).length)
{
const t = html.thumbs(`${abs_url}/${product_rel}/${path}`,_path);
return `<h4 style="text-align:center">${name}</h4>${t}`;
}else{
console.log(_path + 'doesnt exists');
}
[%endjs%]

View File

@ -0,0 +1,100 @@
{
"products_path": "./products/products",
"fragments_path": "../../products/templates/jekyll/",
"vendor_name": "Plastic Hub",
"vendor_website": "https://plastic-hub.com/",
"vendor_products_external": "https://plastic-hub.com/products/",
"vendor_instagram": "https://www.instagram.com/plastichubcat",
"vendor_youtube": "https://www.youtube.com/channel/UCuWDxJtV2pf5BefHEy09Cew/featured?view_as=subscriber",
"vendor_github": "https://git.osr-plastic.org/osr-plastic",
"vendor_contact_email": "mailto:sales@plastic-hub.com",
"vendor_whatsapp": "tel:0034666894789",
"vendor_facebook": "https://www.facebook.com/plastichubcat/",
"vendor_blog": "https://precious-plastic.org/",
"vendor_discord": "https://discord.gg/vR5d6ShTez",
"author_link_pp": "https://preciousplastic.com/",
"author_link": "https://osr-plastic.org",
"site": "https://precious-plastic.org/",
"github_root": "https://precious-plastic.org/",
"OSR_HOWTOS_ROOT_URL": "https://osr-plastic.org/howtos/",
"OSR_HOWTOS_PATH": "../../ph3/pp-next2/howtos",
"mysql" : {
},
"show": {
"badges": false,
"authors": true,
"head": true,
"debug": false,
"wiki": false,
"forum": false,
"others": false,
"howtos":false
},
"discourse": {
"host": "https://forum.osr-plastic.org/",
"key": "a642d7405fb1318990b9e440cbc8d262a81d643c0530980ab470671296197d4f",
"username": "PlasticHub",
"rateLimitConcurrency": 1
},
"instagram": {
},
"all": [
{
"name": "Zoe",
"rel": "products/zoe",
"slug": "zoe",
"link": "https://shop.osr-plastic.org/shredder-en/shredder-fully-built/zoe-shredder-and-extrusion-combo/",
"image" : "https://plastic-hub.com/products/zoe/media/gallery/xmax.JPG"
},
{
"name": "Lydia-v3.5",
"rel": "products/extrusion/lydia-v3.5",
"slug": "lydia-v3.5",
"link": "https://bazar.preciousplastic.com/machines/extruder/extruder-fully-built/extrusion-v3.1-lydia/",
"image" : "https://plastic-hub.com/products/extrusion/lydia-v3.5/renderings/perspective.jpg"
},
{
"name": "Lydia-v4.5",
"rel": "products/extrusion/lydia-v4.5",
"slug": "lydia-v4.5",
"link": "https://bazar.preciousplastic.com/machines/extruder-pro/extruder-pro-fully-built/extrusion-v4.3-lydia/",
"image" : "https://plastic-hub.com/products/extrusion/lydia-v4.5/renderings/perspective_2k_teaser.png"
},
{
"name": "Elena",
"rel": "products/injection/elena",
"slug": "elena",
"link": "https://bazar.preciousplastic.com/machines/injection/injection-fully-built/arbor-injection-machine-elena-catalonia-the-original/",
"image" : "https://plastic-hub.com/products/injection/elena/renderings/teaser.jpg"
},
{
"name": "Obelix",
"rel": "products/shredder/obelix",
"slug": "obelix",
"link": "https://bazar.preciousplastic.com/machines/shredder-pro/shredder-pro-fully-built/upgraded-v4-shredder/",
"image" : "https://plastic-hub.com/products/shredder/obelix/media/gallery/latest.jpg"
},
{
"name": "Asterix",
"rel": "products/shredder/asterix",
"slug": "asterix",
"link": "https://bazar.preciousplastic.com/machines/shredder/shredder-fully-built/dual-axis-shredder-withh-auto-plunge-and-reverse/",
"image" : "https://plastic-hub.com/products/shredder/asterix/media/gallery/revA.JPG"
},
{
"name": "Idefix",
"rel": "products/shredder/idefix",
"slug": "idefix",
"link": "https://bazar.preciousplastic.com/machines/shredder/shredder-fully-built/shredder-v3.1-and-hopper/",
"image" : "https://plastic-hub.com/products/shredder/idefix/media/gallery/IMG_2994.JPG"
},
{
"name": "Cassandra",
"rel": "products/cassandra",
"slug": "cassandra",
"link": "https://bazar.preciousplastic.com/machines/sheetpress/sheet-press-fully-built/heat-conductive-putty-sheetpress/",
"image" : "https://plastic-hub.com/products/cassandra/media/gallery/perspective_closed.JPG"
}
]
}

View File

@ -0,0 +1,3 @@
<hr/>
Please always contact us through EMAIL : <b>sales@plastic-hub.com</b><br/>
<hr/>

View File

@ -0,0 +1,25 @@
<div style="padding:16px; text-align: center; ">
<h2> See our other products </h2>
<div class="ty-vendor-plans">
[%js%]
const template = readFile('${root}/osr/bazar/other_item.html');
let product = store.product;
let all = config.all.filter((p)=>{
return p.slug !== product.slug;
})
const ret = all.map((p)=>{
const vars = {
...p,
image: p.image || substitute('${abs_url}/' + p.rel + '/renderings/perspective.jpg',global)
}
return substitute(template,vars);
})
return ret;
[%endjs%]
</div>
<div style="clear: both;">
<p style="text-align:center ;">
<a href="https://plastic-hub.com/products/">See more products on our website</a>
</p>
</div>
</div>

View File

@ -0,0 +1,11 @@
{
"name": "osr",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

View File

@ -0,0 +1,3 @@
module.exports = {
};

View File

@ -0,0 +1,58 @@
const path = require('path');
const proc = require('process');
console.log('cwd ' + proc.cwd())
// const c = require('@plastichub/osrl/library')
const context = {}// require('@plastichub/osrl/library').getContext();
const link = (name, link, _class) => `<a class="${_class||''}" ref="${link}">${name}</a>`;
const wrap = (content) => `
<div style="padding:16px; text-align: center; ">
<div class="ty-vendor-plans">
${content}
</div>
</div>
`;
const image = (src, link, style) => `<a href="${link||src}"><img style="${style||''}" src="${src}"></img></a>`;
const item = (content, style = 'border-color: #c5c5c5;width: 300px;display: inline-block', title) =>
`<div class="ty-grid-list__item" style="float:left;overflow:initial;${style}">
${content}<br/>
<h6>${title||''}</h6>
</div>`;
const styles = {
thumb: 'border:none; width:200px;max-height:200px'
};
const center_caption = (el = 'h5', text) => `<${el} style="text-align:center">${text}</${el}>`;
const thumbs = (url, folder) => {
folder = path.resolve(folder);
images = [];
/*
let images = context.fs.images(folder, {
absolute: false
});
*/
images = images.map((i) => item(image(`${url}/${i}`), 'border:none; width:200px;max-height:200px'));
images = wrap(images.join('\n'));
return images;
}
module.exports = {
html: {
link: link,
caption: {
center: center_caption
},
container: {
wrap: wrap,
item: item
},
image: image,
styles: styles,
thumbs: thumbs
}
};

View File

@ -0,0 +1,59 @@
const url = require('url');
const path = require('path');
process.on('unhandledRejection', (reason) => {
console.error('Unhandled rejection, reason: ', reason);
debugger;
});
const images = (user, password, context) => {
return new Promise((resolve, reject) => {
context.ig.feed(user, password).then((f) => {
f = f.feed.filter((p)=>{
return p.media_type !==2;
});
let ret = f.map((p) => {
try {
const media = p.carousel_media ? p.carousel_media[0] : {
image_versions2: p.image_versions2
};
if (media) {
const version = media.image_versions2.candidates[1] ? media.image_versions2.candidates[1] : media.image_versions2.candidates[0];
return {
image: version.url,
url: p.code
}
}
} catch (e) {
debugger;
}
});
context.BPromise.resolve(ret).map((i) => {
const parts = url.parse(i.image);
const fileName = context.fs.path.basename(parts.pathname);
const cacheDir = context.fs.path.resolve(`${context.CACHE}`);
const cacheFile = context.fs.path.resolve(`${cacheDir}/${fileName}`);
if (context.fs.exists(cacheFile)) {
return cacheFile;
} else {
return context.download(i.image, cacheDir);
}
}, {
concurrency: 1
}).then(() => {
ret = ret.map((i) => {
const parts = url.parse(i.image);
const fileName = context.fs.path.basename(parts.pathname);
return {
path: `${context.CACHE_URL}/${fileName}`,
url : i.url
}
});
resolve(ret);
});
});
});
}
module.exports = {
instagram: {
images: images
}
};

View File

@ -0,0 +1,15 @@
const parts = (user, password, url, category, context) => {
return new Promise((resolve, reject) => {
context.Magento.Magento.init(url, user, password).then(() => {
const productsAPI = new context.Magento.API.CatalogProductRepositoryV1Api(context.Magento.Magento.apiConfig);
productsAPI.catalogProductRepositoryV1GetListGet('category_id', "" + category).then((products) => {
resolve(products.items);
})
});
});
}
module.exports = {
magento: {
parts: parts
}
};

View File

@ -0,0 +1,11 @@
{
"name": "plugins",
"version": "1.0.0",
"description": "",
"main": "cache.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

View File

@ -0,0 +1,9 @@
[% include "product_header_jekyll.osr" %]
[% if config.show.badges %]
{% include product_badges.html %}
[%endif%]
[% if config.show.authors %]
[% include "authors.osr" authors:product.authors showHeader:true %]
[%endif%]

View File

@ -0,0 +1,6 @@
## Product
[% js %]
if(debug){
return "<pre>" + prettyJSON(store.product) + "</pre>";
}
[%endjs%]

View File

@ -0,0 +1,25 @@
[%js%]
try{
return new Promise((resolve, reject) => {
const d = new Discourse.Discourser({
host: config.discourse.host,
key: config.discourse.key,
username: config.discourse.username,
rateLimitConcurrency: 1
});
d.getTopicItemsOfCategories([category]).then((posts) => {
if(!posts.length){
return '';
}
posts = posts.map((p)=>{
const url = `${config.discourse.host}/t/${p.id}`;
const title = `${p.fancy_title}`;
return `<a href="${url}">${title}</a><br/>`;
}).join('\n');
resolve(posts);
});
});
}catch(e){
debugger;
}
[%endjs%]

View File

@ -0,0 +1,97 @@
[% js foo=2 %]
[%endjs%]
[% capture config %][% js %]
const globalVariables = readJSON('${root}/osr/global.json');
addGlobal({config:globalVariables});
return globalVariables;
[%endjs%][% endcapture %]
[% capture product %][% js %]
let globalVariables = readJSON('${root}/osr/global.json');
let localVariables = readJSON('${PRODUCT_ROOT}/config.json');
let localYAML = readFile('${PRODUCT_ROOT}/config.yaml');
let defaultsYAML = fs.findUp.sync('defaults.yaml', {
cwd:PRODUCT_ROOT,
stopAt:root
});
if(defaultsYAML){
defaultsYAML = readFile(defaultsYAML).trim();
localYAML = `${defaultsYAML}\n${localYAML}`;
}
let defaultsJSON = fs.findUp.sync('defaults.json', {
cwd:PRODUCT_ROOT,
stopAt:root
});
if(defaultsJSON){
defaultsJSON = readJSON(defaultsJSON);
localVariables = {
...defaultsJSON,
...localVariables
}
}
let allVariables = {
...localVariables,
...globalVariables,
...scope
}
let all = substitute(JSON.stringify(allVariables,null,2),allVariables);
allVariables = JSON.parse(all);
resolveConfig(allVariables);
return allVariables;
[%endjs%][% endcapture %]
---
[% js %]
let globalVariables = readJSON('${root}/osr/global.json');
resolveConfig(globalVariables);
addGlobal(globalVariables);
let localVariables = readJSON('${PRODUCT_ROOT}/config.json');
let localYAML = readFile('${PRODUCT_ROOT}/config.yaml');
let defaultsYAML = fs.findUp.sync('defaults.yaml', {
cwd:PRODUCT_ROOT,
stopAt:root
});
if(defaultsYAML){
defaultsYAML = readFile(defaultsYAML).trim();
localYAML = `${defaultsYAML}\n${localYAML}`;
}
let defaultsJSON = fs.findUp.sync('defaults.json', {
cwd:PRODUCT_ROOT,
stopAt:root
});
if(defaultsJSON){
defaultsJSON = readJSON(defaultsJSON);
localVariables = {
...defaultsJSON,
...localVariables
}
}
localVariables['rel']=product.replace('products/','');
localVariables['image']='${abs_url}/${product_rel}/renderings/perspective.jpg';
let allVariables = {
...localVariables,
...globalVariables,
...scope
}
let all = substitute(JSON.stringify(allVariables, null, 2), allVariables);
allVariables = JSON.parse(all);
resolveConfig(allVariables);
store.product = allVariables;
addGlobal(allVariables);
register('product', allVariables);
const yaml = substitute(localYAML, allVariables);
return (YAML.stringify(allVariables) + yaml).trim();
[%endjs%]
---

View File

@ -0,0 +1,12 @@
[%js%]
if(store.product.howtos && store.product.howtos.length){
return store.product.howtos.map((i)=>{
return i
}).join('\n<br/>');
/*
const t = html.thumbs(`${abs_url}/${product}/media/products`,`${PRODUCT_ROOT}/media/products`);
return `<h5 style="text-align:center">Products done with ${store.product.name}</h5>
${t}`;
*/
}
[%endjs%]

View File

@ -0,0 +1,29 @@
<div>
[% if product.showDimensions !=false %]
<h4 style="text-align: center;">Dimensions</h4>
<a href="[[product.product_dimensions]]">
<p style="text-align: center">
<img style="max-height:500px" src="[[product.product_dimensions]]">
</p>
</a>
<hr/>
[% endif %]
[% if product.showParts !=false %]
<div style="padding:16px; text-align: center; ">
<div class="ty-vendor-plans">
<div class="ty-grid-list__item" style="float: left;border: 1px gray;">
<h4 style="text-align: center; ">Parts</h4>
<a href="[[product.product_parts]]">
<p style="text-align: center">
<img style="max-height:500px" src="[[product.product_parts]]">
</p>
</a>
</div>
<div class="ty-grid-list__item" style="float: left;text-align: left;border: 1px gray;margin:auto">
<p style="text-align: center">[% include 'product_parts.osr' %]</p>
</div>
</div>
</div>
</div>
[% endif %]

View File

@ -0,0 +1,7 @@
[%js%]
let p = PRODUCT_ROOT;
const _path = path.resolve(PRODUCT_ROOT + './parts.xlsx');
const data = xlsx.parse(_path);
data[0].data = data[0].data.filter((d) => !!d.length);
return md2html(markdownTable(data[0].data));
[%endjs%]

View File

@ -0,0 +1,50 @@
### Resources
[% if product.forum %]
- [Forum]([[product.forum]])
[% endif %]
[% if product.download %]
- [Download]([[product.download]])
[% endif %]
[% if product.firmware %]
- [Firmware]([[product.firmware]])
[% endif %]
[% if product.Preview3d %]
[% if product.edrawings %]
- [3D-Preview]([[product.edrawings]])
[% else %]
- [3D-Preview]([[product.abs_url]]/[[product.product_rel]]/resources/edrawings.html)
[% endif %]
- [Source Code Reposity]([[GIT_REPO]]/src/branch/master/machines/[[product.rel]])
[%endif%]
[% if product.hasSpec %]
- [Specification PDF]([[product.abs_url]]/[[product.product_rel]]/resources/spec.pdf)
[%endif%]
[% if product.howtoSection %]
- [How-tos]([[product.howtoSection]])
[%endif%]
[% if product.library %]
- [Library]([[product.library]])
[%endif%]
<hr/>
[% if config.show.wiki %]
[% if product.wiki_articles %]
<h4>Wiki Articles</h4>
[% include "product_wiki.osr" category:product.wiki_articles %]
[% else %]
[% endif %]
[% else %]
[% endif %]
[% if config.show.forum %]
[% if product.forumCategory %]
<h4>Forum Posts</h4>
[% include "product_forum.osr" category:product.forumCategory %]
[% endif %]
[% endif %]
[% include "extra_resources.md" %]

View File

@ -0,0 +1,7 @@
[%js%]
if(fs.images(`${PRODUCT_ROOT}/media/products`).length){
const t = html.thumbs(`${abs_url}/${product}/media/products`,`${PRODUCT_ROOT}/media/products`);
return `<h4 style="text-align:center">Products done with ${store.product.name}</h4>
${t}`;
}
[%endjs%]

View File

@ -0,0 +1,14 @@
[%js%]
let p = PRODUCT_ROOT;
const _path = path.resolve(PRODUCT_ROOT + './specs.xlsx');
let data = xlsx.parse(_path);
data[0].data = data[0].data.filter((d)=>d.length >0);
data = markdownTable(data[0].data);
if(html){
return md2html(data);
}else{
data;
}
[%endjs%]

View File

@ -0,0 +1,55 @@
[% capture config %][% js %]
const globalVariables = readJSON('${root}/osr/global.json');
addGlobal({config:globalVariables});
return globalVariables;
[%endjs%][% endcapture %]
[% capture product %][% js %]
let globalVariables = readJSON('${root}/osr/global.json');
let localVariables = readJSON('${PRODUCT_ROOT}/config.json');
localVariables['image']='${product_rel}/renderings/perspective.jpg';
localVariables['rel']=product.replace('products/','');
localVariables['sidebar'] = {
nav: "machines"
};
let localYAML = readFile('${PRODUCT_ROOT}/config.yaml');
let defaultsYAML = fs.findUp.sync('defaults.yaml', {
cwd:PRODUCT_ROOT,
stopAt:root
});
if(defaultsYAML){
defaultsYAML = readFile(defaultsYAML).trim();
localYAML = `${defaultsYAML}\n${localYAML}`;
}
let defaultsJSON = fs.findUp.sync('defaults.json', {
cwd:PRODUCT_ROOT,
stopAt:root
});
if(defaultsJSON){
defaultsJSON = readJSON(defaultsJSON);
localVariables = {
...defaultsJSON,
...localVariables
}
}
let allVariables = {
...localVariables,
...globalVariables,
...scope
}
allVariables.product_rel = product;
let all = substitute(JSON.stringify(allVariables,null,2),allVariables);
allVariables = JSON.parse(all);
resolveConfig(allVariables);
addGlobal({product:allVariables});
return allVariables;
[%endjs%][% endcapture %]

View File

@ -0,0 +1,24 @@
[%js%]
try{
return new Promise((resolve, reject) => {
const d = new Discourse.Discourser({
host: config.discourse.host,
key: config.discourse.key,
username: config.discourse.username,
rateLimitConcurrency: 1
});
d.getTopicItemsOfCategories([category]).then((posts) => {
let content = "<ul>"
posts = posts.map((p)=>{
const url = `${config.discourse.host}/t/${p.id}`;
const title = `${p.fancy_title}`;
return `<li><a href="${url}">${title}</a></li>`;
}).join('\n');
content += posts + "</ul>";
resolve(content);
});
});
}catch(e){
debugger;
}
[%endjs%]

Some files were not shown because too many files have changed in this diff Show More