You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by db...@apache.org on 2015/07/24 00:21:04 UTC

[60/75] docs commit: Moved tools to tools/ and added some tools for new doc pipeline.

http://git-wip-us.apache.org/repos/asf/cordova-docs/blob/5f554950/tools/lib/docs_generator.js
----------------------------------------------------------------------
diff --git a/tools/lib/docs_generator.js b/tools/lib/docs_generator.js
new file mode 100644
index 0000000..8ea7a20
--- /dev/null
+++ b/tools/lib/docs_generator.js
@@ -0,0 +1,256 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+/*jslint node: true */
+var fs = require("fs-extra");
+var path = require("path");
+var JoDoc = require("./cordova/jodoc");
+var FileHelpers = require("./file_helpers");
+
+var DocsGenerator = (function () {
+    'use strict';
+
+    function processEachFile(source_path, callback) {
+        var directoryEntries = fs.readdirSync(source_path);
+        directoryEntries.forEach(function (dirEntry) {
+            var fullPath = path.join(source_path, dirEntry),
+                stat;
+            if (!fs.existsSync(fullPath)) {
+                return;
+            }
+
+            stat = fs.lstatSync(fullPath);
+            if (stat.isFile()) {
+                callback(fullPath);
+                return;
+            }
+
+            if (stat.isDirectory()) {
+                processEachFile(fullPath, callback);
+                return;
+            }
+        });
+    }
+
+    /**
+    * Creates a new instance of DocsGenerator
+    * @param inputDirectory Directory which contains files which has to be processed.
+    * @param outputDirectory Directory to which store generated files.
+    */
+    function DocsGenerator(inputDirectory, outputDirectory) {
+        this.input_directory = path.resolve(inputDirectory || FileHelpers.getDefaultInputDirectory());
+        this.output_directory = path.resolve(outputDirectory || FileHelpers.getDefaultOutputDirectory());
+        this.working_directory = path.join(FileHelpers.getTmpDirectory(), 'docs');
+    }
+
+    /* Cordova Build-Time Steps
+    * - For each version of the documentation
+    *   - Create a work space for the docs processing
+    *   - Pre-file processing
+    *   - Run joDoc
+    *   - Pre-file processing
+    *   - Release and cleanup
+    */
+    DocsGenerator.prototype.run = function (language, version, verbose_mode, timing) {
+        var self = this,
+            ignore_list = ['.', '..', '.DS_Store'];
+
+        verbose_mode = verbose_mode || 0;
+        if (verbose_mode > 0) {
+            console.log("Generating docs for lang " + language + " and version " + version);
+            // console.log("Clearing output directory");
+            if (verbose_mode > 1) {
+                console.log("Sources directory: " + this.input_directory);
+                console.log("Output directory: " + this.output_directory);
+            }
+        }
+
+        // fs.removeSync(this.output_directory);
+
+        self.options = {
+            verbose: verbose_mode,
+            timing: timing
+        };
+        self.captureExecutionTime("Generate all docs", 0, function () {
+            fs.readdirSync(this.input_directory).forEach(function (language_dir) {
+                if (ignore_list.indexOf(language_dir) !== -1) {
+                    return;
+                }
+
+                if (language && language_dir !== language) {
+                    return;
+                }
+
+                var language_path = path.join(self.input_directory, language_dir);
+
+                fs.readdirSync(language_path).forEach(function (version_dir) {
+                    if (ignore_list.indexOf(version_dir) !== -1) {
+                        return;
+                    }
+
+                    if (version && version_dir !== version) {
+                        return;
+                    }
+
+                    var output_path = path.join(self.output_directory, language_dir, version_dir),
+                        input_path = path.join(self.input_directory, language_dir, version_dir),
+                        options = {
+                            lang: language_dir,
+                            version: version_dir,
+                            verbose: verbose_mode,
+                            timing: timing
+                        };
+                    self.options = options;
+                    console.log(" => Generating the Cordova Documentation for " + version_dir + "-" + language_dir + "...");
+                    self.captureExecutionTime("Generate docs for " + version_dir + "-" + language_dir, 0, function () {
+                        try {
+                            self.process(input_path, output_path, options);
+                        } catch (e) {
+                            console.warn("=================================================");
+                            console.warn("ERROR: Generating the Cordova Documentation for " + version_dir + "-" + language_dir + " failed.");
+                            console.warn(e.stack || e.toString());
+                            console.warn("=================================================");
+                        }
+                    });
+                    self.options = {
+                        verbose: verbose_mode,
+                        timing: timing
+                    };
+                });
+            });
+        });
+    };
+
+    DocsGenerator.prototype.process = function (input_path, output_path, options) {
+        if (options.verbose > 0) {
+            console.log("Clearing output directory for lang " + options.lang + " and version " + options.version);
+            if (options.verbose > 1) {
+                console.log("Output directory: " + output_path);
+            }
+        }
+        
+        this.captureExecutionTime("Removing lang output directory", 1, function () {
+            fs.removeSync(output_path);
+        });
+        this.captureExecutionTime("Copy source files to temp", 1, function () {
+            fs.copySync(input_path, this.working_directory);
+        });
+        
+        var preprocessPath,
+            processPath,
+            generated_path;
+        this.captureExecutionTime("Pre processing docs", 1, function () {
+            preprocessPath = this.before_jodoc(this.working_directory, options);
+        });
+        this.captureExecutionTime("joDoc-ify", 1, function () {
+            processPath = this.jodocify(preprocessPath, options);
+        });
+        this.captureExecutionTime("Post processing docs", 1, function () {
+            generated_path = this.after_jodoc(processPath, options);
+        });
+        
+        this.captureExecutionTime("Moving to results folder", 1, function () {
+            fs.ensureDirSync(path.dirname(output_path));
+            fs.renameSync(generated_path, output_path);
+            fs.removeSync(FileHelpers.getTmpDirectory());
+        });
+    };
+
+    DocsGenerator.prototype.run_process_sequence = function (sequence_name, source_path, options) {
+        var self = this,
+            currentModuleDir = path.dirname(module.filename),
+            directoryEntries,
+            sequenceProcessors,
+            processors;
+        directoryEntries = fs.readdirSync(path.join(currentModuleDir, "cordova", sequence_name));
+        sequenceProcessors = require("./cordova/" + sequence_name + "/index");
+        processors = sequenceProcessors.map(function (ProcessorConstructor) {
+            return new ProcessorConstructor(options);
+        });
+        processors.forEach(function (process_module) {
+            self.captureExecutionTime("Processor: " + process_module.stage, 1, function () {
+                if (options.verbose > 0) {
+                    console.log("Stage: " + process_module.stage);
+                }
+
+                processEachFile(source_path, function (filename) {
+                    self.captureExecutionTime("File: " + filename, 2, function () {
+                        process_module.run(filename);
+                    });
+                });
+            });
+        });
+
+        return source_path;
+    };
+
+    DocsGenerator.prototype.before_jodoc = function (source_path, options) {
+        this.run_process_sequence("pre", source_path, options);
+
+        return source_path;
+    };
+
+    DocsGenerator.prototype.jodocify = function (source_path, options) {
+        var output_directory = path.join(FileHelpers.getTmpDirectory(), 'jodoc');
+
+        new JoDoc(source_path, output_directory, options).run();
+        fs.ensureDirSync(output_directory);
+
+        return output_directory;
+    };
+
+    DocsGenerator.prototype.after_jodoc = function (source_path, options) {
+        this.run_process_sequence("post", source_path, options);
+        return source_path;
+    };
+    
+    DocsGenerator.prototype.captureExecutionTime = function (step_name, level, callback) {
+        var startDate,
+            finishDate,
+            timingLevel = -1,
+            secondsPassed;
+        if (this.options.timing) {
+            if (this.options.timing === true) {
+                timingLevel = 0;
+            } else {
+                timingLevel = this.options.timing;
+            }
+        }
+        
+        if (timingLevel >= level) {
+            startDate = new Date();
+            if (this.options.verbose > 0) {
+                console.log(startDate, "Start " + step_name);
+            }
+        }
+        
+        callback.apply(this);
+        if (timingLevel >= level) {
+            finishDate = new Date();
+            if (this.options.verbose > 0) {
+                console.log(finishDate, "Finish " + step_name);
+            }
+            
+            secondsPassed = (finishDate.valueOf() - startDate.valueOf()) / 1000;
+            console.log(step_name + ". Total time: ", secondsPassed);
+        }
+    };
+
+    return DocsGenerator;
+}());
+module.exports = DocsGenerator;

