diff --git a/config/demos/demos.config.js b/config/demos/demos.config.js new file mode 100644 index 00000000000..c60e09e9e44 --- /dev/null +++ b/config/demos/demos.config.js @@ -0,0 +1,51 @@ +var path = require('canonical-path'); +var _ = require('lodash'); +var staticSite = require('./static-site'); + +var projectBase = path.resolve(__dirname, '../..'); + +module.exports = function(config) { + + config = staticSite(config); + + config.merge('rendering.nunjucks.config.tags', { + variableStart: '{$', + variableEnd: '$}', + blockStart: '{%', + blockEnd: '%}' + }); + + config.set('logging.level', 'info'); + + config.set('rendering.outputFolder', path.resolve(projectBase, 'dist/ionic-demo')); + + config.set('rendering.templateFolders', [ + path.resolve(__dirname, 'templates') + ]); + config.set('rendering.templatePatterns', [ + '${ doc.template }', + '${doc.area}/${ doc.id }.${ doc.docType }.template.html', + '${doc.area}/${ doc.id }.template.html', + '${doc.area}/${ doc.docType }.template.html', + '${ doc.id }.${ doc.docType }.template.html', + '${ doc.id }.template.html', + '${ doc.docType }.template.html' + ]); + + config.append('processing.processors', [ + require('../docs/processors/version-data'), + require('./processors/demos') + ]); + + config.set('basePath', __dirname); + config.set('source.projectPath', '.'); + + config.set('source.files', [ + { pattern: 'demos/**/*.html', basePath: projectBase }, + { pattern: 'demos/**/*.js', basePath: projectBase }, + { pattern: 'demos/**/*.css', basePath: projectBase } + ]); + + + return config; +}; diff --git a/config/demos/processors/demos.js b/config/demos/processors/demos.js new file mode 100644 index 00000000000..257999bfdbe --- /dev/null +++ b/config/demos/processors/demos.js @@ -0,0 +1,99 @@ +var _ = require('lodash'); +var log = require('dgeni').log; +var path = require('canonical-path'); + +var typeTransform = { + markdown: 'md' +}; + +module.exports = { + name: 'demos', + description: 'Output demos to their files on ionic-demo website', + runAfter: ['files-read'], + runBefore: ['processing-docs'], + process: function(docs, config) { + + var contentsFolder = config.rendering.contentsFolder; + var assetOutputPath = path.join(contentsFolder, '${component}/${name}/${fileName}'); + + var pages = []; + + var demos = _(docs) + .filter('yaml') + .groupBy(function(doc) { + return doc.yaml.component + '-' + doc.yaml.name; + }) + .map(function(fragmentsForId, id) { + + var demoData = { + files: [] + }; + fragmentsForId.forEach(function(fragment) { + var doc = fragment.yaml; + if (!doc.name || !doc.component) { + log.error('Doc ' + fragment.filePath + + ' expects yaml keys "name" and "component"!'); + } + + doc.id = doc.component + '-' + doc.name; + doc.fileType = typeTransform[fragment.fileType] || fragment.fileType; + doc.fileName = fragment.fileName; + doc.contents = fragment.contents; + doc.extension = doc.fileType.replace(/^\./,''); + + doc.template = 'asset.contents.template', + doc.outputPath = _.template(assetOutputPath, doc); + + demoData.files.push(doc); + pages.push(doc); + }); + + var firstDoc = demoData.files[0]; + + var indexOutputPath = _.template(assetOutputPath, _.assign({}, firstDoc, { + fileName: 'index.html' + })); + var appOutputPath = _.template(assetOutputPath, _.assign({}, firstDoc, { + fileName: 'index-ionic-demo-app.js' + }, demoData)); + + + demoData.files = _.groupBy(demoData.files, 'extension'); + demoData.id = firstDoc.id; + demoData.name = firstDoc.name; + demoData.component = firstDoc.component; + demoData.href = '/' + _.template(assetOutputPath, _.assign({}, firstDoc, { fileName: '' })); + + pages.push({ + template: 'index.template.html', + demoData: demoData, + outputPath: indexOutputPath + }); + pages.push({ + template: 'app.template.js', + demoData: demoData, + outputPath: appOutputPath + }); + + return demoData; + + }) + .value(); + + pages.push({ + template: 'pages-data.template.js', + demos: demos, + outputPath: path.join(contentsFolder, 'pages-data.js') + }); + pages.push({ + template: 'index.template.html', + outputPath: path.join(contentsFolder, 'index.html') + }); + pages.push({ + template: 'app.template.js', + outputPath: path.join(contentsFolder, 'index-ionic-demo-app.js') + }); + + return pages; +} +}; diff --git a/config/demos/static-site/file-readers/yaml.js b/config/demos/static-site/file-readers/yaml.js new file mode 100644 index 00000000000..895ac00c8c9 --- /dev/null +++ b/config/demos/static-site/file-readers/yaml.js @@ -0,0 +1,37 @@ +var jsYaml = require('js-yaml'); +var path = require('canonical-path'); +var YAML_LINE_REGEX = /---+/; + +module.exports = { + pattern: /\.*$/, + processFile: function(filePath, contents, basePath) { + + contents = contents.trim(); + + var yamlStartMatch = contents.match(YAML_LINE_REGEX); + if (!yamlStartMatch || yamlStartMatch.index !== 0) { + return []; + } + + var yamlContents = contents.substring(yamlStartMatch.index + yamlStartMatch[0].length + 1); + + var yamlEndMatch = yamlContents.match(YAML_LINE_REGEX); + if (!yamlEndMatch) { + return []; + } + + contents = yamlContents.substring(yamlEndMatch.index + yamlEndMatch[0].length); + yamlContents = yamlContents.substring(0, yamlEndMatch.index); + + var yamlJson = jsYaml.safeLoad(yamlContents); + + return [{ + fileType: path.extname(filePath), + file: filePath, + basePath: basePath, + contents: contents, + yaml: yamlJson + }]; + } +}; + diff --git a/config/demos/static-site/index.js b/config/demos/static-site/index.js new file mode 100644 index 00000000000..be55015cdd2 --- /dev/null +++ b/config/demos/static-site/index.js @@ -0,0 +1,14 @@ +module.exports = function(config) { + + require('dgeni-packages/base')(config); + require('dgeni-packages/nunjucks')(config); + + config.append('source.fileReaders', [ + require('./file-readers/yaml') + ]); + + config.append('processing.processors', [ + ]); + + return config; +}; diff --git a/config/demos/static-site/spec/file-readers/_test-data/long-header.md b/config/demos/static-site/spec/file-readers/_test-data/long-header.md new file mode 100644 index 00000000000..d0ed28327f0 --- /dev/null +++ b/config/demos/static-site/spec/file-readers/_test-data/long-header.md @@ -0,0 +1,9 @@ + + +-------- +car: is fast +tortoise: is slow +--- + + +Some content diff --git a/config/demos/static-site/spec/file-readers/_test-data/markdown-title.md b/config/demos/static-site/spec/file-readers/_test-data/markdown-title.md new file mode 100644 index 00000000000..0e6cdb57f9a --- /dev/null +++ b/config/demos/static-site/spec/file-readers/_test-data/markdown-title.md @@ -0,0 +1,2 @@ +Here's a title +-------------- diff --git a/config/demos/static-site/spec/file-readers/_test-data/no-closing-header.md b/config/demos/static-site/spec/file-readers/_test-data/no-closing-header.md new file mode 100644 index 00000000000..84d1d6f9d49 --- /dev/null +++ b/config/demos/static-site/spec/file-readers/_test-data/no-closing-header.md @@ -0,0 +1,5 @@ +--- +something: is here + + +Hello there diff --git a/config/demos/static-site/spec/file-readers/_test-data/no-header.md b/config/demos/static-site/spec/file-readers/_test-data/no-header.md new file mode 100644 index 00000000000..ce013625030 --- /dev/null +++ b/config/demos/static-site/spec/file-readers/_test-data/no-header.md @@ -0,0 +1 @@ +hello diff --git a/config/demos/static-site/spec/file-readers/_test-data/normal-header.md b/config/demos/static-site/spec/file-readers/_test-data/normal-header.md new file mode 100644 index 00000000000..1a5973d24cd --- /dev/null +++ b/config/demos/static-site/spec/file-readers/_test-data/normal-header.md @@ -0,0 +1,6 @@ +--- +hello: world +works: true +--- + +**Here's** some content. diff --git a/config/demos/static-site/spec/file-readers/yaml.spec.js b/config/demos/static-site/spec/file-readers/yaml.spec.js new file mode 100644 index 00000000000..44103ef4d6d --- /dev/null +++ b/config/demos/static-site/spec/file-readers/yaml.spec.js @@ -0,0 +1,35 @@ +var fs = require('fs'); +var path = require('canonical-path'); +var processor = require('../../file-readers/yaml'); + +describe('yaml file-reader', function() { + + function readTestFile(name) { + return fs.readFileSync(path.resolve(__dirname, '_test-data', name)).toString(); + } + + it('normal yaml header should process', function() { + var contents = readTestFile('normal-header.md'); + + var result = processor.processFile('some/file.md', contents); + expect(result.contents.trim()).toEqual('**Here\'s** some content.'); + expect(result.yaml).toEqual({hello: 'world', works: true}); + }); + + it('long yaml header should process', function() { + var contents = readTestFile('long-header.md'); + + var result = processor.processFile('cool/file.md', contents); + expect(result.contents.trim()).toEqual('Some content'); + expect(result.yaml).toEqual({car: 'is fast', tortoise: 'is slow'}); + }); + + ['markdown-title.md', 'no-closing-header.md', 'no-header.md'].forEach(function(file) { + it(file + ' should not be processed', function() { + var contents = readTestFile(file); + var result = processor.processFile('cool/file.md', contents); + expect(result).toBeFalsy(); + }); + }); + +}); diff --git a/config/dgeni/templates/demo/app.template.js b/config/demos/templates/app.template.js similarity index 64% rename from config/dgeni/templates/demo/app.template.js rename to config/demos/templates/app.template.js index 4771ed335b1..a6e490d05fc 100644 --- a/config/dgeni/templates/demo/app.template.js +++ b/config/demos/templates/app.template.js @@ -1,14 +1,14 @@ var DEMO; -<@ if doc.demoData @> - DEMO = <$ doc.demoData | json $>; -<@ endif @> +{% if doc.demoData %} + DEMO = {$ doc.demoData | json $}; +{% endif %} -angular.module(<@ if doc.demoData @>'<$ doc.demoData.module $>' - <@ else @>'demoApp', ['ionic']<@ endif @>) +angular.module({% if doc.demoData %}'{$ doc.demoData.name $}' + {% else %}'demoApp', ['ionic']{% endif %}) .controller('IonicDemoCtrl', function($scope, $ionicModal, $ionicLoading) { $scope.$demos = DEMOS; - <@ if doc.demoData @> + {% if doc.demoData %} $scope.$demo = DEMO; $ionicModal.fromTemplateUrl('ionic-demo-modal.html', { scope: $scope, @@ -30,34 +30,40 @@ angular.module(<@ if doc.demoData @>'<$ doc.demoData.module $>' var form = angular.element('