Browse files

Initial commit

  • Loading branch information...
0 parents commit 8abe589366a7214bf668f8ac0c0cfae6ee8cc00b @dotcypress committed Mar 15, 2013
Showing with 209 additions and 0 deletions.
  1. +10 −0 .editorconfig
  2. +1 −0 .gitattributes
  3. +15 −0 .gitignore
  4. +6 −0 .travis.yml
  5. +20 −0 LICENSE
  6. +4 −0 README.md
  7. +4 −0 index.js
  8. +1 −0 lib/engine.coffee
  9. +61 −0 lib/parser.coffee
  10. +39 −0 package.json
  11. +48 −0 test/parser-tests.coffee
10 .editorconfig
@@ -0,0 +1,10 @@
+# editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
1 .gitattributes
@@ -0,0 +1 @@
+* text=auto
15 .gitignore
@@ -0,0 +1,15 @@
+lib-cov
+*.seed
+*.log
+*.csv
+*.dat
+*.out
+*.pid
+*.gz
+
+pids
+logs
+results
+node_modules
+
+npm-debug.log
6 .travis.yml
@@ -0,0 +1,6 @@
+language: node_js
+node_js:
+ - 0.8
+branches:
+ only:
+ - master
20 LICENSE
@@ -0,0 +1,20 @@
+The MIT License
+
+Copyright (C) 2011-2013 Vojta Jína and contributors.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 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.
4 README.md
@@ -0,0 +1,4 @@
+AIML [![Build Status](https://secure.travis-ci.org/dotCypress/aiml.png?branch=master)](https://travis-ci.org/dotCypress/aiml)
+=====
+
+[Artificial Intelligence Markup Language](http://en.wikipedia.org/wiki/AIML "Artificial Intelligence Markup Language") lib for Node.js
4 index.js
@@ -0,0 +1,4 @@
+require('coffee-script');
+module.exports.Engine = require('./lib/engine');
+module.exports.parse = require('./lib/parser').parse;
+module.exports.parseFile = require('./lib/parser').parseFile;
1 lib/engine.coffee
@@ -0,0 +1 @@
+
61 lib/parser.coffee
@@ -0,0 +1,61 @@
+fs = require 'fs'
+path = require 'path'
+_ = require 'underscore'
+async = require 'async'
+DomJS = require("dom-js").DomJS
+engine = require './engine'
+
+parse = (xml, cb) ->
+ return cb 'Xml not defined' if not xml
+ domjs = new DomJS()
+ domjs.parse xml, (err, dom) ->
+ return cb err if err
+ return cb 'Unsupported file' if dom.name is not 'aiml'
+ topics = parseTopics dom
+ topCategories = parseCategories dom
+ topics.unshift { name: 'Default', categories: topCategories } if topCategories.length > 0
+ cb null, topics
+
+parseFile = (file, cb) ->
+ cb null, null
+
+parseTopics = (node) ->
+ topics = _.filter node.children, (child) -> child.name is 'topic'
+ _.map topics, parseTopic
+
+parseTopic = (node) ->
+ name: node.attributes.name
+ categories: parseCategories node
+
+parseCategories = (node) ->
+ categories = _.filter node.children, (child) -> child.name is 'category'
+ _.map categories, parseCategory
+
+parseCategory = (node) ->
+ pattern = _.find node.children, (child) -> child.name is 'pattern'
+ that = _.find node.children, (child) -> child.name is 'that'
+ templates = _.filter node.children, (child) -> child.name is 'template'
+ pattern: parseMixedPatternExpression pattern
+ that: parseMixedPatternExpression that if that
+ templates: _.map templates, parseMixedTemplateContentContainer
+
+parseMixedPatternExpression = (node) ->
+ return undefined if not node
+ trim _.reduce node.children, ((acc, next) -> "#{acc}#{parsePatternExpression next} "), ''
+
+parseMixedTemplateContentContainer = (node) ->
+ return undefined if not node
+ trim _.reduce node.children, ((acc, next) -> "#{acc}#{parseTemplateExpression next} "), ''
+
+parsePatternExpression = (node) ->
+ # TODO: implement
+ node.text
+
+parseTemplateExpression = (node) ->
+ # TODO: implement
+ node.text
+
+trim = (string) -> string.replace /^\s+|\s+$/g, ''
+
+module.exports.parse = parse
+module.exports.parseFile = parseFile
39 package.json
@@ -0,0 +1,39 @@
+{
+ "name": "aiml",
+ "version": "0.0.1",
+ "description": "Artificial Intelligence Markup Language lib for Node.js",
+ "keywords": [
+ "aiml",
+ "ai",
+ "parser"
+ ],
+ "homepage": "https://github.com/dotCypress/aiml",
+ "bugs": "https://github.com/dotCypress/aiml/issues",
+ "author": "Vitaly Domnikov <dotcypress@gmail.com>",
+ "main": "index.js",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/dotCypress/aiml.git"
+ },
+ "scripts": {
+ "test": "mocha --reporter spec --compilers coffee:coffee-script"
+ },
+ "dependencies": {
+ "coffee-script": "~1.6.1",
+ "underscore": "~1.4.4",
+ "async": "~0.2.6",
+ "dom-js": "~0.0.9"
+ },
+ "devDependencies": {
+ "mocha": "~1.8.1",
+ "chai": "~1.5.0"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ },
+ "licenses": [
+ {
+ "type": "MIT"
+ }
+ ]
+}
48 test/parser-tests.coffee
@@ -0,0 +1,48 @@
+should = require('chai').should()
+parse = require('./../index').parse
+parseFile = require('./../index').parseFile
+
+describe 'AIML parser', () ->
+
+ it 'should not parse empty string', (done) ->
+ parse '', (err, topics) ->
+ should.exist err
+ done()
+
+ it 'should parse simple category', (done) ->
+ xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+ <aiml version=\"1.0\">
+ <category>
+ <pattern>WHAT IS YOUR NAME</pattern>
+ <template><![CDATA[My name is Jonny.]]></template>
+ </category>
+ </aiml>"
+ parse xml, (err, topics) ->
+ should.not.exist err
+ topics.should.have.length 1
+ topics[0].categories.should.have.length 1
+ topics[0].categories[0].pattern.should.equal 'WHAT IS YOUR NAME'
+ topics[0].categories[0].templates[0].should.equal 'My name is Jonny.'
+ done()
+
+ it 'should parse simple topic', (done) ->
+ xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+ <aiml version=\"1.0\">
+ <category>
+ <pattern>WHAT IS YOUR NAME</pattern>
+ <that>bot</that>
+ <template><![CDATA[My name is Jonny.]]></template>
+ </category>
+ <topic name=\"Development\">
+ <category>
+ <pattern>WHAT IS YOUR PREFFERED PROGRAMMING LANGUAGE</pattern>
+ <template>My name is <bot name=\"name\"/> and i prefer F#.</template>
+ </category>
+ </topic>
+ </aiml>"
+ parse xml, (err, topics) ->
+ should.not.exist err
+ topics.should.have.length 2
+ topics[1].name.should.equal 'Development'
+ topics[1].categories[0].pattern.should.equal 'WHAT IS YOUR PREFFERED PROGRAMMING LANGUAGE'
+ done()

0 comments on commit 8abe589

Please sign in to comment.