diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..104a3d9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+bower_components/
+node_modules/
+npm-debug.log
+.module-cache
+*.pyc
diff --git a/README.md b/README.md
index 0b422c6..a28c97b 100644
--- a/README.md
+++ b/README.md
@@ -4,14 +4,71 @@ cuttlefish
Human-friendly HTML rendering of machine-friendly JSON-LD
---------------------------------------------------------
-Description to come.
-
+Cuttlefish allows you to get HTML out of almost any JSON-LD data structure by providing [ReactJS](https://facebook.github.io/react/) component based on the [Schema.org](http://schema.org/) definition of entities.
What's in a name?
-----------------
Story to come.
+How do I use it?
+----------
+
+The basic compiled version allows you to visualise `Person`s, `Product`s and `Place`s. (see `index.html` example)
+
+To use it, all you need to do is :
+
+* Install cuttlefish with bower
+
+```sh
+bower install cuttlefish
+```
+
+* Insert it in your webpage (before your scripts) and insert a node in which to insert the representation
+
+```html
+
+
+
+
+
+...
+
+...
+```
+
+* Call it with your JSON-ld and the ID of your node
+
+```javascript
+cuttlefish.represent(JSONLDData, 'myJSON-LDRepresentationContainer');
+```
+
+* Check out your HTML (right-click + inspect in Google Chrome)
+
+Develop
+-------
+
+Ok, that's nice, but now, you want to put your hands in the dough.
+
+There are three ways to do that:
+
+* You want to change the style of what you see ...
+
+ * ... by modifying only certain attributes? Just create a CSS file and override the classes you want by using the ID of the container as a higher CSS specificity selector!
+
+ * ... by starting from scratch? Remove our stylesheet in the *head* tag and create your own, you will find that cuttlefish tries to follow the [SUIT CSS naming convention](https://github.com/suitcss/suit/blob/master/doc/naming-conventions.md) to make it easy for you to style.
+
+* You want to customize the HTML itself, or extend the React components for them to really do something!
+
+ * Fork this repo
+ * In the `src/es6/` folder, you will find the components: Modify them as you want!
+ * To Rebuild the all in one dist file: run `npm install && npm run build-dist`
+
+* You want to adapt cuttlefish to YOUR data structure:
+ * Put an extensive example of your JSON-LD data in the `source.json` file
+ * Run the `npm run generate-source` command
+ * Look in `src/es6` and you should have the corresponding react components in Ecma script 6 syntax. Customize them as you want and
+ * Run `npm run build` to get the new version of Cuttlefish with YOUR React components packaged. If you are happy with them, run `npm run build-dist` to generate the distribution-ready version (minified and stuff)
License
-------
@@ -31,4 +88,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-
diff --git a/bower.json b/bower.json
index db8a3b5..55fd1fd 100644
--- a/bower.json
+++ b/bower.json
@@ -1,16 +1,29 @@
{
"name": "cuttlefish",
+ "version": "0.0.2",
"description": "Human-friendly HTML rendering of machine-friendly JSON-LD. We believe in an open Internet of Things.",
+ "homepage": "https://github.com/reelyactive/cuttlefish",
"keywords": [
"JSON-LD",
"IoT"
],
"authors": [
- { "name": "Adrien Thiery" }
+ "Adrien Thiery "
],
"repository": {
"type": "git",
"url": "git://github.com/reelyactive/cuttlefish.git"
},
- "license": "MIT"
+ "license": "MIT",
+ "main": "dist/cuttlefish.min.js",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ },
+ "devDependencies": {}
}
diff --git a/dist/cuttlefish.css b/dist/cuttlefish.css
new file mode 100644
index 0000000..9bc4580
--- /dev/null
+++ b/dist/cuttlefish.css
@@ -0,0 +1,111 @@
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+
+@font-face {
+ font-family: 'EntypoRegular';
+ src: url('../font/entypo.eot');
+ src: url('../font/entypo.eot?#iefix') format('embedded-opentype'),
+ url('../font/entypo.woff') format('woff'),
+ url('../font/entypo.ttf') format('truetype'),
+ url('../font/entypo.svg#EntypoRegular') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+@font-face {
+ font-family: 'EntypoSocial';
+ src: url('../font/entypo-social.eot');
+ src: url('../font/entypo-social.eot?#iefix') format('embedded-opentype'),
+ url('../font/entypo-social.woff') format('woff'),
+ url('../font/entypo-social.ttf') format('truetype'),
+ url('../font/entypo-social.svg#entypo-social') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+img {
+ display: block;
+ max-width: 100%;
+}
+
+a {
+ color: #0770a2;
+ text-decoration: none;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+.entity {
+ border: solid 1px #ddd;
+ font-size: 0.8em;
+ padding: 5px;
+ background-color: white;
+ margin: 5px;
+ clear: both;
+}
+
+.Device + .Device {
+ margin-top: 10px;
+}
+
+/* Colored !
+.Device {
+ border-color: #FFAC71;
+ background-color: #FFDFA6;
+}
+
+.Person {
+ border-color: #BFD4FF;
+ background-color: #BFD4FF;
+}
+
+.Product {
+ border-color: #FFFF82;
+ background-color: #FFFF82;
+}
+
+.tiraid {
+ border-color: #CCCCCC;
+ background-color: #EEEEEE;
+}
+*/
+
+.clear {
+ clear: both;
+}
+
+.Person img, .Device img {
+ max-width: 8em;
+ max-height: 8em;
+ width: auto;
+ height: auto;
+ float: left;
+ margin: 5px;
+}
+
+.Person .clear, .Device .clear {
+ clear: both;
+}
+
+img.icon {
+ clear: both;
+ max-height: 2em;
+}
+
+/* Icons */
+.icon {
+ font-family: 'EntypoRegular';
+ font-size: 2em;
+ display: inline-block;
+ margin-right: 5px;
+ vertical-align: bottom;
+}
+.social {
+ font-family: 'EntypoSocial';
+}
+
diff --git a/dist/cuttlefish.js b/dist/cuttlefish.js
new file mode 100644
index 0000000..d431562
--- /dev/null
+++ b/dist/cuttlefish.js
@@ -0,0 +1,20203 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o camelize('background-color')
+ * < "backgroundColor"
+ *
+ * @param {string} string
+ * @return {string}
+ */
+function camelize(string) {
+ return string.replace(_hyphenPattern, function (_, character) {
+ return character.toUpperCase();
+ });
+}
+
+module.exports = camelize;
+},{}],4:[function(require,module,exports){
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @typechecks
+ */
+
+'use strict';
+
+var camelize = require('./camelize');
+
+var msPattern = /^-ms-/;
+
+/**
+ * Camelcases a hyphenated CSS property name, for example:
+ *
+ * > camelizeStyleName('background-color')
+ * < "backgroundColor"
+ * > camelizeStyleName('-moz-transition')
+ * < "MozTransition"
+ * > camelizeStyleName('-ms-transition')
+ * < "msTransition"
+ *
+ * As Andi Smith suggests
+ * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
+ * is converted to lowercase `ms`.
+ *
+ * @param {string} string
+ * @return {string}
+ */
+function camelizeStyleName(string) {
+ return camelize(string.replace(msPattern, 'ms-'));
+}
+
+module.exports = camelizeStyleName;
+},{"./camelize":3}],5:[function(require,module,exports){
+'use strict';
+
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ *
+ */
+
+var isTextNode = require('./isTextNode');
+
+/*eslint-disable no-bitwise */
+
+/**
+ * Checks if a given DOM node contains or is another DOM node.
+ */
+function containsNode(outerNode, innerNode) {
+ if (!outerNode || !innerNode) {
+ return false;
+ } else if (outerNode === innerNode) {
+ return true;
+ } else if (isTextNode(outerNode)) {
+ return false;
+ } else if (isTextNode(innerNode)) {
+ return containsNode(outerNode, innerNode.parentNode);
+ } else if ('contains' in outerNode) {
+ return outerNode.contains(innerNode);
+ } else if (outerNode.compareDocumentPosition) {
+ return !!(outerNode.compareDocumentPosition(innerNode) & 16);
+ } else {
+ return false;
+ }
+}
+
+module.exports = containsNode;
+},{"./isTextNode":18}],6:[function(require,module,exports){
+(function (process){
+'use strict';
+
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @typechecks
+ */
+
+var invariant = require('./invariant');
+
+/**
+ * Convert array-like objects to arrays.
+ *
+ * This API assumes the caller knows the contents of the data type. For less
+ * well defined inputs use createArrayFromMixed.
+ *
+ * @param {object|function|filelist} obj
+ * @return {array}
+ */
+function toArray(obj) {
+ var length = obj.length;
+
+ // Some browsers builtin objects can report typeof 'function' (e.g. NodeList
+ // in old versions of Safari).
+ !(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : void 0;
+
+ !(typeof length === 'number') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : void 0;
+
+ !(length === 0 || length - 1 in obj) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : void 0;
+
+ !(typeof obj.callee !== 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'toArray: Object can\'t be `arguments`. Use rest params ' + '(function(...args) {}) or Array.from() instead.') : invariant(false) : void 0;
+
+ // Old IE doesn't give collections access to hasOwnProperty. Assume inputs
+ // without method will throw during the slice call and skip straight to the
+ // fallback.
+ if (obj.hasOwnProperty) {
+ try {
+ return Array.prototype.slice.call(obj);
+ } catch (e) {
+ // IE < 9 does not support Array#slice on collections objects
+ }
+ }
+
+ // Fall back to copying key by key. This assumes all keys have a value,
+ // so will not preserve sparsely populated inputs.
+ var ret = Array(length);
+ for (var ii = 0; ii < length; ii++) {
+ ret[ii] = obj[ii];
+ }
+ return ret;
+}
+
+/**
+ * Perform a heuristic test to determine if an object is "array-like".
+ *
+ * A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
+ * Joshu replied: "Mu."
+ *
+ * This function determines if its argument has "array nature": it returns
+ * true if the argument is an actual array, an `arguments' object, or an
+ * HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
+ *
+ * It will return false for other array-like objects like Filelist.
+ *
+ * @param {*} obj
+ * @return {boolean}
+ */
+function hasArrayNature(obj) {
+ return(
+ // not null/false
+ !!obj && (
+ // arrays are objects, NodeLists are functions in Safari
+ typeof obj == 'object' || typeof obj == 'function') &&
+ // quacks like an array
+ 'length' in obj &&
+ // not window
+ !('setInterval' in obj) &&
+ // no DOM node should be considered an array-like
+ // a 'select' element has 'length' and 'item' properties on IE8
+ typeof obj.nodeType != 'number' && (
+ // a real array
+ Array.isArray(obj) ||
+ // arguments
+ 'callee' in obj ||
+ // HTMLCollection/NodeList
+ 'item' in obj)
+ );
+}
+
+/**
+ * Ensure that the argument is an array by wrapping it in an array if it is not.
+ * Creates a copy of the argument if it is already an array.
+ *
+ * This is mostly useful idiomatically:
+ *
+ * var createArrayFromMixed = require('createArrayFromMixed');
+ *
+ * function takesOneOrMoreThings(things) {
+ * things = createArrayFromMixed(things);
+ * ...
+ * }
+ *
+ * This allows you to treat `things' as an array, but accept scalars in the API.
+ *
+ * If you need to convert an array-like object, like `arguments`, into an array
+ * use toArray instead.
+ *
+ * @param {*} obj
+ * @return {array}
+ */
+function createArrayFromMixed(obj) {
+ if (!hasArrayNature(obj)) {
+ return [obj];
+ } else if (Array.isArray(obj)) {
+ return obj.slice();
+ } else {
+ return toArray(obj);
+ }
+}
+
+module.exports = createArrayFromMixed;
+}).call(this,require('_process'))
+},{"./invariant":16,"_process":27}],7:[function(require,module,exports){
+(function (process){
+'use strict';
+
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * @typechecks
+ */
+
+/*eslint-disable fb-www/unsafe-html*/
+
+var ExecutionEnvironment = require('./ExecutionEnvironment');
+
+var createArrayFromMixed = require('./createArrayFromMixed');
+var getMarkupWrap = require('./getMarkupWrap');
+var invariant = require('./invariant');
+
+/**
+ * Dummy container used to render all markup.
+ */
+var dummyNode = ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
+
+/**
+ * Pattern used by `getNodeName`.
+ */
+var nodeNamePattern = /^\s*<(\w+)/;
+
+/**
+ * Extracts the `nodeName` of the first element in a string of markup.
+ *
+ * @param {string} markup String of markup.
+ * @return {?string} Node name of the supplied markup.
+ */
+function getNodeName(markup) {
+ var nodeNameMatch = markup.match(nodeNamePattern);
+ return nodeNameMatch && nodeNameMatch[1].toLowerCase();
+}
+
+/**
+ * Creates an array containing the nodes rendered from the supplied markup. The
+ * optionally supplied `handleScript` function will be invoked once for each
+ *
+
+