Comparing version 1.4.3 to 1.5.0
245
index.js
@@ -1,132 +0,135 @@ | ||
module.exports = (function(){ | ||
/* istanbul ignore else */ | ||
if (typeof define !== 'function') { | ||
var define = require('amdefine')(module); | ||
} | ||
define(["./main/static-resolver", "./main/index"], function(resolver, main) { | ||
"use strict"; | ||
var DEFAULT_PARSER = "./parse/mscgenparser_node"; | ||
var DEFAULT_TEXT_RENDERER = "./render/text/ast2mscgen"; | ||
var _ = require("./lib/lodash/lodash.custom"); | ||
var gLang2Parser = { | ||
mscgen: "./parse/mscgenparser_node", | ||
xu: "./parse/xuparser_node", | ||
msgenny: "./parse/msgennyparser_node" | ||
}; | ||
return { | ||
/** | ||
* parses the given script and renders it in the DOM element with | ||
* id pOptions.elementId. | ||
* | ||
* @param {string} pScript The script to parse and render. Assumed | ||
* to be MscGen - unless specified | ||
* differently in pOptions.inputType | ||
* @param {object} pOptions options influencing parsing and | ||
* rendering. See below for the complete | ||
* list. | ||
* @param {function} pCallBack function with error, success | ||
* parameters. renderMsc will pass the | ||
* resulting svg in the success parameter | ||
* when successful, the error message | ||
* in the error parameter when not. | ||
* @return none | ||
* | ||
* Options: | ||
* elementId: the id of the DOM element to render in. Defaults to | ||
* "__svg". renderMsc assumes this element to exist. | ||
* inputType: language to parse - default "mscgen"; other accepted | ||
* languages: "xu", "msgenny" and "json" | ||
* mirrorEntitiesOnBottom: draws entities on both top and bottom of | ||
* the chart when true. Defaults to false. | ||
* additionalTemplate: use one of the predefined templates. Default | ||
* null/ empty. Possible values: "lazy", "classic", | ||
* "cygne", "pegasse", "fountainpen" (experimental), | ||
* "inverted" (doesn't work in safari), "grayscaled" | ||
* (doesn't work in safari either) | ||
* includeSource: whether the generated svg should include the script | ||
* in a desc element or not. Defaults to false | ||
}, | ||
*/ | ||
renderMsc: function (pScript, pOptions, pCallBack){ | ||
main.renderMsc( | ||
pScript, pOptions, pCallBack, | ||
resolver.getParser, resolver.getGraphicsRenderer | ||
); | ||
}, | ||
var gLang2TextRenderer = { | ||
mscgen: "./render/text/ast2mscgen", | ||
msgenny: "./render/text/ast2msgenny", | ||
xu: "./render/text/ast2xu", | ||
dot: "./render/text/ast2dot", | ||
doxygen: "./render/text/ast2doxygen" | ||
}; | ||
var getParser = _.memoize( | ||
function getParser (pLanguage) { | ||
if (["ast", "json"].indexOf(pLanguage) > -1) { | ||
return JSON; | ||
} | ||
return require( | ||
gLang2Parser[pLanguage] || DEFAULT_PARSER | ||
/** | ||
* Translates the input script to an outputscript. | ||
* | ||
* @param {string} pScript The script to translate | ||
* @param {object} pOptions options influencing parsing & rendering. | ||
* See below for the complete list. | ||
* @param {function} pCallBack function with error, success | ||
* parameters. translateMsc will pass the | ||
* resulting script in the success | ||
* parameter when successful, the error | ||
* message in the error parameter when not. | ||
* @return none | ||
* | ||
* Options: | ||
* inputType : the language of pScript defaults to "mscgen". Possible | ||
* values: "mscgen", "msgenny", "xu", "json" | ||
* outputType : defaults to "json". Possible values: "mscgen", | ||
* "msgenny", "xu", "json", "dot", "doxygen" | ||
*/ | ||
translateMsc: function (pScript, pOptions, pCallBack){ | ||
main.translateMsc( | ||
pScript, pOptions, pCallBack, | ||
resolver.getParser, resolver.getTextRenderer | ||
); | ||
} | ||
); | ||
}, | ||
var getGraphicsRenderer = _.memoize( | ||
function getGraphicsRenderer(){ | ||
return require('./render/graphics/renderast'); | ||
} | ||
); | ||
/** | ||
* The current (semver compliant) version number string of | ||
* mscgenjs | ||
* | ||
* @type {string} | ||
*/ | ||
version: main.version, | ||
var getTextRenderer = _.memoize( | ||
function getTextRenderer(pLanguage){ | ||
return require( | ||
gLang2TextRenderer[pLanguage] || DEFAULT_TEXT_RENDERER | ||
); | ||
} | ||
); | ||
/** | ||
* returns a parser module for the given language. The module exposes | ||
* a parse(pString) function which returns an abstract syntax tree in | ||
* json format as described in the link below. | ||
* | ||
* https://github.com/sverweij/mscgenjs-core/blob/master/parse/README.md#the-abstract-syntax-tree | ||
* | ||
* @param {string} pLanguage the language to get a parser for | ||
* Possible values: "mscgen", "msgenny", "xu" | ||
* "json". Defaults to "mscgen" | ||
* @return {object} | ||
*/ | ||
getParser: resolver.getParser, | ||
function runCallBack(pCallBack, pError, pResult){ | ||
/* istanbul ignore else */ | ||
if (Boolean(pCallBack)){ | ||
if (Boolean(pError)) { | ||
pCallBack(pError, null); | ||
} else { | ||
pCallBack(null, pResult); | ||
} | ||
} | ||
} | ||
/** | ||
* returns a renderer that renders the abstract syntax tree as a scalable | ||
* vector graphics (in practice: @render/graphics/renderast) | ||
* | ||
* @deprecated use renderMsc instead to render graphics | ||
* | ||
* @return {object} | ||
*/ | ||
getGraphicsRenderer: resolver.getGraphicsRenderer, | ||
function isProbablyAnASTAlready(pScript, pInputType){ | ||
return pInputType === "json" && typeof pScript === "object"; | ||
} | ||
/** | ||
* returns a renderer to the given language. The module exposes a | ||
* render(pAST) function which returns a rendition of the abstract | ||
* syntax tree it got passed into the given language | ||
* | ||
* @deprecated use translateMsc instead to render text | ||
* | ||
* @return {object} | ||
*/ | ||
getTextRenderer: resolver.getTextRenderer | ||
}; | ||
}); | ||
/* | ||
This file is part of mscgen_js. | ||
function getAST(pScript, pInputType){ | ||
if (isProbablyAnASTAlready(pScript, pInputType)) { | ||
return pScript; | ||
} else { | ||
return getParser(pInputType).parse(pScript); | ||
} | ||
} | ||
mscgen_js is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU General Public License as published by | ||
the Free Software Foundation, either version 3 of the License, or | ||
(at your option) any later version. | ||
return { | ||
renderMsc : function renderMsc(pScript, pOptions, pCallBack){ | ||
var lOptions = pOptions || {}; | ||
_.defaults(lOptions, { | ||
inputType : "mscgen", | ||
elementId : "__svg", | ||
window : pOptions.window || window, | ||
includeSource : true, | ||
styleAdditions : null, | ||
additionalTemplate : null, | ||
mirrorEntitiesOnBottom : false | ||
}); | ||
mscgen_js is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU General Public License for more details. | ||
try { | ||
runCallBack( | ||
pCallBack, | ||
null, | ||
getGraphicsRenderer().renderASTNew( | ||
getAST(pScript, lOptions.inputType), | ||
lOptions.window, | ||
lOptions.elementId, | ||
{ | ||
source: lOptions.includeSource ? pScript : null, | ||
styleAdditions: lOptions.styleAdditions, | ||
additionalTemplate: lOptions.additionalTemplate, | ||
mirrorEntitiesOnBottom: lOptions.mirrorEntitiesOnBottom | ||
} | ||
) | ||
); | ||
} catch (pException){ | ||
runCallBack(pCallBack, pException); | ||
} | ||
}, | ||
translateMsc : function translateMsc(pScript, pOptions, pCallBack){ | ||
var lOptions = pOptions || {}; | ||
_.defaults(lOptions, { | ||
inputType: "mscgen", | ||
outputType: "json" | ||
}); | ||
try { | ||
runCallBack( | ||
pCallBack, | ||
null, | ||
(lOptions.outputType === "json") | ||
? JSON.stringify( | ||
getParser(lOptions.inputType).parse(pScript), | ||
null, | ||
" " | ||
) | ||
: getTextRenderer(lOptions.outputType).render( | ||
getAST(pScript, lOptions.inputType) | ||
) | ||
); | ||
} catch (pException) { | ||
runCallBack(pCallBack, pException); | ||
} | ||
}, | ||
getParser : getParser, | ||
getGraphicsRenderer : getGraphicsRenderer, | ||
getTextRenderer : getTextRenderer | ||
}; | ||
})(); | ||
You should have received a copy of the GNU General Public License | ||
along with mscgen_js. If not, see <http://www.gnu.org/licenses/>. | ||
*/ |
145
indexAMD.js
@@ -1,136 +0,17 @@ | ||
/* istanbul ignore else */ | ||
if (typeof define !== 'function') { | ||
var define = require('amdefine')(module); | ||
} | ||
/* eslint max-params: 0 */ | ||
define(["./lib/lodash/lodash.custom", | ||
"./parse/mscgenparser", | ||
"./parse/xuparser", | ||
"./parse/msgennyparser", | ||
"./render/text/ast2mscgen", | ||
"./render/text/ast2msgenny", | ||
"./render/text/ast2xu", | ||
"./render/text/ast2dot", | ||
"./render/text/ast2doxygen", | ||
"./render/graphics/renderast"], function( | ||
_, | ||
mscgenparser, | ||
xuparser, | ||
msgennyparser, | ||
ast2mscgen, | ||
ast2msgenny, | ||
ast2xu, | ||
ast2dot, | ||
ast2doxygen, | ||
renderast) { | ||
/** | ||
* @deprecated - here only for backward compatibility reasons. | ||
* Will be removed in version 2.0.0 and higher. | ||
* Instead use index.js. It provides the same | ||
* functionality with the same interface | ||
*/ | ||
define(["./index"], function(index) { | ||
"use strict"; | ||
var DEFAULT_PARSER = mscgenparser; | ||
var DEFAULT_TEXT_RENDERER = ast2mscgen; | ||
var gLang2Parser = { | ||
mscgen : mscgenparser, | ||
xu : xuparser, | ||
msgenny : msgennyparser | ||
}; | ||
var gLang2TextRenderer = { | ||
mscgen : ast2mscgen, | ||
msgenny : ast2msgenny, | ||
xu : ast2xu, | ||
dot : ast2dot, | ||
doxygen : ast2doxygen | ||
}; | ||
var getParser = _.memoize( | ||
function getParser (pLanguage) { | ||
if (["ast", "json"].indexOf(pLanguage) > -1) { | ||
return JSON; | ||
} | ||
return gLang2Parser[pLanguage] || DEFAULT_PARSER; | ||
} | ||
); | ||
var getGraphicsRenderer = _.memoize( | ||
function getGraphicsRenderer(){ | ||
return renderast; | ||
} | ||
); | ||
var getTextRenderer = _.memoize( | ||
function getTextRenderer(pLanguage){ | ||
return gLang2TextRenderer[pLanguage] || DEFAULT_TEXT_RENDERER; | ||
} | ||
); | ||
function runCallBack(pCallBack, pError, pResult){ | ||
/* istanbul ignore else */ | ||
if (Boolean(pCallBack)){ | ||
if (Boolean(pError)) { | ||
pCallBack(pError, null); | ||
} else { | ||
pCallBack(null, pResult); | ||
} | ||
} | ||
} | ||
return { | ||
renderMsc : function renderMsc(pScript, pOptions, pCallBack){ | ||
var lOptions = pOptions || {}; | ||
_.defaults(lOptions, { | ||
inputType : "mscgen", | ||
elementId : "__svg", | ||
window : pOptions.window || window, | ||
includeSource : true, | ||
styleAdditions : null, | ||
additionalTemplate : null, | ||
mirrorEntitiesOnBottom : false | ||
}); | ||
try { | ||
runCallBack( | ||
pCallBack, | ||
null, | ||
getGraphicsRenderer().renderASTNew( | ||
getParser(lOptions.inputType).parse(pScript), | ||
lOptions.window, | ||
lOptions.elementId, | ||
{ | ||
source: lOptions.includeSource ? pScript : null, | ||
styleAdditions: lOptions.styleAdditions, | ||
additionalTemplate: lOptions.additionalTemplate, | ||
mirrorEntitiesOnBottom: lOptions.mirrorEntitiesOnBottom | ||
} | ||
) | ||
); | ||
} catch (pException){ | ||
runCallBack(pCallBack, pException); | ||
} | ||
}, | ||
translateMsc : function translateMsc(pScript, pOptions, pCallBack){ | ||
var lOptions = pOptions || {}; | ||
_.defaults(lOptions, { | ||
inputType: "mscgen", | ||
outputType: "json" | ||
}); | ||
try { | ||
runCallBack( | ||
pCallBack, | ||
null, | ||
(lOptions.outputType === "json") | ||
? getParser(lOptions.inputType).parse(pScript) | ||
: getTextRenderer(lOptions.outputType).render( | ||
(lOptions.inputType === "json" && typeof pScript === "string") | ||
? getParser(lOptions.inputType).parse(pScript) | ||
: pScript | ||
) | ||
); | ||
} catch (pException) { | ||
runCallBack(pCallBack, pException); | ||
} | ||
}, | ||
getParser : getParser, | ||
getGraphicsRenderer : getGraphicsRenderer, | ||
getTextRenderer : getTextRenderer | ||
renderMsc : index.renderMsc, | ||
translateMsc : index.translateMsc, | ||
version : index.version, | ||
getParser : index.getParser, | ||
getGraphicsRenderer : index.getGraphicsRenderer, | ||
getTextRenderer : index.getTextRenderer | ||
}; | ||
@@ -137,0 +18,0 @@ }); |
{ | ||
"name": "mscgenjs", | ||
"version": "1.4.3", | ||
"version": "1.5.0", | ||
"description": "Implementation of MscGen in JavaScript", | ||
@@ -14,9 +14,9 @@ "main": "index.js", | ||
"codeclimate-test-reporter": "0.3.3", | ||
"eslint": "3.0.1", | ||
"eslint": "3.2.2", | ||
"istanbul": "0.4.4", | ||
"js-makedepend": "0.4.0", | ||
"js-makedepend": "1.0.1", | ||
"jsdom": "9.4.1", | ||
"lodash-cli": "4.13.1", | ||
"mocha": "2.5.3", | ||
"npm-check-updates": "2.7.0", | ||
"lodash-cli": "4.14.2", | ||
"mocha": "3.0.2", | ||
"npm-check-updates": "2.8.0", | ||
"nsp": "2.6.1", | ||
@@ -31,3 +31,3 @@ "pegjs": "0.9.0", | ||
"plato": "plato -r -d platoreports -x \"parser|test|lib|platoreports|node_modules|coverage|indexAMD|csstemplates\" ./", | ||
"lint": "eslint index.js indexAMD.js parse render test", | ||
"lint": "eslint index.js index-lazy.js indexAMD.js main parse render test", | ||
"codeclimate-cover-submit": "node node_modules/codeclimate-test-reporter/bin/codeclimate.js < coverage/lcov.info", | ||
@@ -34,0 +34,0 @@ "npm-check-updates": "ncu --upgrade" |
@@ -19,3 +19,5 @@ # Parsing | ||
needs to be replaced with `define ([], function(){`. The | ||
`commonjs2amd.sh` script in the utl directory does just that. | ||
`commonjs2amd.sh` script in the utl directory does just that and | ||
adds an amd loader boiler plate, so the resulting parser is \ | ||
usable both as amd and as commonjs module. | ||
Usage: | ||
@@ -28,3 +30,3 @@ ```bash | ||
All parsers generate a JSON syntax tree that consist of three | ||
parts that make up mscgen programs: | ||
parts that make up mscgen programs: | ||
- options | ||
@@ -36,3 +38,3 @@ - entities | ||
> :information_source: When you add `debug=true` to the url of the | ||
> :information_source: When you add `debug=true` to the url of the | ||
> online interpreter (https://sverweij.github.io/mscgen_js?debug=true) | ||
@@ -90,3 +92,3 @@ > it gets an extra language option called "AST". When you click it, | ||
- If the input program does not have an option, the associated | ||
- If the input program does not have an option, the associated | ||
attribute won't be in the syntax tree either. | ||
@@ -97,6 +99,6 @@ - If the input program does not have any options at all, the | ||
`wordwraparcs` can have | ||
- the values _true_, _1_, _on_, _"true"_ and _"on"_ for *true* and | ||
- the values _true_, _1_, _on_, _"true"_ and _"on"_ for *true* and | ||
- _false_, _0_, _off_, _"false"_ and _"off"_ for *false*. | ||
The parser flattens this to "true" and "false" respectively so | ||
consumers working with the syntax tree don't have to worry | ||
consumers working with the syntax tree don't have to worry | ||
about it. | ||
@@ -103,0 +105,0 @@ |
188
README.md
@@ -17,6 +17,6 @@ # mscgen_js - core package | ||
- If you find proof to the contrary: [tell us][mscgenjs.issues.compliance]. | ||
- Parses and renders [Xù][mscgenjs.wikum.xu] | ||
- Parses and renders [Xù][mscgenjs.doc.xu] | ||
Xù is a strict superset of MscGen. It adds things like `alt` and | ||
`loop`. | ||
- Parses and renders [MsGenny][mscgenjs.wikum.msgenny] | ||
- Parses and renders [MsGenny][mscgenjs.doc.msgenny] | ||
Same as Xù, but with a simpler syntax. | ||
@@ -28,6 +28,150 @@ - Translates between these three languages | ||
## I'm still here. How can I use this? | ||
You already know how to `npm install mscgenjs`, right? | ||
### Prerequisites | ||
mscgen_js works in anything with an implementation of the document object model | ||
(DOM). This includes web-browsers, client-side application shells like electron | ||
and even headless browsers like phantomjs. It does _not_ include nodejs | ||
(although it is possible to get it sorta to work even there with | ||
[jsdom](https://github.com/tmpvar/jsdom)). | ||
Good. For examples on how to use the mscgen_js core package, have a look at | ||
the source code of any of the above mentioned tools. | ||
### Get it | ||
`npm install mscgenjs` | ||
### Import it | ||
You'll have to import the mscgenjs module somehow. There's a commonjs and a | ||
requirejs variant, both of which are in the `mscgenjs` | ||
[npm module](https://www.npmjs.com/package/mscgenjs) | ||
(repo: [sverweij/mscgenjs-core](https://github.com/sverweij/mscgenjs-core)). | ||
```javascript | ||
// commonjs | ||
var mscgenjs = require('mscgenjs'); | ||
``` | ||
```javascript | ||
// commonjs, but with lazy loading. Useful when you're using it in | ||
// e.g. an electron shell without a minifier. | ||
var mscgenjs = require('mscgenjs/index-lazy'); | ||
``` | ||
```javascript | ||
// requirejs - assuming the module is in your root and you're loading from | ||
// node_modules. | ||
define(['./node_modules/mscgenjs/index'], function(mscgenjs){ | ||
// your code here | ||
}); | ||
// ... or using the alternative notation | ||
define(function(require){ | ||
var mscgenjs = require("./node_modules/mscgenjs/index"); | ||
// your code here | ||
}); | ||
``` | ||
### Use it | ||
- **use the root module directly** => recommended | ||
e.g. atom-mscgen-preview takes that approach. See the samples below | ||
- **individually do calls to the parse and render steps** => do this when you have | ||
special needs. | ||
This is the approach the mscgen_js and mscgenjs-inpage script take. The main | ||
reason these aren't using the root module directly is that it did not exist | ||
at the time they were written (JUN 2013 and APR 2014 respectively). | ||
[Link to where this happens in mscgen_js](https://github.com/sverweij/mscgen_js/blob/master/src/script/interpreter/uistate.js#L242) | ||
and one | ||
[where it happens in mscgenjs-inpage](https://github.com/sverweij/mscgenjs-inpage/blob/master/src/mscgen-inpage.js#L116). | ||
Here's some some samples for using the root module directly: | ||
```Javascript | ||
// renders the given script in the (already existing) element with id=yourCoolId | ||
mscgenjs.renderMsc ( | ||
'msc { a,b; a=>>b[label="render this"; }', | ||
{ | ||
elementId: "yourCoolId" | ||
} | ||
); | ||
``` | ||
If you want to do error handling, or act on the created svg: provide a callback: | ||
```javascript | ||
mscgenjs.renderMsc ( | ||
'msc { a,b; a=>>b[label="render this"; }', | ||
{ | ||
elementId: "yourOtherCoolId" | ||
}, | ||
handleRenderMscResult | ||
); | ||
function handleRenderMscResult(pError, pSuccess) { | ||
if (Boolean(pError)){ | ||
console.log (pError); | ||
return; | ||
} else if (Boolean(pSuccess)){ | ||
console.log ('That worked - cool!'); | ||
return; | ||
// the svg is in the pSuccess argument | ||
} | ||
console.log('Wat! Error nor success?'); | ||
} | ||
``` | ||
The second parameter in the `renderMsc` call takes some options that influence rendering e.g. | ||
```javascript | ||
mscgenjs.renderMsc ( | ||
'a=>>b:render this;', | ||
{ | ||
elementId: "yourThirdCoolId", | ||
inputType: "msgenny", // language to parse - default "mscgen"; other accepted languages: "xu", "msgenny" and "json" | ||
mirrorEntitiesOnBottom: true, // draws entities on both top and bottom of the chart - default false | ||
additionalTemplate: "lazy", // use a predefined template. E.g. "lazy" or "classic". Default empty | ||
includeSource: false, // whether the generated svg should include the source in a desc element | ||
}, | ||
``` | ||
In [doc/samples](doc/samples) you'll find a simple dynamic integration using | ||
webpack and one using requirejs. | ||
### Transpiling | ||
You can use the second function of the root module for transpiling to and from | ||
msgenny, mscgen, xù and json and for exporting to dot and doxygen. This function | ||
does _not_ depend on the DOM so you can use it not only in browsers & | ||
browser-likes, but also hack-free in node. | ||
```javascript | ||
mscgenjs.translateMsc( | ||
'wordwraparcs=on; you =>> me: can we translate this to Mscgen please?; me >> you: "yes, you can - use translateMsc";', | ||
{ | ||
inputType: "msgenny", // defaults to mscgen - other accepted formats: msgenny, xu, json | ||
outputType: "mscgen" // defaults to json - other accepted formats: mscgen, msgenny, xu, dot, doxygen | ||
}, | ||
function(pError, pSuccess){ | ||
if(Boolean(pError)){ | ||
console.log("error:", pError); | ||
return; | ||
} | ||
if(Boolean(pSuccess)){ | ||
// the transpiled result is in pSuccess | ||
console.log(pSuccess); | ||
return; | ||
} | ||
console.log("Neither success nor failure. I do not even."); | ||
} | ||
); | ||
// result: | ||
// | ||
// msc { | ||
// wordwraparcs=true; | ||
// | ||
// you, | ||
// me; | ||
// | ||
// you =>> me [label="can we translate this to Mscgen please?"]; | ||
// me >> you [label="yes, you can - use translateMsc"]; | ||
// } | ||
``` | ||
## Battle tested implementations | ||
Software that uses `mscgenjs`: | ||
- the atom package [mscgen-preview][mscgen-preview.source] (CoffeeScript alert) | ||
@@ -47,10 +191,8 @@ - specifically the [renderer][mscgen-preview.source.render] | ||
Hint: for rendering graphics the library needs a DOMElement (with a | ||
unique id) to perform its rendering in. | ||
### Building mscgen_js | ||
## Hacking on mscgenjs itself | ||
### Building mscgenjs | ||
See [build.md][mscgenjs.docbuild]. | ||
### How does mscgen_js work? | ||
You can start reading about that [over here](wikum/readme.md) | ||
### How does mscgenjs work? | ||
You can start reading about that [over here](doc/readme.md) | ||
@@ -97,3 +239,3 @@ ## License | ||
[amdefine.license]: wikum/licenses/license.amdefine.md | ||
[amdefine.license]: doc/licenses/license.amdefine.md | ||
[atom]: https://atom.io | ||
@@ -112,3 +254,3 @@ [codeclimate.mscgenjs]: https://codeclimate.com/github/sverweij/mscgenjs-core | ||
[jsdom.author]: http://tmpvar.com/ | ||
[jsdom.license]: wikum/licenses/license.jsdom.md | ||
[jsdom.license]: doc/licenses/license.jsdom.md | ||
[license.gpl-3.0]: http://www.gnu.org/licenses/gpl.html | ||
@@ -123,4 +265,4 @@ [mscgen]: http://www.mcternan.me.uk/mscgen | ||
[mscgenjs.cli.source]: https://github.com/sverweij/mscgenjs-cli | ||
[mscgenjs.docbuild]: wikum/build.md | ||
[mscgenjs.docsource]: wikum/README.md | ||
[mscgenjs.docbuild]: doc/build.md | ||
[mscgenjs.docsource]: doc/README.md | ||
[mscgenjs.embed]: https://sverweij.github.io/mscgen_js/embed.html?utm_source=mscgenjs-core | ||
@@ -138,17 +280,17 @@ [mscgenjs.embed.source]: https://github.com/sverweij/mscgenjs-inpage/blob/master/src/mscgen-inpage.js | ||
[mscgenjs.license]: LICENSE.md | ||
[mscgenjs.wikum.msgenny]: wikum/msgenny.md | ||
[mscgenjs.wikum.xu]: wikum/xu.md | ||
[mscgenjs.doc.msgenny]: doc/msgenny.md | ||
[mscgenjs.doc.xu]: doc/xu.md | ||
[pegjs]: http://pegjs.org | ||
[pegjs.author]: http://majda.cz/about | ||
[pegjs.license]: wikum/licenses/license.pegjs.md | ||
[pegjs.license]: doc/licenses/license.pegjs.md | ||
[phantomjs]: https://www.npmjs.com/package/phantomjs | ||
[requirejs.license]: wikum/licenses/license.requirejs.md | ||
[requirejs.license]: doc/licenses/license.requirejs.md | ||
[travis.mscgenjs]: https://travis-ci.org/sverweij/mscgenjs-core | ||
[travis.mscgenjs.badge]: https://travis-ci.org/sverweij/mscgenjs-core.svg?branch=master | ||
[21]: wikum/licenses/license.mocha.md | ||
[22]: wikum/licenses/license.eslint.md | ||
[23]: wikum/licenses/license.plato.md | ||
[28]: wikum/licenses/license.istanbul.md | ||
[21]: doc/licenses/license.mocha.md | ||
[22]: doc/licenses/license.eslint.md | ||
[23]: doc/licenses/license.plato.md | ||
[28]: doc/licenses/license.istanbul.md | ||
[35]: https://nodesecurity.io/ | ||
[39]: https://github.com/chaijs/chai | ||
[40]: https://github.com/krampstudio/chai-xml |
@@ -9,3 +9,3 @@ /* istanbul ignore else */ | ||
return { | ||
baseTemplate : "svg.<%=id%>{font-family:Helvetica,sans-serif;font-size:<%=fontSize%>px;font-weight:normal;font-style:normal;text-decoration:none;background-color:white;stroke:black;stroke-width:<%=lineWidth%>;color:black;}.<%=id%> rect{fill:none;stroke:black;}.<%=id%> rect.entity{fill:white;}.<%=id%> rect.label-text-background{fill:white;stroke:white;stroke-width:0;}.<%=id%> rect.bglayer{fill:white;stroke:white;stroke-width:0;}.<%=id%> line{stroke:black;}.<%=id%> line.return, .<%=id%> path.return{stroke-dasharray:5,2;}.<%=id%> line.comment{stroke-dasharray:5,2;}.<%=id%> line.inline_expression_divider{stroke-dasharray:10,5;}.<%=id%> text{color:inherit;stroke:none;text-anchor:middle;}.<%=id%> text.entity-text{text-decoration:underline;}.<%=id%> text.anchor-start{text-anchor:start;}.<%=id%> path{stroke:black;color:black;fill:none;}.<%=id%> .arrow-marker{overflow:visible;}.<%=id%> .arrow-style{stroke-width:1;}.<%=id%> .arcrowomit{stroke-dasharray:2,2;}.<%=id%> rect.box, .<%=id%> path.box{fill:white;}.<%=id%> .inherit{stroke:inherit;color:inherit;}.<%=id%> .inherit-fill{fill:inherit;}.<%=id%> .watermark{stroke:black;color:black;fill:black;font-size:48pt;font-weight:bold;opacity:0.14;}", | ||
baseTemplate : "svg.<%=id%>{font-family:Helvetica,sans-serif;font-size:<%=fontSize%>px;font-weight:normal;font-style:normal;text-decoration:none;background-color:white;stroke:black;stroke-width:<%=lineWidth%>;color:black}.<%=id%> path, .<%=id%> rect{fill:none;color:black;stroke:black}.<%=id%> .label-text-background{fill:white;stroke:white;stroke-width:0}.<%=id%> .bglayer{fill:white;stroke:white;stroke-width:0}.<%=id%> line{stroke:black}.<%=id%> line.return, .<%=id%> path.return, .<%=id%> line.comment{stroke-dasharray:5,3}.<%=id%> line.inline_expression_divider{stroke-dasharray:10,5}.<%=id%> text{color:inherit;stroke:none;text-anchor:middle}.<%=id%> text.entity-text{text-decoration:underline}.<%=id%> text.anchor-start{text-anchor:start}.<%=id%> .arrow-marker{overflow:visible}.<%=id%> .arrow-style{stroke-width:1}.<%=id%> .arcrow, .<%=id%> .arcrowomit, .<%=id%> .emphasised{stroke-linecap:butt}.<%=id%> line.arcrowomit{stroke-dasharray:2,2;}.<%=id%> .box, .<%=id%> .entity{fill:white;stroke-linejoin:round}.<%=id%> .inherit{stroke:inherit;color:inherit}.<%=id%> .inherit-fill{fill:inherit}.<%=id%> .watermark{stroke:black;color:black;fill:black;font-size:48pt;font-weight:bold;opacity:0.14}", | ||
additionalTemplates : [ | ||
@@ -21,2 +21,6 @@ { | ||
{ | ||
"name": "fountainpen", | ||
"css": "svg.<%=id%>{font-family:cursive;stroke-opacity:0.4;stroke-linecap:round;background-color:transparent}.<%=id%> text{fill:rgba(0,0,128,0.8)}.<%=id%> marker polygon{fill:rgba(0,0,255,0.4);stroke-linejoin:round}.<%=id%> line, .<%=id%> path, .<%=id%> rect, .<%=id%> polygon{stroke:blue !important}.<%=id%> text.entity-text{font-weight:bold;text-decoration:none}.<%=id%> text.return-text{font-style:italic}.<%=id%> path.note{fill:#FFFFCC;}.<%=id%> .label-text-background{opacity:0}.<%=id%> .comment,.<%=id%> .inline_expression,.<%=id%> .inline_expression_divider,.<%=id%> .inline_expression_label{stroke:black}.<%=id%> .bglayer, .<%=id%> .entity{fill:transparent;}" | ||
}, | ||
{ | ||
"name": "grayscaled", | ||
@@ -23,0 +27,0 @@ "css": "svg.<%=id%>{filter:grayscale(1);-webkit-filter:grayscale(1);}" |
@@ -9,3 +9,2 @@ /* istanbul ignore else */ | ||
function rad2deg(pDegrees){ | ||
@@ -15,17 +14,71 @@ return (pDegrees * 360) / (2 * Math.PI); | ||
function _getDiagonalAngle(pBBox) { | ||
return 0 - rad2deg(Math.atan(pBBox.height / pBBox.width)); | ||
function getLineLength(pLine) { | ||
var lA = Math.abs(pLine.xTo - pLine.xFrom); | ||
var lB = Math.abs(pLine.yTo - pLine.yFrom); | ||
return Math.sqrt((lA * lA) + (lB * lB)); | ||
} | ||
function _getDirection(pLine){ | ||
var ldx = -1; | ||
if (pLine.xTo > pLine.xFrom){ | ||
ldx = 1; | ||
} | ||
function getNumberOfSegments(pLine, pInterval){ | ||
var lLineLength = getLineLength(pLine); | ||
return lLineLength > 0 ? Math.floor(lLineLength / pInterval) : 0; | ||
} | ||
function getDirection(pLine){ | ||
var lSignX = pLine.xTo > pLine.xFrom ? 1 : -1; | ||
return { | ||
dx: ldx, | ||
dy: ldx * (pLine.yTo - pLine.yFrom) / (pLine.xTo - pLine.xFrom) | ||
signX: lSignX, | ||
signY: pLine.yTo > pLine.yFrom ? 1 : -1, | ||
dy: lSignX * (pLine.yTo - pLine.yFrom) / (pLine.xTo - pLine.xFrom) | ||
}; | ||
} | ||
/** | ||
* Returns a random (real) number between -pNumber and +pNumber (inclusive) | ||
* | ||
* @param {number} pNumber a real | ||
* @return {number} | ||
*/ | ||
function getRandomDeviation(pNumber) { | ||
return Math.round(Math.random() * 2 * pNumber) - pNumber; | ||
} | ||
function getBetweenPoints(pLine, pInterval, pWobble) { | ||
if (pInterval <= 0) { | ||
throw new Error("pInterval must be > 0"); | ||
} | ||
pInterval = Math.min(getLineLength(pLine), pInterval); | ||
var lRetval = []; | ||
var lNoSegments = getNumberOfSegments(pLine, pInterval); | ||
var lDir = getDirection(pLine); | ||
var lIntervalX = lDir.signX * Math.sqrt((Math.pow(pInterval, 2)) / (1 + Math.pow(lDir.dy, 2))); | ||
var lIntervalY = lDir.signY * (Math.abs(lDir.dy) === Infinity | ||
? pInterval | ||
: Math.sqrt((Math.pow(lDir.dy, 2) * Math.pow(pInterval, 2)) / (1 + Math.pow(lDir.dy, 2)))); | ||
var lCurvePoint = {}; | ||
for (var i = 1; i <= lNoSegments; i++) { | ||
lCurvePoint = { | ||
controlX : pLine.xFrom + (i - 0.5) * lIntervalX + getRandomDeviation(pWobble), | ||
controlY : pLine.yFrom + (i - 0.5) * lIntervalY + getRandomDeviation(pWobble), | ||
x : pLine.xFrom + i * lIntervalX, | ||
y : pLine.yFrom + i * lIntervalY | ||
}; | ||
if (pInterval > | ||
getLineLength({ | ||
xFrom: lCurvePoint.x, | ||
yFrom: lCurvePoint.y, | ||
xTo: pLine.xTo, | ||
yTo: pLine.yTo | ||
}) | ||
){ | ||
lCurvePoint.x = pLine.xTo; | ||
lCurvePoint.y = pLine.yTo; | ||
} | ||
lRetval.push(lCurvePoint); | ||
} | ||
return lRetval; | ||
} | ||
return { | ||
@@ -39,3 +92,5 @@ /** | ||
*/ | ||
getDiagonalAngle : _getDiagonalAngle, | ||
getDiagonalAngle: function (pBBox) { | ||
return 0 - rad2deg(Math.atan(pBBox.height / pBBox.width)); | ||
}, | ||
@@ -46,5 +101,44 @@ /** | ||
* @param {object} pLine - (xFrom,yFrom, xTo, YTo quadruple) | ||
* @return {number} the angle (in radials) of the line | ||
* @return {object} the angle of the line in an object: | ||
* signX: the x direction (1 or -1) | ||
* signY: the y direction (1 or -1) | ||
* dy: the angle (in radials) | ||
*/ | ||
getDirection : _getDirection | ||
getDirection: getDirection, | ||
/** | ||
* Calculates the length of the given line | ||
* @param {object} pLine an object with xFrom, yFrom and xTo and yTo | ||
* as properties | ||
* @return {number} The length | ||
*/ | ||
getLineLength: getLineLength, | ||
/** | ||
* Calculates the number of times a segment of pInterval length | ||
* can fit into pLine | ||
* | ||
* @param {object} pLine an object with xFrom, yFrom, and xTo and yTo | ||
* @param {number} pInterval the length of the segments to fit into the | ||
* line | ||
* @return {number} a natural number | ||
*/ | ||
getNumberOfSegments: getNumberOfSegments, | ||
/** | ||
* returns an array of curvepoints (x,y, controlX, controlY) along pLine, | ||
* at pInterval length intervals. The pWobble parameter influences the | ||
* amount controlX and controlY can at most deviate from the pLine. | ||
* | ||
* | ||
* @param {object} pLine a line (an object with xFrom, yFrom, | ||
* xTo, yTo properties) | ||
* @param {number} pInterval The length of the interval between two | ||
* points on the line. Must be > 0. The | ||
* function throws an error in other cases | ||
* @param {number} pWobble The maximum amount of deviation allowed for | ||
* control points | ||
* @return {array} | ||
*/ | ||
getBetweenPoints: getBetweenPoints | ||
}; | ||
@@ -51,0 +145,0 @@ }); |
@@ -179,3 +179,3 @@ /* istanbul ignore else */ | ||
function getSignalend(pKind, pFrom, pTo){ | ||
if (pFrom && pTo && (["<->", "->"].indexOf(pKind > -1))) { | ||
if (pFrom && pTo && (["<->", "->"].indexOf(pKind) > -1)) { | ||
return (pFrom < pTo) ? "signal" : "signal-u"; | ||
@@ -202,6 +202,6 @@ } | ||
value: pAttribute.value | ||
.replace(/\{\{signal-marker-end\}\}/g, getSignalend(pKind, pFrom, pTo)) | ||
.replace(/\{\{signal-marker-start\}\}/g, getSignalstart(pKind, pFrom, pTo)) | ||
.replace(/\{\{id\}\}/g, pId) | ||
.replace(/\{\{color\}\}/g, pLineColor || "black") | ||
.replace(/\{\{signal-marker-end\}\}/g, getSignalend(pKind, pFrom, pTo)) | ||
.replace(/\{\{signal-marker-start\}\}/g, getSignalstart(pKind, pFrom, pTo)) | ||
.replace(/\{\{id\}\}/g, pId) | ||
.replace(/\{\{color\}\}/g, pLineColor || "black") | ||
}; | ||
@@ -208,0 +208,0 @@ }); |
@@ -511,3 +511,3 @@ /* istanbul ignore else */ | ||
gInlineExpressionMemory = []; | ||
gChart.layer.defs.appendChild(renderLifeLines(pEntities, id.get("arcrow"))); | ||
gChart.layer.defs.appendChild(renderLifeLines(pEntities, "arcrow", null, id.get("arcrow"))); | ||
@@ -653,3 +653,5 @@ /* put some space between the entities and the arcs */ | ||
}, | ||
pClass | ||
{ | ||
class: pClass | ||
} | ||
); | ||
@@ -788,4 +790,6 @@ if (pEntity.linecolor) { | ||
{xFrom: pFrom, yFrom: 0, xTo: pTo, yTo: lArcGradient}, | ||
lClass, | ||
lDoubleLine | ||
{ | ||
class: lClass, | ||
doubleLine: lDoubleLine | ||
} | ||
); | ||
@@ -878,3 +882,5 @@ mark.getAttributes( | ||
}, | ||
lClass | ||
{ | ||
class: lClass | ||
} | ||
); | ||
@@ -881,0 +887,0 @@ |
@@ -45,5 +45,27 @@ /* istanbul ignore else */ | ||
if (pPosition === 0) { | ||
lText = fact.createText(pLine, {x:pMiddle, y:pY}, pClass, pArc.url, pArc.id, pArc.idurl); | ||
lText = fact.createText( | ||
pLine, | ||
{ | ||
x : pMiddle, | ||
y : pY | ||
}, | ||
{ | ||
class : pClass, | ||
url : pArc.url, | ||
id : pArc.id, | ||
idurl : pArc.idurl | ||
} | ||
); | ||
} else { | ||
lText = fact.createText(pLine, {x:pMiddle, y:pY}, pClass, pArc.url); | ||
lText = fact.createText( | ||
pLine, | ||
{ | ||
x : pMiddle, | ||
y : pY | ||
}, | ||
{ | ||
class : pClass, | ||
url : pArc.url | ||
} | ||
); | ||
} | ||
@@ -50,0 +72,0 @@ return lText; |
@@ -6,3 +6,7 @@ /* istanbul ignore else */ | ||
define(["./constants", "./svglowlevelfactory", "./geometry"], function(C, factll, math) { | ||
define([ | ||
"./constants", | ||
"./svglowlevelfactory", | ||
"./geometry", | ||
"../../lib/lodash/lodash.custom"], function(C, factll, math, _) { | ||
/** | ||
@@ -25,2 +29,10 @@ * Renders individual elements in sequence charts | ||
function point2String(pX, pY) { | ||
return pX.toString() + "," + pY.toString() + " "; | ||
} | ||
function pathPoint2String(pType, pX, pY) { | ||
return pType + point2String(pX, pY); | ||
} | ||
/** | ||
@@ -68,3 +80,3 @@ * Creates an svg path element given the path pD, with pClass applied | ||
function createSingleLine(pLine, pClass) { | ||
function createSingleLine(pLine, pOptions) { | ||
return factll.createElement( | ||
@@ -77,3 +89,3 @@ "line", | ||
y2: pLine.yTo.toString(), | ||
class: pClass | ||
class: pOptions ? pOptions.class : null | ||
} | ||
@@ -107,3 +119,10 @@ ); | ||
function _createText(pLabel, pCoords, pClass, pURL, pID, pIDURL) { | ||
function _createText(pLabel, pCoords, pOptions) { | ||
var lOptions = _.defaults( | ||
pOptions, { | ||
class: null, | ||
url: null, | ||
id: null, | ||
idurl: null | ||
}); | ||
var lText = factll.createElement( | ||
@@ -114,10 +133,10 @@ "text", | ||
y: pCoords.y.toString(), | ||
class: pClass | ||
class: lOptions.class | ||
} | ||
); | ||
lText.appendChild(createTSpan(pLabel, pURL)); | ||
lText.appendChild(createTSpan(pLabel, lOptions.url)); | ||
if (pID) { | ||
var lTSpanID = createTSpan(" [" + pID + "]", pIDURL); | ||
if (lOptions.id) { | ||
var lTSpanID = createTSpan(" [" + lOptions.id + "]", lOptions.idurl); | ||
lTSpanID.setAttribute("style", lSuperscriptStyle); | ||
@@ -151,28 +170,29 @@ lText.appendChild(lTSpanID); | ||
function createDoubleLine(pLine, pClass) { | ||
function createDoubleLine(pLine, pOptions) { | ||
var lSpace = C.LINE_WIDTH; | ||
var lClass = pOptions ? pOptions.class : null; | ||
var lDir = math.getDirection(pLine); | ||
var lEndCorr = determineEndCorrection(pLine, pClass); | ||
var lStartCorr = determineStartCorrection(pLine, pClass); | ||
var lEndCorr = determineEndCorrection(pLine, lClass); | ||
var lStartCorr = determineStartCorrection(pLine, lClass); | ||
var lLenX = (pLine.xTo - pLine.xFrom + lEndCorr - lStartCorr).toString(); | ||
var lLenY = (pLine.yTo - pLine.yFrom).toString(); | ||
var lStubble = "l" + lDir.dx.toString() + "," + lDir.dy.toString(); | ||
var lLine = " l" + lLenX + "," + lLenY; | ||
var lStubble = pathPoint2String("l", lDir.signX, lDir.dy); | ||
var lLine = pathPoint2String("l", lLenX, lLenY); | ||
return _createPath( | ||
"M" + pLine.xFrom.toString() + "," + (pLine.yFrom - 7.5 * C.LINE_WIDTH * lDir.dy).toString() + | ||
pathPoint2String("M", pLine.xFrom, (pLine.yFrom - 7.5 * C.LINE_WIDTH * lDir.dy)) + | ||
// left stubble: | ||
lStubble + | ||
"M" + (pLine.xFrom + lStartCorr).toString() + "," + (pLine.yFrom - lSpace).toString() + | ||
pathPoint2String("M", pLine.xFrom + lStartCorr, pLine.yFrom - lSpace) + | ||
// upper line: | ||
lLine + | ||
"M" + (pLine.xFrom + lStartCorr).toString() + "," + (pLine.yFrom + lSpace).toString() + | ||
pathPoint2String("M", pLine.xFrom + lStartCorr, pLine.yFrom + lSpace) + | ||
// lower line | ||
lLine + | ||
"M" + (pLine.xTo - lDir.dx).toString() + "," + (pLine.yTo + 7.5 * C.LINE_WIDTH * lDir.dy).toString() + | ||
pathPoint2String("M", pLine.xTo - lDir.signX, pLine.yTo + 7.5 * C.LINE_WIDTH * lDir.dy) + | ||
// right stubble | ||
lStubble, | ||
pClass | ||
lClass | ||
); | ||
@@ -336,11 +356,13 @@ } | ||
return _createPath( | ||
// start | ||
"M" + pBBox.x + "," + (pBBox.y + (pBBox.height / 2)) + | ||
// start | ||
"l" + lSlopeOffset + ", -" + pBBox.height / 2 + | ||
// top line | ||
"l" + (pBBox.width - 2 * lSlopeOffset) + ",0" + | ||
// right wedge | ||
"l" + lSlopeOffset + "," + pBBox.height / 2 + | ||
"l-" + lSlopeOffset + "," + pBBox.height / 2 + | ||
// bottom line: | ||
"l-" + (pBBox.width - 2 * lSlopeOffset) + ",0 " + | ||
// bottom line | ||
"l-" + lSlopeOffset + ",-" + pBBox.height / 2, | ||
"z", | ||
pClass, pColor, pBgColor | ||
@@ -369,2 +391,4 @@ ); | ||
// fold: | ||
// we lift the pen of the paper here to make sure the fold | ||
// gets the fill color as well when such is specified | ||
"l0," + lFoldSize + " l" + lFoldSize + ",0 m-" + lFoldSize + ",-" + | ||
@@ -376,4 +400,10 @@ lFoldSize + " l" + lFoldSize + "," + lFoldSize + " " + | ||
"l-" + pBBox.width + ",0 " + | ||
// back to home: | ||
"l0,-" + (pBBox.height + (C.LINE_WIDTH / 2)) + " ", | ||
"l0,-" + pBBox.height + " " + | ||
// because we lifted the pen from the paper in the fold (see | ||
// the m over there) - svg interpreters consider that to be | ||
// the start of the path. So, although we're already 'home' | ||
// visually we need to do one step extra. | ||
// If we don't we end up with a little gap on the top left | ||
// corner when our stroke-linecap===butt | ||
"z", | ||
pClass, pColor, pBgColor | ||
@@ -411,11 +441,12 @@ ); | ||
/** | ||
* Creates a text node with the appropriate tspan & a elements on position | ||
* (pX, pY). | ||
* Creates a text node with the appropriate tspan & a elements on | ||
* position pCoords. | ||
* | ||
* @param {string} pLabel | ||
* @param {object} pCoords | ||
* @param {string} pClass - reference to the css class to be applied | ||
* @param {string=} pURL - link to render | ||
* @param {string=} pID - (small) id text to render | ||
* @param {string=} pIDURL - link to render for the id text | ||
* @param {object} pOptions - options to influence rendering | ||
* {string} pClass - reference to the css class to be applied | ||
* {string=} pURL - link to render | ||
* {string=} pID - (small) id text to render | ||
* {string=} pIDURL - link to render for the id text | ||
* @return {SVGElement} | ||
@@ -434,3 +465,3 @@ */ | ||
return factll.setAttributes( | ||
_createText(pText, {x: pCanvas.width / 2, y: pCanvas.height / 2}, pClass), | ||
_createText(pText, {x: pCanvas.width / 2, y: pCanvas.height / 2}, {class: pClass}), | ||
{ | ||
@@ -454,7 +485,7 @@ "transform": | ||
*/ | ||
createLine: function (pLine, pClass, pDouble) { | ||
if (Boolean(pDouble)) { | ||
return createDoubleLine(pLine, pClass); | ||
createLine: function (pLine, pOptions) { | ||
if (Boolean(pOptions) && Boolean(pOptions.doubleLine)) { | ||
return createDoubleLine(pLine, pOptions); | ||
} else { | ||
return createSingleLine(pLine, pClass); | ||
return createSingleLine(pLine, pOptions); | ||
} | ||
@@ -478,9 +509,9 @@ }, | ||
// point to start from: | ||
"M" + pPoint.x.toString() + ", -" + pPoint.y.toString() + | ||
pathPoint2String("M", pPoint.x, -pPoint.y) + | ||
// curve first to: | ||
" C" + (pPoint.x + pWidth).toString() + "," + (pPoint.y - 7.5 * C.LINE_WIDTH).toString() + | ||
pathPoint2String("C", pPoint.x + pWidth, pPoint.y - 7.5 * C.LINE_WIDTH) + | ||
// curve back from.: | ||
" " + (pPoint.x + pWidth).toString() + "," + (pEndY + 0).toString() + | ||
point2String(pPoint.x + pWidth, pEndY + 0) + | ||
// curve end-pont: | ||
" " + lEndX.toString() + "," + pEndY.toString(), | ||
point2String(lEndX, pEndY), | ||
pClass | ||
@@ -487,0 +518,0 @@ ); |
@@ -30,19 +30,19 @@ var fs = require('fs'); | ||
fs.readdirSync(pDirName) | ||
.filter(fileNameIsAddition) | ||
.map(fileNameToAdditionNode(pDirName)); | ||
.filter(fileNameIsAddition) | ||
.map(fileNameToAdditionNode(pDirName)); | ||
process.stdout.write( | ||
fs.readFileSync('render/graphics/templates/csstemplates.template.js', 'utf-8') | ||
.replace( | ||
/<%=additionalTemplates%>/g, | ||
JSON.stringify( | ||
dirToAdditionsArray("render/graphics/templates/"), | ||
null, | ||
" " | ||
.replace( | ||
/<%=additionalTemplates%>/g, | ||
JSON.stringify( | ||
dirToAdditionsArray("render/graphics/templates/"), | ||
null, | ||
" " | ||
) | ||
) | ||
) | ||
.replace( | ||
/<%=baseTemplateString%>/g, | ||
extractFileContents("render/graphics/templates/", "base.css") | ||
) | ||
.replace( | ||
/<%=baseTemplateString%>/g, | ||
extractFileContents("render/graphics/templates/", "base.css") | ||
) | ||
); |
@@ -31,3 +31,3 @@ /* | ||
} else { | ||
return true && pString !== "*"; | ||
return pString !== "*"; | ||
} | ||
@@ -34,0 +34,0 @@ } |
@@ -153,4 +153,4 @@ /* | ||
var lOptions = | ||
extractSupportedOptions(pOptions, gConfig.supportedOptions) | ||
.filter(gConfig.optionIsValidfn); | ||
extractSupportedOptions(pOptions, gConfig.supportedOptions) | ||
.filter(gConfig.optionIsValidfn); | ||
var lRetVal = ""; | ||
@@ -157,0 +157,0 @@ if (lOptions.length > 0){ |
@@ -235,5 +235,5 @@ /* Automatically adds colors to an AST: | ||
return ["linecolor", "textcolor", "textbgcolor", "arclinecolor", "arctextcolor", "arctextbgcolor"] | ||
.some(function(pColorAttr) { | ||
return Boolean(pArcOrEntity[pColorAttr]); | ||
}); | ||
.some(function(pColorAttr) { | ||
return Boolean(pArcOrEntity[pColorAttr]); | ||
}); | ||
} | ||
@@ -240,0 +240,0 @@ |
@@ -1,3 +0,3 @@ | ||
const mscgenjs = require("../"); | ||
const tst = require("./testutensils"); | ||
/* eslint max-nested-callbacks: 0 */ | ||
// const mscgenjs = require("../index-lazy"); | ||
const fix = require("./astfixtures.json"); | ||
@@ -7,2 +7,3 @@ const jsdom = require("jsdom"); | ||
const expect = chai.expect; | ||
const version = require("../package.json").version; | ||
chai.use(require("chai-xml")); | ||
@@ -30,54 +31,9 @@ | ||
describe('index', () => { | ||
function isMscGenParser(pParser){ | ||
tst.assertSyntaxError('xu { watermark="this is only valid in xu"; a,b; a->b;}', pParser); | ||
expect( | ||
pParser.parse('msc { a,"b space"; a => "b space" [label="a simple script"];}') | ||
).to.deep.equal( | ||
fix.astSimple | ||
); | ||
} | ||
function isMscGenTextRenderer(pRenderer){ | ||
expect(pRenderer.render(fix.astOneAlt)).to.equal(gExpectedMscGenOutput); | ||
} | ||
describe('#getParser()', () => { | ||
it("Returns the mscgen parser when not provided with arguments", () => { | ||
isMscGenParser(mscgenjs.getParser()); | ||
}); | ||
it('Returns the MscGen parser when not provided with a valid argument', () => { | ||
isMscGenParser(mscgenjs.getParser("c++")); | ||
}); | ||
}); | ||
describe('#getTextRenderer()', () => { | ||
it('Returns the ast2mscgen renderer when not provided with arguments', () => { | ||
isMscGenTextRenderer(mscgenjs.getTextRenderer()); | ||
}); | ||
it('Returns the ast2mscgen renderer when not with a valid argument', () => { | ||
isMscGenTextRenderer(mscgenjs.getTextRenderer("some weird xmi format")); | ||
}); | ||
}); | ||
describe('#translateMsc()', () => { | ||
it('no params translates mscgen to json', () => { | ||
mscgenjs.translateMsc(SIMPLE_MSCGEN, null, function(pError, pResult){ | ||
/* eslint no-unused-expression:0 */ | ||
expect(pError).to.be.null; | ||
expect( | ||
JSON.parse(pResult) | ||
).to.deep.equal( | ||
fix.astSimple | ||
); | ||
}); | ||
}); | ||
it('explicit mscgen & json params translates mscgen to json too', () => { | ||
mscgenjs.translateMsc( | ||
SIMPLE_MSCGEN, | ||
{inputType: "mscgen", outputType: "json"}, | ||
function(pError, pResult){ | ||
[require("../"), require("../index-lazy")].forEach(mscgenjs => { | ||
describe('index', () => { | ||
describe('#translateMsc()', () => { | ||
it('no params translates mscgen to json', () => { | ||
mscgenjs.translateMsc(SIMPLE_MSCGEN, null, function(pError, pResult){ | ||
/* eslint no-unused-expression:0 */ | ||
expect(pError).to.be.null; | ||
@@ -90,48 +46,21 @@ expect( | ||
}); | ||
}); | ||
it('invalid mscgen throws an error', () => { | ||
mscgenjs.translateMsc( | ||
SIMPLE_XU, | ||
{inputType: "mscgen", outputType: "msgenny"}, | ||
function(pError, pResult){ | ||
expect(pError).to.be.not.null; | ||
expect(pError).to.be.instanceof(Error); | ||
expect(pResult).to.be.null; | ||
}); | ||
}); | ||
it('downgrading xu -> mscgen works', () => { | ||
mscgenjs.translateMsc( | ||
JSON.stringify(fix.astOneAlt, null, ""), | ||
{inputType: "json", outputType: "mscgen"}, | ||
function(pError, pResult){ | ||
expect(pError).to.be.null; | ||
expect(pResult).to.equal(gExpectedMscGenOutput); | ||
}); | ||
}); | ||
it('translating a raw javascript object works', () => { | ||
mscgenjs.translateMsc( | ||
fix.astOneAlt, | ||
{inputType: "json", outputType: "mscgen"}, | ||
function(pError, pResult){ | ||
expect(pError).to.be.null; | ||
expect(pResult).to.equal(gExpectedMscGenOutput); | ||
}); | ||
}); | ||
}); | ||
jsdom.env("<html><body><span id='__svg'></span></body></html>", function(err, pWindow) { | ||
describe('#renderMsc()', () => { | ||
it('should given given a simple MscGen program, render an svg', () => { | ||
mscgenjs.renderMsc( | ||
}); | ||
it('explicit mscgen & json params translates mscgen to json too', () => { | ||
mscgenjs.translateMsc( | ||
SIMPLE_MSCGEN, | ||
{window: pWindow}, | ||
{inputType: "mscgen", outputType: "json"}, | ||
function(pError, pResult){ | ||
expect(pError).to.be.null; | ||
expect(pResult).xml.to.be.valid(); | ||
} | ||
); | ||
expect( | ||
JSON.parse(pResult) | ||
).to.deep.equal( | ||
fix.astSimple | ||
); | ||
}); | ||
}); | ||
it('should given given an invalid MscGen program, throw an error', () => { | ||
mscgenjs.renderMsc( | ||
it('invalid mscgen throws an error', () => { | ||
mscgenjs.translateMsc( | ||
SIMPLE_XU, | ||
{window: pWindow}, | ||
{inputType: "mscgen", outputType: "msgenny"}, | ||
function(pError, pResult){ | ||
@@ -141,23 +70,70 @@ expect(pError).to.be.not.null; | ||
expect(pResult).to.be.null; | ||
} | ||
); | ||
}); | ||
}); | ||
it('should given given a simple AST, render an svg', () => { | ||
mscgenjs.renderMsc( | ||
it('downgrading xu -> mscgen works', () => { | ||
mscgenjs.translateMsc( | ||
JSON.stringify(fix.astOneAlt, null, ""), | ||
{ | ||
inputType: "json", | ||
window: pWindow | ||
}, | ||
{inputType: "json", outputType: "mscgen"}, | ||
function(pError, pResult){ | ||
expect(pError).to.be.null; | ||
expect(pResult).xml.to.be.valid(); | ||
} | ||
); | ||
expect(pResult).to.equal(gExpectedMscGenOutput); | ||
}); | ||
}); | ||
it('translating a raw javascript object works', () => { | ||
mscgenjs.translateMsc( | ||
fix.astOneAlt, | ||
{inputType: "json", outputType: "mscgen"}, | ||
function(pError, pResult){ | ||
expect(pError).to.be.null; | ||
expect(pResult).to.equal(gExpectedMscGenOutput); | ||
}); | ||
}); | ||
it('returns a version number equal to the one in package.json', () => { | ||
expect(mscgenjs.version).to.equal(version); | ||
}); | ||
}); | ||
jsdom.env("<html><body><span id='__svg'></span></body></html>", function(err, pWindow) { | ||
describe('#renderMsc()', () => { | ||
it('should given given a simple MscGen program, render an svg', () => { | ||
mscgenjs.renderMsc( | ||
SIMPLE_MSCGEN, | ||
{window: pWindow}, | ||
function(pError, pResult){ | ||
expect(pError).to.be.null; | ||
expect(pResult).xml.to.be.valid(); | ||
} | ||
); | ||
}); | ||
it('should given given an invalid MscGen program, throw an error', () => { | ||
mscgenjs.renderMsc( | ||
SIMPLE_XU, | ||
{window: pWindow}, | ||
function(pError, pResult){ | ||
expect(pError).to.be.not.null; | ||
expect(pError).to.be.instanceof(Error); | ||
expect(pResult).to.be.null; | ||
} | ||
); | ||
}); | ||
it('should given given a simple AST, render an svg', () => { | ||
mscgenjs.renderMsc( | ||
JSON.stringify(fix.astOneAlt, null, ""), | ||
{ | ||
inputType: "json", | ||
window: pWindow, | ||
includeSource: false | ||
}, | ||
function(pError, pResult){ | ||
expect(pError).to.be.null; | ||
expect(pResult).xml.to.be.valid(); | ||
} | ||
); | ||
}); | ||
}); | ||
}); | ||
it('dummy so mocha executes the tests wrapped in jsdom', () => { | ||
return true; | ||
}); | ||
}); | ||
it('dummy so mocha executes the tests wrapped in jsdom', () => { | ||
return true; | ||
}); | ||
}); |
var assert = require("assert"); | ||
var ast2animate = require("../../../render/text/ast2animate"); | ||
var parser = require("../../../parse/xuparser_node"); | ||
var parser = require("../../../parse/xuparser"); | ||
var fix = require("../../astfixtures.json"); | ||
@@ -5,0 +5,0 @@ var fs = require("fs"); |
const assert = require("assert"); | ||
const renderer = require("../../../render/text/ast2mscgen"); | ||
const parser = require("../../../parse/mscgenparser_node"); | ||
const parser = require("../../../parse/mscgenparser"); | ||
const fix = require("../../astfixtures.json"); | ||
@@ -5,0 +5,0 @@ const fs = require("fs"); |
@@ -6,3 +6,3 @@ const assert = require("assert"); | ||
const path = require(`path`); | ||
const parser = require("../../../parse/xuparser_node"); | ||
const parser = require("../../../parse/xuparser"); | ||
const expect = require("chai").expect; | ||
@@ -9,0 +9,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
200
290
1589439
27757