Skip to content

Commit

Permalink
Merge branch 'lindsvg-1.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Amphiluke committed Jan 12, 2020
2 parents 7d98482 + d506dba commit 853d444
Show file tree
Hide file tree
Showing 16 changed files with 236 additions and 97 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist/
dist/
test/
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,25 @@ let {pathData, minX, minY, width, height} = getSVGData(lsParams);

An object returned by `getSVGData` contains [path data](https://www.w3.org/TR/SVG11/paths.html#PathData) needed to draw the L-system, and also the drawing boundaries that are essential for the `viewBox` attribute.

In case of invalid input L-system parameters, the methods throw a custom exception. You may use it to get a detailed explanation of which parameter(s) failed to pass validation, and format the message as you wish.

```javascript
let {getSVGCode} = require("lindsvg");
let yaml = require("js-yaml");

try {
console.log(getSVGCode(lsParams, svgParams));
} catch (error) {
// Log the original message
console.error(error);
if (error.name === "LSError") {
// Get a JSON representation of the error list and format it as YAML
let errorJSON = error.toJSON();
console.log(yaml.dump(errorJSON, {indent: 4}));
}
}
```

### Compatibility note

lindsvg utilizes the ECMAScript 2018 syntax. If you want to use the module in environments that do not support ES 2018, please transpile the sources with babel or whatever for your needs.
51 changes: 36 additions & 15 deletions dist/lindsvg.esm.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
lindsvg v1.0.0
lindsvg v1.1.0
https://amphiluke.github.io/l-systems/
(c) 2020 Amphiluke
*/
Expand All @@ -25,17 +25,17 @@ function checkRule(rule, msg = messages.RULE) {
}

function checkRules(rules, letterMsg, ruleMsg) {
let errors = new Map();
let errors = Object.create(null);
Object.entries(rules).forEach(([letter, rule]) => {
let result = checkLetter(letter, letterMsg);
if (result === true) {
result = checkRule(rule, ruleMsg);
}
if (result !== true) {
errors.set(letter, result);
errors[letter] = result;
}
});
return errors.size ? errors : true;
return Object.keys(errors).length ? errors : true;
}

function checkStep(step, msg = messages.STEP) {
Expand All @@ -51,7 +51,7 @@ function checkAngle(angle, msg = messages.NUMBER) {
}

function validate(lsParams) {
let errors = new Map();
let errors = Object.create(null);
Object.entries(lsParams).forEach(([param, value]) => {
let result = true;
switch (param) {
Expand All @@ -73,21 +73,42 @@ function validate(lsParams) {
break;
}
if (result !== true) {
errors.set(param, result);
errors[param] = result;
}
});
return errors.size ? errors : true;
return Object.keys(errors).length ? errors : true;
}

function formatErrors(errors) {
return [...errors].reduce((accumulator, [param, error]) => {
if (error instanceof Map) {
return `${accumulator}\n${param}:${formatErrors(error).replace(/\n/g, "\n ")}`;
}
return `${accumulator}\n${param}: ${error}`;
}, "");
class LSError extends Error {
/**
* LSError constructor
* @param {Object} errors - Error map “parameter->message(s)”
* @constructor
*/
constructor(errors) {
let message = JSON.stringify(errors, null, 2);
super(message);
// Using JSON.parse for deep cloning
Object.defineProperty(this, "lsErrors", {value: JSON.parse(message)});
}

/**
* Get raw object representation of the errors
* @return {Object}
*/
toJSON() {
return JSON.parse(JSON.stringify(this.lsErrors));
}
}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString
Object.defineProperty(LSError.prototype, "name", {
configurable: true,
enumerable: false,
writable: true,
value: "LSError"
});

/** @type {Rules} */
let ctrlRules = {
F: "",
Expand All @@ -114,7 +135,7 @@ let defaults = {
function generate(lsParams) {
let validity = validate(lsParams);
if (validity !== true) {
throw new Error(formatErrors(validity));
throw new LSError(validity);
}
let {axiom: code, iterations} = {...defaults, ...lsParams};
let rules = {...ctrlRules, ...lsParams.rules};
Expand Down
4 changes: 2 additions & 2 deletions dist/lindsvg.esm.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 36 additions & 15 deletions dist/lindsvg.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*!
lindsvg v1.0.0
lindsvg v1.1.0
https://amphiluke.github.io/l-systems/
(c) 2020 Amphiluke
*/
Expand Down Expand Up @@ -31,17 +31,17 @@ https://amphiluke.github.io/l-systems/
}

function checkRules(rules, letterMsg, ruleMsg) {
let errors = new Map();
let errors = Object.create(null);
Object.entries(rules).forEach(([letter, rule]) => {
let result = checkLetter(letter, letterMsg);
if (result === true) {
result = checkRule(rule, ruleMsg);
}
if (result !== true) {
errors.set(letter, result);
errors[letter] = result;
}
});
return errors.size ? errors : true;
return Object.keys(errors).length ? errors : true;
}

function checkStep(step, msg = messages.STEP) {
Expand All @@ -57,7 +57,7 @@ https://amphiluke.github.io/l-systems/
}

function validate(lsParams) {
let errors = new Map();
let errors = Object.create(null);
Object.entries(lsParams).forEach(([param, value]) => {
let result = true;
switch (param) {
Expand All @@ -79,21 +79,42 @@ https://amphiluke.github.io/l-systems/
break;
}
if (result !== true) {
errors.set(param, result);
errors[param] = result;
}
});
return errors.size ? errors : true;
return Object.keys(errors).length ? errors : true;
}

function formatErrors(errors) {
return [...errors].reduce((accumulator, [param, error]) => {
if (error instanceof Map) {
return `${accumulator}\n${param}:${formatErrors(error).replace(/\n/g, "\n ")}`;
}
return `${accumulator}\n${param}: ${error}`;
}, "");
class LSError extends Error {
/**
* LSError constructor
* @param {Object} errors - Error map “parameter->message(s)”
* @constructor
*/
constructor(errors) {
let message = JSON.stringify(errors, null, 2);
super(message);
// Using JSON.parse for deep cloning
Object.defineProperty(this, "lsErrors", {value: JSON.parse(message)});
}

/**
* Get raw object representation of the errors
* @return {Object}
*/
toJSON() {
return JSON.parse(JSON.stringify(this.lsErrors));
}
}

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString
Object.defineProperty(LSError.prototype, "name", {
configurable: true,
enumerable: false,
writable: true,
value: "LSError"
});

/** @type {Rules} */
let ctrlRules = {
F: "",
Expand All @@ -120,7 +141,7 @@ https://amphiluke.github.io/l-systems/
function generate(lsParams) {
let validity = validate(lsParams);
if (validity !== true) {
throw new Error(formatErrors(validity));
throw new LSError(validity);
}
let {axiom: code, iterations} = {...defaults, ...lsParams};
let rules = {...ctrlRules, ...lsParams.rules};
Expand Down
Loading

0 comments on commit 853d444

Please sign in to comment.