http://git-wip-us.apache.org/repos/asf/cordova-docs/blob/5f554950/tools/lib/docs_validator.js
----------------------------------------------------------------------
diff --git a/tools/lib/docs_validator.js b/tools/lib/docs_validator.js
new file mode 100644
index 0000000..cb04b38
--- /dev/null
+++ b/tools/lib/docs_validator.js
@@ -0,0 +1,535 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+/*jslint node: true, continue:true */
+/*global setImmediate*/
+var fs = require("fs-extra");
+var path = require("path");
+var JoDoc = require("./cordova/jodoc");
+var FileHelpers = require("./file_helpers");
+var cheerio = require('cheerio');
+var jsdiff = require('diff'),
+    yaml = require("js-yaml"),
+    dir = require("node-dir");
+require('colors');
+
+var DocsValidator = (function () {
+    'use strict';
+
+    function processEachFileSync(source_path, fileCallback, directoryCallback) {
+        var directoryEntries = fs.readdirSync(source_path);
+        directoryEntries.forEach(function (dirEntry) {
+            var fullPath = path.join(source_path, dirEntry),
+                stat;
+            if (!fs.existsSync(fullPath)) {
+                return;
+            }
+
+            stat = fs.lstatSync(fullPath);
+            if (stat.isFile()) {
+                fileCallback(fullPath);
+                return;
+            }
+
+            if (stat.isDirectory()) {
+                if (directoryCallback(fullPath)) {
+                    processEachFileSync(fullPath, fileCallback, directoryCallback);
+                }
+
+                return;
+            }
+        });
+    }
+
+    function processEachFile(source_path, fileCallback, directoryCallback, errorCallback) {
+        fs.readdirSync(source_path, function (err, directoryEntries) {
+            if (err) {
+                errorCallback(err);
+                return;
+            }
+
+            directoryEntries.forEach(function (dirEntry) {
+                var fullPath = path.join(source_path, dirEntry);
+                fs.exists(fullPath, function (exists) {
+                    if (!exists) {
+                        return;
+                    }
+
+                    fs.lstat(fullPath, function (err, stat) {
+                        if (err) {
+                            errorCallback(err);
+                            return;
+                        }
+
+                        if (stat.isFile()) {
+                            fileCallback(fullPath);
+                            return;
+                        }
+
+                        if (stat.isDirectory()) {
+                            if (directoryCallback(fullPath)) {
+                                processEachFile(fullPath, fileCallback, directoryCallback, errorCallback);
+                            }
+
+                            return;
+                        }
+                    });
+                });
+            });
+        });
+    }
+
+    /**
+    * Creates a new instance of DocsValidator
+    * @param inputDirectory Directory which contains files which has to be processed.
+    */
+    function DocsValidator(originalDirectory) {
+        this.original_directory = originalDirectory || path.join(FileHelpers.getRootDirectory(), "docs");
+    }
+
+    /**
+    * Validates the specific version of documentation
+    * @param language Language which has to be validated.
+    * @param version Version which files has to be validated.
+    * @param verbose_mode Verbosity level.
+    */
+    DocsValidator.prototype.validate = function (language, version, verbose_mode) {
+        var self = this,
+            ignore_list = ['.', '..', '.DS_Store', 'test'];
+
+        verbose_mode = verbose_mode || 0;
+        if (verbose_mode > 0) {
+            console.log("Comparing docs for lang " + language + " and version " + version);
+            console.log("Clearing output directory");
+        }
+
+        fs.readdirSync(this.original_directory).forEach(function (language_dir) {
+            if (ignore_list.indexOf(language_dir) !== -1) {
+                return;
+            }
+
+            if (language && language_dir !== language) {
+                return;
+            }
+
+            var language_path = path.join(self.original_directory, language_dir);
+
+            fs.readdirSync(language_path).forEach(function (version_dir) {
+                if (ignore_list.indexOf(version_dir) !== -1) {
+                    return;
+                }
+
+                if (version && version_dir !== version) {
+                    return;
+                }
+
+                var input_path = path.join(self.original_directory, language_dir, version_dir),
+                    options = {
+                        lang: language_dir,
+                        version: version_dir,
+                        verbose: verbose_mode
+                    };
+
+                console.log(" => Validating the Cordova Documentation for " + version_dir + "-" + language_dir + "...");
+                self.process(input_path, options);
+            });
+        });
+    };
+
+    /**
+    * Validates the specific version of documentation
+    * @param outputDirectory Directory where documentation is stored.
+    * @param language Language which has to be validated.
+    * @param version Version which files has to be validated.
+    * @param verbose_mode Verbosity level.
+    */
+    DocsValidator.prototype.validateTranslation = function (docsDirectory, language, version, verbose_mode) {
+        var self = this,
+            outputDirectory = path.resolve(docsDirectory || FileHelpers.getDefaultOutputDirectory()),
+            ignore_list = ['.', '..', '.DS_Store', 'test'];
+        
+        verbose_mode = verbose_mode || 0;
+        if (verbose_mode > 0) {
+            console.log("Comparing docs for lang " + language + " and version " + version);
+            console.log("Clearing output directory");
+        }
+
+        fs.readdirSync(outputDirectory).forEach(function (language_dir) {
+            if (ignore_list.indexOf(language_dir) !== -1) {
+                return;
+            }
+
+            if (language && language_dir !== language) {
+                return;
+            }
+
+            var language_path = path.join(outputDirectory, language_dir);
+
+            fs.readdirSync(language_path).forEach(function (version_dir) {
+                if (ignore_list.indexOf(version_dir) !== -1) {
+                    return;
+                }
+
+                if (version && version_dir !== version) {
+                    return;
+                }
+
+                var input_path = path.join(outputDirectory, language_dir, version_dir),
+                    source_path = path.join(outputDirectory, "en", version_dir),
+                    options = {
+                        lang: language_dir,
+                        version: version_dir,
+                        verbose: verbose_mode
+                    };
+
+                console.log(" => Validating translation for version " + version_dir + " on language " + language_dir + "...");
+                self.doValidateTranslation(source_path, input_path, options);
+            });
+        });
+    };
+    DocsValidator.prototype.doValidateTranslation = function (original_directory, comparing_directory, options) {
+        var self = this,
+            compareFiles,
+            completed;
+        console.log("Comparing " + original_directory);
+        console.log("with " + comparing_directory);
+        completed = false;
+        dir.readFiles(original_directory,
+            { match: /\.html/ },
+            function (err, content, filename, next) {
+                if (err) {
+                    throw err;
+                }
+
+                var relativePath = path.relative(original_directory, filename),
+                    alternativeFile = path.join(comparing_directory, relativePath),
+                    $ = cheerio.load(alternativeFile);
+                fs.readFile(alternativeFile, function (err, data) {
+                    if (err) {
+                        throw err;
+                    }
+
+                    var target = cheerio.load(data),
+                        source = cheerio.load(content);
+
+                    self.validateLinksStructure(relativePath, source, target, options);
+                    self.validateDomStructure(relativePath, source, target, options);
+                    next();
+                });
+            },
+            function (err, files) {
+                if (err) {
+                    throw err;
+                }
+
+                completed = true;
+            });
+        function waitCompletition() {
+            if (!completed) {
+                setImmediate(waitCompletition);
+            }
+        }
+
+        setImmediate(waitCompletition);
+    };
+    DocsValidator.prototype.process = function (original_directory, options) {
+        var self = this,
+            compareFiles,
+            completed;
+        console.log("Processing " + original_directory);
+        compareFiles = function (fileName) {
+            self.validateYaml(fileName, options);
+        };
+        completed = false;
+        dir.readFiles(original_directory,
+            { match: /\.md$/ },
+            function (err, content, filename, next) {
+                if (err) {
+                    throw err;
+                }
+
+                self.validateYaml(filename, content, options);
+                next();
+            },
+            function (err, files) {
+                if (err) {
+                    throw err;
+                }
+
+                completed = true;
+            });
+        function waitCompletition() {
+            if (!completed) {
+                setImmediate(waitCompletition);
+            }
+        }
+
+        setImmediate(waitCompletition);
+    };
+
+    DocsValidator.prototype.validateDomStructure = function (relativePath, source, target, options) {
+        var sourceDom = source("#content"),
+            targetDom = target("#content"),
+            sourceDomList = "",
+            targetDomList = "",
+            changes,
+            changed = false;
+        function convertSource(element, initial, offset) {
+            var i,
+                child;
+            if (element.children === undefined) {
+                console.log(element);
+            }
+
+            for (i = 0; i < element.children.length; i += 1) {
+                child = element.children[i];
+                if (child.type !== 'tag') {
+                    continue;
+                }
+
+                initial += offset + child.name + "\r\n";
+                initial = convertSource(child, initial, ' ' + offset);
+            }
+
+            return initial;
+        }
+        sourceDomList = convertSource(sourceDom[0], '', '');
+        targetDomList = convertSource(targetDom[0], '', '');
+        if (sourceDomList !== targetDomList) {
+            console.error("Path " + relativePath + " has different dom structure.");
+            if (options.verbose > 0) {
+                //console.log(jsdiff.createPatch(relativePath, sourceDomList, targetDomList, '', ''));
+                changes = jsdiff.diffLines(sourceDomList, targetDomList);
+                if (options.verbose > 0) {
+                    changes.forEach(function (part) {
+                        // green for additions, red for deletions
+                        // grey for common parts
+                        var color = part.added ? 'green' : (part.removed ? 'red' : 'grey');
+                        process.stderr.write(part.value[color]);
+                    });
+
+                    console.log();
+                }
+            }
+        }
+    };
+
+    DocsValidator.prototype.validateLinksStructure = function (relativePath, source, target, options) {
+        // Skip _index.html since it will have links in the different
+        // order, not as in the original docs, since each word
+        // will be translated to different languages.
+        if (relativePath === "_index.html") {
+            return;
+        }
+
+        var sourceLinks = source("#content a"),
+            targetLinks = target("#content a"),
+            sourceLinksList = "",
+            targetLinksList = "",
+            changes,
+            changed = false;
+        sourceLinks.each(function (i, a) {
+            var link = a.attribs.href || "";
+            link = link.split('#')[0];
+            if (link) {
+                sourceLinksList += link + "\n";
+            }
+        });
+        targetLinks.each(function (i, a) {
+            var link = a.attribs.href || "";
+            link = link.split('#')[0];
+            if (link) {
+                targetLinksList += link + "\n";
+            }
+        });
+        changes = jsdiff.diffLines(sourceLinksList, targetLinksList);
+        changes.forEach(function (part) {
+            changed = part.added || part.removed;
+        });
+        if (changed) {
+            console.error("Path " + relativePath + " has different links.");
+            if (options.verbose > 0) {
+                changes.forEach(function (part) {
+                    // green for additions, red for deletions
+                    // grey for common parts
+                    var color = part.added ? 'green' : (part.removed ? 'red' : 'grey');
+                    process.stderr.write(part.value[color]);
+                });
+
+                console.log();
+            }
+        }
+    };
+    
+    DocsValidator.prototype.validateYaml = function (sourceFile, content, options) {
+        if (options.verbose > 0) {
+            console.log("Validate " + sourceFile);
+        }
+
+        var yamlRegexStripper = /^(---\s*\n[\s\S]*?\n?)^(---\s*$\n?)/m,
+            match = yamlRegexStripper.exec(content);
+
+        if (!match) {
+            console.log("File " + sourceFile + " miss the YAML license header");
+            return 1;
+        } else {
+            if (match[1].indexOf("license:") === -1) {
+                console.log("File " + sourceFile + " has invalid YAML license header");
+                return 2;
+            }
+        }
+
+        return 0;
+    };
+
+    /**
+    * Validates the specific version of documentation
+    * @param outputDirectory Directory where documentation is stored.
+    * @param language Language which has to be validated.
+    * @param version Version which files has to be validated.
+    * @param verbose_mode Verbosity level.
+    */
+    DocsValidator.prototype.fixYamlHeader = function (docsDirectory, language, version, verbose_mode) {
+        var self = this,
+            outputDirectory = path.resolve(docsDirectory || FileHelpers.getDefaultInputDirectory()),
+            ignore_list = ['.', '..', '.DS_Store', 'test'];
+
+        verbose_mode = verbose_mode || 0;
+        if (verbose_mode > 0) {
+            console.log("Fixing YAML headers for lang " + language + " and version " + version);
+            console.log("Clearing output directory");
+        }
+
+        fs.readdirSync(outputDirectory).forEach(function (language_dir) {
+            if (ignore_list.indexOf(language_dir) !== -1) {
+                return;
+            }
+
+            if (language && language_dir !== language) {
+                return;
+            }
+
+            var language_path = path.join(outputDirectory, language_dir);
+
+            fs.readdirSync(language_path).forEach(function (version_dir) {
+                if (ignore_list.indexOf(version_dir) !== -1) {
+                    return;
+                }
+
+                if (version && version_dir !== version) {
+                    return;
+                }
+
+                var input_path = path.join(outputDirectory, language_dir, version_dir),
+                    options = {
+                        lang: language_dir,
+                        version: version_dir,
+                        verbose: verbose_mode
+                    };
+
+                console.log(" => Fix YAML header for version " + version_dir + " on language " + language_dir + "...");
+                self.doFixYamlHeader(input_path, options);
+            });
+        });
+    };
+    DocsValidator.prototype.doFixYamlHeader = function (lang_directory, options) {
+        var self = this,
+            compareFiles,
+            completed;
+        console.log("Fixing " + lang_directory);
+        completed = false;
+        dir.readFiles(lang_directory,
+            { match: /\.md/ },
+            function (err, content, filename, next) {
+                if (err) {
+                    throw err;
+                }
+
+                var relativePath = path.relative(lang_directory, filename);
+                fs.readFile(filename, 'utf8', function (err, data) {
+                    if (err) {
+                        throw err;
+                    }
+
+                    var target = data,
+                        validationResult = self.validateYaml(filename, content, options),
+                        yamlReplaceRegex1,
+                        yamlReplaceRegex2,
+                        eol = require('os').type() === 'win32' ? "\r\n" : "\n",
+                        prefix = "         ",
+                        correctLicense = '---' + eol +
+                            "license: Licensed to the Apache Software Foundation (ASF) under one" + eol +
+                            prefix + "or more contributor license agreements.  See the NOTICE file" + eol +
+                            prefix + "distributed with this work for additional information" + eol +
+                            prefix + "regarding copyright ownership.  The ASF licenses this file" + eol +
+                            prefix + "to you under the Apache License, Version 2.0 (the" + eol +
+                            prefix + "\"License\"); you may not use this file except in compliance" + eol +
+                            prefix + "with the License.  You may obtain a copy of the License at" + eol +
+                            eol +
+                            prefix + "  http://www.apache.org/licenses/LICENSE-2.0" + eol +
+                            eol +
+                            prefix + "Unless required by applicable law or agreed to in writing," + eol +
+                            prefix + "software distributed under the License is distributed on an" + eol +
+                            prefix + "\"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY" + eol +
+                            prefix + "KIND, either express or implied.  See the License for the" + eol +
+                            prefix + "specific language governing permissions and limitations" + eol +
+                            prefix + "under the License." + eol +
+                            '---' + eol + eol;
+
+                    if (validationResult !== 0) {
+                        yamlReplaceRegex1 = /^(\* \* \*\s*\n[\s\S]*?\n?)^(\#\# (under the License\.|unter der Lizenz\.|по лицензии\.|aux termes de la licence\.|con la licenza\.|ライセンス。|라이센스\.|根據許可證。)\s*$\n?)/m;
+                        if (yamlReplaceRegex1.exec(content)) {
+                            content = correctLicense + content.replace(yamlReplaceRegex1, '');
+                        } else {
+                            yamlReplaceRegex2 = /^(\* \* \*\s*\n[\s\S]*?\n?)^(\* \* \*\s*\s*$\n?)/m;
+                            if (yamlReplaceRegex2.exec(content)) {
+                                content = correctLicense + content.replace(yamlReplaceRegex2, '');
+                            }
+                        }
+
+                        fs.writeFile(filename, content, 'utf8', function (err, data) {
+                            if (err) {
+                                throw err;
+                            }
+
+                            next();
+                        });
+                    } else {
+                        next();
+                    }
+                });
+            },
+            function (err, files) {
+                if (err) {
+                    throw err;
+                }
+
+                completed = true;
+            });
+        function waitCompletition() {
+            if (!completed) {
+                setImmediate(waitCompletition);
+            }
+        }
+
+        setImmediate(waitCompletition);
+    };
+
+    return DocsValidator;
+}());
+module.exports = DocsValidator;

http://git-wip-us.apache.org/repos/asf/cordova-docs/blob/5f554950/tools/lib/file_helpers.js
----------------------------------------------------------------------
diff --git a/tools/lib/file_helpers.js b/tools/lib/file_helpers.js
new file mode 100644
index 0000000..078c0cd
--- /dev/null
+++ b/tools/lib/file_helpers.js
@@ -0,0 +1,59 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+/*jslint node: true */
+var fs = require("fs-extra");
+var path = require("path");
+
+var FileHelpers = (function () {
+    'use strict';
+
+    var FileHelpers = {};
+
+    /**
+    * Gets default directory for source files.
+    */
+    FileHelpers.getDefaultInputDirectory = function () {
+        return path.join(FileHelpers.getRootDirectory(), "docs");
+    };
+
+    /**
+    * Gets default directory for final output.
+    * @remarks Right now used non default folder, to not mix with Ruby implementation.
+    */
+    FileHelpers.getDefaultOutputDirectory = function () {
+        return path.join(FileHelpers.getRootDirectory(), "public");
+    };
+
+    /**
+    * Gets temporary directory, where files will be processed.
+    */
+    FileHelpers.getTmpDirectory = function () {
+        return path.join(FileHelpers.getRootDirectory(), "tmp");
+    };
+
+    /**
+    * Gets absolute path for the Cordova Docs root directory
+    */
+    FileHelpers.getRootDirectory = function () {
+        return path.resolve(path.join(path.dirname(module.filename), ".."));
+    };
+
+    return FileHelpers;
+}());
+module.exports = FileHelpers;

http://git-wip-us.apache.org/repos/asf/cordova-docs/blob/5f554950/tools/spec/cordova/add_title_spec.js
----------------------------------------------------------------------
diff --git a/tools/spec/cordova/add_title_spec.js b/tools/spec/cordova/add_title_spec.js
new file mode 100644
index 0000000..9219d01
--- /dev/null
+++ b/tools/spec/cordova/add_title_spec.js
@@ -0,0 +1,70 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+/*jslint node: true */
+/*global describe, it, beforeEach, afterEach, after, before */
+(function () {
+    'use strict';
+    var assert = require("assert"),
+        path = require('path'),
+        fs = require('fs'),
+        cheerio = require('cheerio'),
+        AddTitle = require("../../lib/cordova/post/addtitle"),
+        SpecHelpers = require("../spec_helpers");
+
+    describe('AddTitle', function () {
+        var sut,
+            files;
+        
+        before(function (done) {
+            var tmp_directory = SpecHelpers.create_tmp_directory_assets(module.filename);
+            sut = new AddTitle();
+            files = {
+                'normal': path.join(tmp_directory, 'example.html'),
+                'no_source': path.join(tmp_directory, 'example_no_source.html'),
+                'no_target': path.join(tmp_directory, 'example_no_target.html')
+            };
+            done();
+        });
+        
+        after(function (done) {
+            SpecHelpers.remove_tmp_directory();
+            done();
+        });
+
+        it('should set the title', function () {
+            var testing_file = files.normal,
+                dom = cheerio.load(fs.readFileSync(testing_file)),
+                result = sut.run(testing_file, dom);
+            assert.strictEqual('Accelerometer', result);
+            assert.strictEqual('Accelerometer', dom('#subheader > h1').first().html());
+        });
+
+        it('should skip files with no source title', function () {
+            var dom = cheerio.load(fs.readFileSync(files.no_source)),
+                result = sut.run(files.no_source, dom);
+            assert.strictEqual(null, result);
+        });
+
+        it('should skip files with no target title', function () {
+            var dom = cheerio.load(fs.readFileSync(files.no_target)),
+                result = sut.run(files.no_target, dom);
+            assert.strictEqual(null, result);
+        });
+    });
+}());
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-docs/blob/5f554950/tools/spec/cordova/add_title_spec/example.html
----------------------------------------------------------------------
diff --git a/tools/spec/cordova/add_title_spec/example.html b/tools/spec/cordova/add_title_spec/example.html
new file mode 100644
index 0000000..9918a71
--- /dev/null
+++ b/tools/spec/cordova/add_title_spec/example.html
@@ -0,0 +1,547 @@
+<!--
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+
+	  http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+-->
+
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no, width=device-width">
+		<meta name="generator" content="joDoc">
+		<link rel="stylesheet" type="text/css" href="index.css">
+		<title>PhoneGap API Documentation</title>
+	</head>
+	<body>
+		
+		<div id="header">
+			<h1>Phone<strong>Gap</strong> Documentation</h1>
+			<small></small>
+		</div>
+		<div id="subheader">
+			<h1>[ Object Title Goes Here ]</h1>
+			<small>
+				<select>
+					<option>Quick Jump...</option>
+					<option>Geolocation</option>
+					<option>getCurrentPosition</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Description</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Quick Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Full Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- iPhone Quirks</option>
+					<option>watchPosition</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Description</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Quick Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Full Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- iPhone Quirks</option>
+					<option>clearWatch</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Description</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Quick Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Full Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- iPhone Quirks</option>
+				</select>
+			</small>
+		</div>
+		
+		<div id="sidebar">
+			<div class="vertical_divider"></div>
+			<h1>API Reference</h1>
+			<ul>
+				<li><a href="phonegap_accelerometer_accelerometer.md.html">Accelerometer</a></li>
+				<li><a href="phonegap_camera_camera.md.html">Camera</a></li>
+				<li><a href="phonegap_device_device.md.html">Device</a></li>
+				<li><a href="phonegap_events_events.md.html">Events</a></li>
+				<li><a href="phonegap_geolocation_geolocation.md.html">Geolocation</a></li>
+				<li><a href="phonegap_notification_notification.md.html">Notification</a></li>
+			</ul>
+		</div>
+		
+		<div id="content">
+			<h1><a name="Accelerometer">Accelerometer</a></h1>
+
+<blockquote>
+  <p>Captures device motion in the x, y, and z direction.</p>
+</blockquote>
+
+<h2>Methods</h2>
+
+<ul>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a></li>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a></li>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a></li>
+</ul>
+
+<h2>Arguments</h2>
+
+<ul>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a></li>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerError">accelerometerError</a></li>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerOptions">accelerometerOptions</a></li>
+</ul>
+
+<h2>Objects (Read-Only)</h2>
+
+<ul>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a></li>
+</ul>
+
+<hr />
+
+<h1><a name="accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a></h1>
+
+<p>Get the current acceleration along the x, y, and z axis.</p>
+
+<pre><code>navigator.accelerometer.getCurrentAcceleration(<a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a>, <a href="phonegap_accelerometer_accelerometer.md.html#accelerometerError">accelerometerError</a>);
+</code></pre>
+
+<h2>Description</h2>
+
+<p>The accelerometer is a motion sensor that detects the change (delta) in movement relative to the current position. The accelerometer can detect 3D movement along the x, y, and z axis.</p>
+
+<p>The acceleration is returned using the <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a></code> callback function.</p>
+
+<h2>Supported Platforms</h2>
+
+<ul>
+<li>iPhone</li>
+</ul>
+
+<h2>Quick Example</h2>
+
+<pre><code>function onSuccess(acceleration) {
+    alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n';
+};
+
+function onError() {
+    alert('onError!');
+};
+
+navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a>(onSuccess, onError);
+</code></pre>
+
+<h2>Full Example</h2>
+
+<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                      "http://www.w3.org/TR/html4/strict.dtd"&gt;
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;title&gt;<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Example&lt;/title&gt;
+
+    &lt;script type="text/javascript" charset="utf-8" src="phonegap.js"&gt;&lt;/script&gt;
+    &lt;script type="text/javascript" charset="utf-8"&gt;
+
+    // Wait for PhoneGap to load
+    //
+    function onLoad() {
+        document.addEventListener("<a href="phonegap_events_events.md.html#deviceready">deviceready</a>", onDeviceReady, false);
+    }
+
+    // PhoneGap is ready
+    //
+    function onDeviceReady() {
+        navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a>(onSuccess, onError);
+    }
+
+    // onSuccess: Get a snapshot of the current acceleration
+    //
+    function onSuccess(acceleration) {
+        alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+              '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+              '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n');
+    }
+
+    // onError: Failed to get the acceleration
+    //
+    function onError() {
+        alert('onError!');
+    }
+
+    &lt;/script&gt;
+  &lt;/head&gt;
+  &lt;body onload="onLoad()"&gt;
+    &lt;h1&gt;Example&lt;/h1&gt;
+    &lt;p&gt;getCurrentAcceleration&lt;/p&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
+</code></pre>
+
+<h2>iPhone Quirks</h2>
+
+<ul>
+<li>iPhone doesn't have the concept of getting the current acceleration at any given point.</li>
+<li>You must watch the acceleration and capture the data at given time intervals.</li>
+<li>Thus, the <code>getCurrentAcceleration</code> function will give you the last value reported from a phoneGap <code>watchAccelerometer</code> call.</li>
+</ul>
+
+<hr />
+
+<h1><a name="accelerometer.watchAcceleration">accelerometer.watchAcceleration</a></h1>
+
+<p>At a regular interval, get the acceleration along the x, y, and z axis.</p>
+
+<pre><code>var watchID = navigator.accelerometer.watchAcceleration(<a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a>,
+                                                       <a href="phonegap_accelerometer_accelerometer.md.html#accelerometerError">accelerometerError</a>,
+                                                       [<a href="phonegap_accelerometer_accelerometer.md.html#accelerometerOptions">accelerometerOptions</a>]);
+</code></pre>
+
+<h2>Description</h2>
+
+<p>The accelerometer is a motion sensor that detects the change (delta) in movement relative to the current position. The accelerometer can detect 3D movement along the x, y, and z axis.</p>
+
+<p>The <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a></code> gets the device's current acceleration at a regular interval. Each time the <code><a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a></code> is retrieved, the <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a></code> callback function is executed. Specify the interval in milliseconds via the <code>frequency</code> parameter in the <code>acceleratorOptions</code> object.</p>
+
+<p>The returned watch ID references references the accelerometer watch interval. The watch ID can be used with <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a></code> to stop watching the accelerometer.</p>
+
+<h2>Supported Platforms</h2>
+
+<ul>
+<li>iPhone</li>
+</ul>
+
+<h2>Quick Example</h2>
+
+<pre><code>function onSuccess(acceleration) {
+    alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n');
+};
+
+function onError() {
+    alert('onError!');
+};
+
+var options = { frequency: 3000 };  // Update every 3 seconds
+
+var watchID = navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a>(onSuccess, onError, options);
+</code></pre>
+
+<h2>Full Example</h2>
+
+<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                      "http://www.w3.org/TR/html4/strict.dtd"&gt;
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;title&gt;<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Example&lt;/title&gt;
+
+    &lt;script type="text/javascript" charset="utf-8" src="phonegap.js"&gt;&lt;/script&gt;
+    &lt;script type="text/javascript" charset="utf-8"&gt;
+
+    // The watch id references the current `watchAcceleration`
+    var watchID = null;
+
+    // Wait for PhoneGap to load
+    //
+    function onLoad() {
+        document.addEventListener("<a href="phonegap_events_events.md.html#deviceready">deviceready</a>", onDeviceReady, false);
+    }
+
+    // PhoneGap is ready
+    //
+    function onDeviceReady() {
+        startWatch();
+    }
+
+    // Start watching the acceleration
+    //
+    function startWatch() {
+
+        // Update acceleration every 3 seconds
+        var options = { frequency: 3000 };
+
+        watchID = navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a>(onSuccess, onError, options);
+    }
+
+    // Stop watching the acceleration
+    //
+    function stopWatch() {
+        if (watchID) {
+            navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a>(watchID);
+            watchID = null;
+        }
+    }
+
+    // onSuccess: Get a snapshot of the current acceleration
+    //
+    function onSuccess(acceleration) {
+        var element = document.getElementById('accelerometer');
+        element.innerHTML = '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '&lt;br /&gt;' +
+                            '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '&lt;br /&gt;' +
+                            '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '&lt;br /&gt;';
+    }
+
+    // onError: Failed to get the acceleration
+    //
+    function onError() {
+        alert('onError!');
+    }
+
+    &lt;/script&gt;
+  &lt;/head&gt;
+  &lt;body onload="onLoad()"&gt;
+    &lt;div id="accelerometer"&gt;Waiting for accelerometer...&lt;/div&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
+</code></pre>
+
+<h2> iPhone Quirks</h2>
+
+<ul>
+<li>At the interval requested, PhoneGap will call the success callback function and pass the accelerometer results.</li>
+<li>However, in requests to the device PhoneGap restricts the interval to minimum of every 40ms and a maximum of every 1000ms.
+<ul>
+<li>For example, if you request an interval of 3 seconds (3000ms), PhoneGap will request an interval of 1 second from the device but invoke the success callback at the requested interval of 3 seconds.</li>
+</ul></li>
+</ul>
+
+<hr />
+
+<h1><a name="accelerometer.clearWatch">accelerometer.clearWatch</a></h1>
+
+<p>Stop watching the <code><a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a></code> referenced by the watch ID parameter.</p>
+
+<pre><code>navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a>(watchID);
+</code></pre>
+
+<ul>
+<li><strong>watchID</strong>: The ID returned by <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a></code>.</li>
+</ul>
+
+<h2>Supported Platforms</h2>
+
+<ul>
+<li>iPhone</li>
+</ul>
+
+<h2>Quick Example</h2>
+
+<pre><code>var watchID = navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a>(onSuccess, onError, options);
+
+// ... later on ...
+
+navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a>(watchID);
+</code></pre>
+
+<h2>Full Example</h2>
+
+<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                      "http://www.w3.org/TR/html4/strict.dtd"&gt;
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;title&gt;<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Example&lt;/title&gt;
+
+    &lt;script type="text/javascript" charset="utf-8" src="phonegap.js"&gt;&lt;/script&gt;
+    &lt;script type="text/javascript" charset="utf-8"&gt;
+
+    // The watch id references the current `watchAcceleration`
+    var watchID = null;
+
+    // Wait for PhoneGap to load
+    //
+    function onLoad() {
+        document.addEventListener("<a href="phonegap_events_events.md.html#deviceready">deviceready</a>", onDeviceReady, false);
+    }
+
+    // PhoneGap is ready
+    //
+    function onDeviceReady() {
+        startWatch();
+    }
+
+    // Start watching the acceleration
+    //
+    function startWatch() {
+
+        // Update acceleration every 3 seconds
+        var options = { frequency: 3000 };
+
+        watchID = navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a>(onSuccess, onError, options);
+    }
+
+    // Stop watching the acceleration
+    //
+    function stopWatch() {
+        if (watchID) {
+            navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a>(watchID);
+            watchID = null;
+        }
+    }
+
+    // onSuccess: Get a snapshot of the current acceleration
+    //
+    function onSuccess(acceleration) {
+        var element = document.getElementById('accelerometer');
+        element.innerHTML = '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '&lt;br /&gt;' +
+                            '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '&lt;br /&gt;' +
+                            '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '&lt;br /&gt;';
+    }
+
+    // onError: Failed to get the acceleration
+    //
+    function onError() {
+        alert('onError!');
+    }
+
+    &lt;/script&gt;
+  &lt;/head&gt;
+  &lt;body onload="onLoad()"&gt;
+    &lt;div id="accelerometer"&gt;Waiting for accelerometer...&lt;/div&gt;
+    &lt;button onclick="stopWatch();"&gt;Stop Watching&lt;/button&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
+</code></pre>
+
+<hr />
+
+<h1><a name="Acceleration">Acceleration</a></h1>
+
+<p>Contains <code><a href="phonegap_accelerometer_accelerometer.md.html#Accelerometer">Accelerometer</a></code> data captured at a specific point in time.</p>
+
+<h2>Properties</h2>
+
+<ul>
+<li><strong>x:</strong> Amount of motion on the x-axis. Range [0, 1] (<code>Number</code>)</li>
+<li><strong>y:</strong> Amount of motion on the y-axis. Range [0, 1] (<code>Number</code>)</li>
+<li><strong>z:</strong> Amount of motion on the z-axis. Range [0, 1] (<code>Number</code>)</li>
+<li><strong>timestamp:</strong> Creation timestamp in milliseconds. (<code>DOMTimeStamp</code>)</li>
+</ul>
+
+<h2>Description</h2>
+
+<p>This object is created and populated by PhoneGap, and returned by an <code><a href="phonegap_accelerometer_accelerometer.md.html#Accelerometer">Accelerometer</a></code> method.</p>
+
+<h2>Supported Platforms</h2>
+
+<ul>
+<li>Untested</li>
+</ul>
+
+<h2>Quick Example</h2>
+
+<pre><code>function onSuccess(acceleration) {
+    alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n';
+};
+
+function onError() {
+    alert('onError!');
+};
+
+navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a>(onSuccess, onError);
+</code></pre>
+
+<h2>Full Example</h2>
+
+<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                      "http://www.w3.org/TR/html4/strict.dtd"&gt;
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;title&gt;<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Example&lt;/title&gt;
+
+    &lt;script type="text/javascript" charset="utf-8" src="phonegap.js"&gt;&lt;/script&gt;
+    &lt;script type="text/javascript" charset="utf-8"&gt;
+
+    // Wait for PhoneGap to load
+    //
+    function onLoad() {
+        document.addEventListener("<a href="phonegap_events_events.md.html#deviceready">deviceready</a>", onDeviceReady, false);
+    }
+
+    // PhoneGap is ready
+    //
+    function onDeviceReady() {
+        navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a>(onSuccess, onError);
+    }
+
+    // onSuccess: Get a snapshot of the current acceleration
+    //
+    function onSuccess() {
+        alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+              '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+              '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n';
+    }
+
+    // onError: Failed to get the acceleration
+    //
+    function onError() {
+        alert('onError!');
+    }
+
+    &lt;/script&gt;
+  &lt;/head&gt;
+  &lt;body onload="onLoad()"&gt;
+    &lt;h1&gt;Example&lt;/h1&gt;
+    &lt;p&gt;getCurrentAcceleration&lt;/p&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
+</code></pre>
+
+<hr />
+
+<h1><a name="accelerometerSuccess">accelerometerSuccess</a></h1>
+
+<p>onSuccess callback function that provides the <a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> information.</p>
+
+<pre><code>function(acceleration) {
+    // Do something
+}
+</code></pre>
+
+<h2>Parameters</h2>
+
+<ul>
+<li><strong>acceleration:</strong> The acceleration at a single moment in time. (<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a>)</li>
+</ul>
+
+<h2>Example</h2>
+
+<pre><code>function onSuccess(acceleration) {
+    alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n';
+};
+</code></pre>
+
+<hr />
+
+<h1><a name="accelerometerError">accelerometerError</a></h1>
+
+<p>onError callback function for acceleration functions.</p>
+
+<pre><code>function() {
+    // Handle the error
+}
+</code></pre>
+
+<hr />
+
+<h1><a name="accelerometerOptions">accelerometerOptions</a></h1>
+
+<p>An optional parameter to customize the retrieval of the accelerometer.</p>
+
+<h2>Options</h2>
+
+<ul>
+<li><strong>frequency:</strong> How often to retrieve the <code><a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a></code> in milliseconds. <em>(Number)</em> (Default: 10000)</li>
+</ul>
+
+		</div>
+		
+	</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-docs/blob/5f554950/tools/spec/cordova/add_title_spec/example_no_source.html
----------------------------------------------------------------------
diff --git a/tools/spec/cordova/add_title_spec/example_no_source.html b/tools/spec/cordova/add_title_spec/example_no_source.html
new file mode 100644
index 0000000..5b60058
--- /dev/null
+++ b/tools/spec/cordova/add_title_spec/example_no_source.html
@@ -0,0 +1,34 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no, width=device-width">
+		<meta name="generator" content="joDoc">
+		<link rel="stylesheet" type="text/css" href="index.css">
+		<title>PhoneGap API Documentation</title>
+	</head>
+	<body>
+		<div id="subheader">
+			<h1>[ Object Title Goes Here ]</h1>
+		</div>
+	</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-docs/blob/5f554950/tools/spec/cordova/add_title_spec/example_no_target.html
----------------------------------------------------------------------
diff --git a/tools/spec/cordova/add_title_spec/example_no_target.html b/tools/spec/cordova/add_title_spec/example_no_target.html
new file mode 100644
index 0000000..4610238
--- /dev/null
+++ b/tools/spec/cordova/add_title_spec/example_no_target.html
@@ -0,0 +1,34 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no, width=device-width">
+		<meta name="generator" content="joDoc">
+		<link rel="stylesheet" type="text/css" href="index.css">
+		<title>PhoneGap API Documentation</title>
+	</head>
+	<body>
+		<div id="content">
+			<h1>Accelerometer</h1>
+		</div>
+	</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-docs/blob/5f554950/tools/spec/cordova/prettify_spec.js
----------------------------------------------------------------------
diff --git a/tools/spec/cordova/prettify_spec.js b/tools/spec/cordova/prettify_spec.js
new file mode 100644
index 0000000..25186f0
--- /dev/null
+++ b/tools/spec/cordova/prettify_spec.js
@@ -0,0 +1,63 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+/*jslint node: true */
+/*global describe, it, beforeEach, afterEach, after, before */
+(function () {
+    'use strict';
+    var assert = require("assert"),
+        path = require('path'),
+        fs = require('fs'),
+        cheerio = require('cheerio'),
+        Prettify = require("../../lib/cordova/post/prettify"),
+        SpecHelpers = require("../spec_helpers");
+
+    describe('Prettify', function () {
+        var sut,
+            files;
+        
+        beforeEach(function (done) {
+            var tmp_directory = SpecHelpers.create_tmp_directory_assets(module.filename);
+            sut = new Prettify();
+            files = {
+                'normal': path.join(tmp_directory, 'example.html')
+            };
+            done();
+        });
+        
+        afterEach(function (done) {
+            SpecHelpers.remove_tmp_directory();
+            done();
+        });
+
+        it('should find some code blocks', function () {
+            var dom = cheerio.load(fs.readFileSync(files.normal)),
+                code_tags = sut.run(files.normal, dom);
+            assert.ok(code_tags.length > 0);
+        });
+
+        it('should add the prettyprint class to each code block', function () {
+            var testing_file = files.normal,
+                dom = cheerio.load(fs.readFileSync(files.normal)),
+                initial_title,
+                new_title;
+            sut.run(files.normal, dom);
+            assert.ok(dom('#content pre.prettyprint').length > 0);
+        });
+    });
+}());
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-docs/blob/5f554950/tools/spec/cordova/prettify_spec/example.html
----------------------------------------------------------------------
diff --git a/tools/spec/cordova/prettify_spec/example.html b/tools/spec/cordova/prettify_spec/example.html
new file mode 100644
index 0000000..a3098fd
--- /dev/null
+++ b/tools/spec/cordova/prettify_spec/example.html
@@ -0,0 +1,547 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no, width=device-width">
+		<meta name="generator" content="joDoc">
+		<link rel="stylesheet" type="text/css" href="index.css">
+		<title>PhoneGap API Documentation</title>
+	</head>
+	<body>
+		
+		<div id="header">
+			<h1>Phone<strong>Gap</strong> Documentation</h1>
+			<small></small>
+		</div>
+		<div id="subheader">
+			<h1>[ Object Title Goes Here ]</h1>
+			<small>
+				<select>
+					<option>Quick Jump...</option>
+					<option>Geolocation</option>
+					<option>getCurrentPosition</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Description</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Quick Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Full Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- iPhone Quirks</option>
+					<option>watchPosition</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Description</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Quick Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Full Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- iPhone Quirks</option>
+					<option>clearWatch</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Description</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Quick Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- Full Example</option>
+					<option>&nbsp;&nbsp;&nbsp;&nbsp;- iPhone Quirks</option>
+				</select>
+			</small>
+		</div>
+		
+		<div id="sidebar">
+			<div class="vertical_divider"></div>
+			<h1>API Reference</h1>
+			<ul>
+				<li><a href="phonegap_accelerometer_accelerometer.md.html">Accelerometer</a></li>
+				<li><a href="phonegap_camera_camera.md.html">Camera</a></li>
+				<li><a href="phonegap_device_device.md.html">Device</a></li>
+				<li><a href="phonegap_events_events.md.html">Events</a></li>
+				<li><a href="phonegap_geolocation_geolocation.md.html">Geolocation</a></li>
+				<li><a href="phonegap_notification_notification.md.html">Notification</a></li>
+			</ul>
+		</div>
+		
+		<div id="content">
+			<h1><a name="Accelerometer">Accelerometer</a></h1>
+
+<blockquote>
+  <p>Captures device motion in the x, y, and z direction.</p>
+</blockquote>
+
+<h2>Methods</h2>
+
+<ul>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a></li>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a></li>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a></li>
+</ul>
+
+<h2>Arguments</h2>
+
+<ul>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a></li>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerError">accelerometerError</a></li>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerOptions">accelerometerOptions</a></li>
+</ul>
+
+<h2>Objects (Read-Only)</h2>
+
+<ul>
+<li><a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a></li>
+</ul>
+
+<hr />
+
+<h1><a name="accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a></h1>
+
+<p>Get the current acceleration along the x, y, and z axis.</p>
+
+<pre><code>navigator.accelerometer.getCurrentAcceleration(<a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a>, <a href="phonegap_accelerometer_accelerometer.md.html#accelerometerError">accelerometerError</a>);
+</code></pre>
+
+<h2>Description</h2>
+
+<p>The accelerometer is a motion sensor that detects the change (delta) in movement relative to the current position. The accelerometer can detect 3D movement along the x, y, and z axis.</p>
+
+<p>The acceleration is returned using the <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a></code> callback function.</p>
+
+<h2>Supported Platforms</h2>
+
+<ul>
+<li>iPhone</li>
+</ul>
+
+<h2>Quick Example</h2>
+
+<pre><code>function onSuccess(acceleration) {
+    alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n';
+};
+
+function onError() {
+    alert('onError!');
+};
+
+navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a>(onSuccess, onError);
+</code></pre>
+
+<h2>Full Example</h2>
+
+<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                      "http://www.w3.org/TR/html4/strict.dtd"&gt;
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;title&gt;<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Example&lt;/title&gt;
+
+    &lt;script type="text/javascript" charset="utf-8" src="phonegap.js"&gt;&lt;/script&gt;
+    &lt;script type="text/javascript" charset="utf-8"&gt;
+
+    // Wait for PhoneGap to load
+    //
+    function onLoad() {
+        document.addEventListener("<a href="phonegap_events_events.md.html#deviceready">deviceready</a>", onDeviceReady, false);
+    }
+
+    // PhoneGap is ready
+    //
+    function onDeviceReady() {
+        navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a>(onSuccess, onError);
+    }
+
+    // onSuccess: Get a snapshot of the current acceleration
+    //
+    function onSuccess(acceleration) {
+        alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+              '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+              '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n');
+    }
+
+    // onError: Failed to get the acceleration
+    //
+    function onError() {
+        alert('onError!');
+    }
+
+    &lt;/script&gt;
+  &lt;/head&gt;
+  &lt;body onload="onLoad()"&gt;
+    &lt;h1&gt;Example&lt;/h1&gt;
+    &lt;p&gt;getCurrentAcceleration&lt;/p&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
+</code></pre>
+
+<h2>iPhone Quirks</h2>
+
+<ul>
+<li>iPhone doesn't have the concept of getting the current acceleration at any given point.</li>
+<li>You must watch the acceleration and capture the data at given time intervals.</li>
+<li>Thus, the <code>getCurrentAcceleration</code> function will give you the last value reported from a phoneGap <code>watchAccelerometer</code> call.</li>
+</ul>
+
+<hr />
+
+<h1><a name="accelerometer.watchAcceleration">accelerometer.watchAcceleration</a></h1>
+
+<p>At a regular interval, get the acceleration along the x, y, and z axis.</p>
+
+<pre><code>var watchID = navigator.accelerometer.watchAcceleration(<a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a>,
+                                                       <a href="phonegap_accelerometer_accelerometer.md.html#accelerometerError">accelerometerError</a>,
+                                                       [<a href="phonegap_accelerometer_accelerometer.md.html#accelerometerOptions">accelerometerOptions</a>]);
+</code></pre>
+
+<h2>Description</h2>
+
+<p>The accelerometer is a motion sensor that detects the change (delta) in movement relative to the current position. The accelerometer can detect 3D movement along the x, y, and z axis.</p>
+
+<p>The <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a></code> gets the device's current acceleration at a regular interval. Each time the <code><a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a></code> is retrieved, the <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometerSuccess">accelerometerSuccess</a></code> callback function is executed. Specify the interval in milliseconds via the <code>frequency</code> parameter in the <code>acceleratorOptions</code> object.</p>
+
+<p>The returned watch ID references references the accelerometer watch interval. The watch ID can be used with <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a></code> to stop watching the accelerometer.</p>
+
+<h2>Supported Platforms</h2>
+
+<ul>
+<li>iPhone</li>
+</ul>
+
+<h2>Quick Example</h2>
+
+<pre><code>function onSuccess(acceleration) {
+    alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n');
+};
+
+function onError() {
+    alert('onError!');
+};
+
+var options = { frequency: 3000 };  // Update every 3 seconds
+
+var watchID = navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a>(onSuccess, onError, options);
+</code></pre>
+
+<h2>Full Example</h2>
+
+<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                      "http://www.w3.org/TR/html4/strict.dtd"&gt;
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;title&gt;<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Example&lt;/title&gt;
+
+    &lt;script type="text/javascript" charset="utf-8" src="phonegap.js"&gt;&lt;/script&gt;
+    &lt;script type="text/javascript" charset="utf-8"&gt;
+
+    // The watch id references the current `watchAcceleration`
+    var watchID = null;
+
+    // Wait for PhoneGap to load
+    //
+    function onLoad() {
+        document.addEventListener("<a href="phonegap_events_events.md.html#deviceready">deviceready</a>", onDeviceReady, false);
+    }
+
+    // PhoneGap is ready
+    //
+    function onDeviceReady() {
+        startWatch();
+    }
+
+    // Start watching the acceleration
+    //
+    function startWatch() {
+
+        // Update acceleration every 3 seconds
+        var options = { frequency: 3000 };
+
+        watchID = navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a>(onSuccess, onError, options);
+    }
+
+    // Stop watching the acceleration
+    //
+    function stopWatch() {
+        if (watchID) {
+            navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a>(watchID);
+            watchID = null;
+        }
+    }
+
+    // onSuccess: Get a snapshot of the current acceleration
+    //
+    function onSuccess(acceleration) {
+        var element = document.getElementById('accelerometer');
+        element.innerHTML = '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '&lt;br /&gt;' +
+                            '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '&lt;br /&gt;' +
+                            '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '&lt;br /&gt;';
+    }
+
+    // onError: Failed to get the acceleration
+    //
+    function onError() {
+        alert('onError!');
+    }
+
+    &lt;/script&gt;
+  &lt;/head&gt;
+  &lt;body onload="onLoad()"&gt;
+    &lt;div id="accelerometer"&gt;Waiting for accelerometer...&lt;/div&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
+</code></pre>
+
+<h2> iPhone Quirks</h2>
+
+<ul>
+<li>At the interval requested, PhoneGap will call the success callback function and pass the accelerometer results.</li>
+<li>However, in requests to the device PhoneGap restricts the interval to minimum of every 40ms and a maximum of every 1000ms.
+<ul>
+<li>For example, if you request an interval of 3 seconds (3000ms), PhoneGap will request an interval of 1 second from the device but invoke the success callback at the requested interval of 3 seconds.</li>
+</ul></li>
+</ul>
+
+<hr />
+
+<h1><a name="accelerometer.clearWatch">accelerometer.clearWatch</a></h1>
+
+<p>Stop watching the <code><a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a></code> referenced by the watch ID parameter.</p>
+
+<pre><code>navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a>(watchID);
+</code></pre>
+
+<ul>
+<li><strong>watchID</strong>: The ID returned by <code><a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a></code>.</li>
+</ul>
+
+<h2>Supported Platforms</h2>
+
+<ul>
+<li>iPhone</li>
+</ul>
+
+<h2>Quick Example</h2>
+
+<pre><code>var watchID = navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a>(onSuccess, onError, options);
+
+// ... later on ...
+
+navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a>(watchID);
+</code></pre>
+
+<h2>Full Example</h2>
+
+<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                      "http://www.w3.org/TR/html4/strict.dtd"&gt;
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;title&gt;<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Example&lt;/title&gt;
+
+    &lt;script type="text/javascript" charset="utf-8" src="phonegap.js"&gt;&lt;/script&gt;
+    &lt;script type="text/javascript" charset="utf-8"&gt;
+
+    // The watch id references the current `watchAcceleration`
+    var watchID = null;
+
+    // Wait for PhoneGap to load
+    //
+    function onLoad() {
+        document.addEventListener("<a href="phonegap_events_events.md.html#deviceready">deviceready</a>", onDeviceReady, false);
+    }
+
+    // PhoneGap is ready
+    //
+    function onDeviceReady() {
+        startWatch();
+    }
+
+    // Start watching the acceleration
+    //
+    function startWatch() {
+
+        // Update acceleration every 3 seconds
+        var options = { frequency: 3000 };
+
+        watchID = navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.watchAcceleration">accelerometer.watchAcceleration</a>(onSuccess, onError, options);
+    }
+
+    // Stop watching the acceleration
+    //
+    function stopWatch() {
+        if (watchID) {
+            navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.clearWatch">accelerometer.clearWatch</a>(watchID);
+            watchID = null;
+        }
+    }
+
+    // onSuccess: Get a snapshot of the current acceleration
+    //
+    function onSuccess(acceleration) {
+        var element = document.getElementById('accelerometer');
+        element.innerHTML = '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '&lt;br /&gt;' +
+                            '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '&lt;br /&gt;' +
+                            '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '&lt;br /&gt;';
+    }
+
+    // onError: Failed to get the acceleration
+    //
+    function onError() {
+        alert('onError!');
+    }
+
+    &lt;/script&gt;
+  &lt;/head&gt;
+  &lt;body onload="onLoad()"&gt;
+    &lt;div id="accelerometer"&gt;Waiting for accelerometer...&lt;/div&gt;
+    &lt;button onclick="stopWatch();"&gt;Stop Watching&lt;/button&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
+</code></pre>
+
+<hr />
+
+<h1><a name="Acceleration">Acceleration</a></h1>
+
+<p>Contains <code><a href="phonegap_accelerometer_accelerometer.md.html#Accelerometer">Accelerometer</a></code> data captured at a specific point in time.</p>
+
+<h2>Properties</h2>
+
+<ul>
+<li><strong>x:</strong> Amount of motion on the x-axis. Range [0, 1] (<code>Number</code>)</li>
+<li><strong>y:</strong> Amount of motion on the y-axis. Range [0, 1] (<code>Number</code>)</li>
+<li><strong>z:</strong> Amount of motion on the z-axis. Range [0, 1] (<code>Number</code>)</li>
+<li><strong>timestamp:</strong> Creation timestamp in milliseconds. (<code>DOMTimeStamp</code>)</li>
+</ul>
+
+<h2>Description</h2>
+
+<p>This object is created and populated by PhoneGap, and returned by an <code><a href="phonegap_accelerometer_accelerometer.md.html#Accelerometer">Accelerometer</a></code> method.</p>
+
+<h2>Supported Platforms</h2>
+
+<ul>
+<li>Untested</li>
+</ul>
+
+<h2>Quick Example</h2>
+
+<pre><code>function onSuccess(acceleration) {
+    alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n';
+};
+
+function onError() {
+    alert('onError!');
+};
+
+navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a>(onSuccess, onError);
+</code></pre>
+
+<h2>Full Example</h2>
+
+<pre><code>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+                      "http://www.w3.org/TR/html4/strict.dtd"&gt;
+&lt;html&gt;
+  &lt;head&gt;
+    &lt;title&gt;<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Example&lt;/title&gt;
+
+    &lt;script type="text/javascript" charset="utf-8" src="phonegap.js"&gt;&lt;/script&gt;
+    &lt;script type="text/javascript" charset="utf-8"&gt;
+
+    // Wait for PhoneGap to load
+    //
+    function onLoad() {
+        document.addEventListener("<a href="phonegap_events_events.md.html#deviceready">deviceready</a>", onDeviceReady, false);
+    }
+
+    // PhoneGap is ready
+    //
+    function onDeviceReady() {
+        navigator.<a href="phonegap_accelerometer_accelerometer.md.html#accelerometer.getCurrentAcceleration">accelerometer.getCurrentAcceleration</a>(onSuccess, onError);
+    }
+
+    // onSuccess: Get a snapshot of the current acceleration
+    //
+    function onSuccess() {
+        alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+              '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+              '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n';
+    }
+
+    // onError: Failed to get the acceleration
+    //
+    function onError() {
+        alert('onError!');
+    }
+
+    &lt;/script&gt;
+  &lt;/head&gt;
+  &lt;body onload="onLoad()"&gt;
+    &lt;h1&gt;Example&lt;/h1&gt;
+    &lt;p&gt;getCurrentAcceleration&lt;/p&gt;
+  &lt;/body&gt;
+&lt;/html&gt;
+</code></pre>
+
+<hr />
+
+<h1><a name="accelerometerSuccess">accelerometerSuccess</a></h1>
+
+<p>onSuccess callback function that provides the <a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> information.</p>
+
+<pre><code>function(acceleration) {
+    // Do something
+}
+</code></pre>
+
+<h2>Parameters</h2>
+
+<ul>
+<li><strong>acceleration:</strong> The acceleration at a single moment in time. (<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a>)</li>
+</ul>
+
+<h2>Example</h2>
+
+<pre><code>function onSuccess(acceleration) {
+    alert('<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> X: ' + acceleration.x + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Y: ' + acceleration.y + '\n' +
+          '<a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a> Z: ' + acceleration.z + '\n';
+};
+</code></pre>
+
+<hr />
+
+<h1><a name="accelerometerError">accelerometerError</a></h1>
+
+<p>onError callback function for acceleration functions.</p>
+
+<pre><code>function() {
+    // Handle the error
+}
+</code></pre>
+
+<hr />
+
+<h1><a name="accelerometerOptions">accelerometerOptions</a></h1>
+
+<p>An optional parameter to customize the retrieval of the accelerometer.</p>
+
+<h2>Options</h2>
+
+<ul>
+<li><strong>frequency:</strong> How often to retrieve the <code><a href="phonegap_accelerometer_accelerometer.md.html#Acceleration">Acceleration</a></code> in milliseconds. <em>(Number)</em> (Default: 10000)</li>
+</ul>
+
+		</div>
+		
+	</body>
+</html>
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org