Skip to content

Commit

Permalink
docs. prepare for GA
Browse files Browse the repository at this point in the history
  • Loading branch information
mdmunir committed Oct 15, 2014
1 parent c7df796 commit 499c9ff
Show file tree
Hide file tree
Showing 56 changed files with 30,964 additions and 0 deletions.
21 changes: 21 additions & 0 deletions docs/api/assets/2f6fad72/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2014 Carsten Brandt

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.
45 changes: 45 additions & 0 deletions docs/api/assets/2f6fad72/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
js-search
=========

This is a client side search engine for use on static pages.

It uses a pre-compiled search index to add a fulltext search to static HTML pages such as
[github pages][] or offline API documentation. The index is built by a PHP script using a
similar yet much more simplified and dump approach than the popular search engine [Lucene].

To see how it looks like, check out the [demo][].

[github pages]: https://pages.github.com/
[Lucene]: http://lucene.apache.org/
[demo]: http://cebe.github.io/js-search/#demo


Installation
------------

PHP 5.4 or higher is required to run the index generator.

Installation is recommended to be done via [composer][] by adding the following to the `require` section in your `composer.json`:

```json
"cebe/js-search": "*"
```

Run `composer update` afterwards.


Usage
-----

TODO.

See [example.html](example.html) for an implementation.

### Generate the index

Using the command line tool:
```
vendor/bin/jsindex <path-to-your-html-files>
```

This will generate a `jssearch.index.js` file that you have to include in the Html header.
133 changes: 133 additions & 0 deletions docs/api/assets/2f6fad72/bin/jsindex
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/env php
<?php

// Send all errors to stderr
ini_set('display_errors', 'stderr');

// setup composer autoloading
$composerAutoload = [
__DIR__ . '/../vendor/autoload.php', // standalone with "composer install" run
__DIR__ . '/../../../autoload.php', // script is installed as a composer binary
];
foreach ($composerAutoload as $autoload) {
if (file_exists($autoload)) {
require($autoload);
break;
}
}

if (!class_exists('cebe\jssearch\Indexer')) {
error('Autoloading does not seem to work. Looks like you should run `composer install` first.');
}

// check arguments
$src = [];
foreach($argv as $k => $arg) {
if ($k == 0) {
continue;
}
if ($arg[0] == '-') {
$arg = explode('=', $arg);
switch($arg[0]) {
// TODO allow baseUrl to be set via arg
case '-h':
case '--help':
echo "jssearch index builder\n";
echo "----------------------\n\n";
echo "by Carsten Brandt <[email protected]>\n\n";
usage();
break;
default:
error("Unknown argument " . $arg[0], "usage");
}
} else {
$src[] = $arg;
}
}

if (empty($src)) {
error("You have to give an input directory.", "usage");
}

$indexer = new \cebe\jssearch\Indexer();

$files = [];
foreach($src as $dir) {
$files = array_merge($files, findFiles($dir));

if (empty($files)) {
error("No files where found in $dir.");
}

$indexer->indexFiles($files, $dir);
}

$js = $indexer->exportJs();
file_put_contents('jssearch.index.js', $js);


// functions

/**
* Display usage information
*/
function usage() {
global $argv;
$cmd = $argv[0];
echo <<<EOF
Usage:
$cmd [src-directory]
--help shows this usage information.
creates and jssearch.index.js file in the current directory.
EOF;
exit(1);
}

/**
* Send custom error message to stderr
* @param $message string
* @param $callback mixed called before script exit
* @return void
*/
function error($message, $callback = null) {
$fe = fopen("php://stderr", "w");
fwrite($fe, "Error: " . $message . "\n");

if (is_callable($callback)) {
call_user_func($callback);
}

exit(1);
}

function findFiles($dir, $ext = '.html')
{
if (!is_dir($dir)) {
error("$dir is not a directory.");
}
$dir = rtrim($dir, DIRECTORY_SEPARATOR);
$list = [];
$handle = opendir($dir);
if ($handle === false) {
error('Unable to open directory: ' . $dir);
}
while (($file = readdir($handle)) !== false) {
if ($file === '.' || $file === '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $file;
if (substr($file, -($l = strlen($ext)), $l) === $ext) {
if (is_file($path)) {
$list[] = $path;
} else {
$list = array_merge($list, findFiles($path, $ext));
}
}
}
closedir($handle);

return $list;
}
22 changes: 22 additions & 0 deletions docs/api/assets/2f6fad72/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "cebe/js-search",
"description": "A client side search engine for use on static pages.",
"license": "MIT",
"authors": [
{
"name": "Carsten Brandt",
"email": "[email protected]"
}
],
"require": {
"php": ">=5.4.0"
},
"autoload": {
"psr-4": {
"cebe\\jssearch\\": "lib/"
}
},
"bin": [
"bin/jsindex"
]
}
50 changes: 50 additions & 0 deletions docs/api/assets/2f6fad72/example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="./jssearch.js"></script>
<script src="./jssearch.index.js"></script>

<script type="text/javascript">

$( document ).ready(function() {
$('#searchbox').on("keyup", function() {
var result = jssearch.search($(this).val());

$('#query').html(jssearch.queryWords.join(' '));

$('#results').html('');
var i = 0;
result.forEach(function(item) {
if (i++ > 20) {
return;
}
var div = $('#results');
div.html(div.html() + '<li>"' + item.file.title + '" ' + item.file.url + ' w:' + item.weight + '</li>');
});
});
});
</script>

<title>Example</title>
</head>
<body>

<h1>Example</h1>

<label for="searchbox" style="display: inline-block; width: 160px;">Search: </label>
<input id="searchbox" type="text" value="">

<br/>

<label for="query" style="display: inline-block; width: 160px;">Actual query: </label>
<span id="query"></span>

<ul id="results">
<li>No results</li>
</ul>

</body>
</html>
120 changes: 120 additions & 0 deletions docs/api/assets/2f6fad72/jssearch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// polyfills for IE<9
(function(fn) {
if (!fn.map) {
fn.map = function(f/*, thisArg */) {
if (this === void 0 || this === null)
throw new TypeError();

var t = Object(this);
var len = t.length >>> 0;
if (typeof f !== "function")
throw new TypeError();

var res = new Array(len);
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t)
res[i] = f.call(thisArg, t[i], i, t);
}

return res;
}
}
if (!fn.forEach) {
fn.forEach = function (f/*, thisArg */) {
if (this === void 0 || this === null)
throw new TypeError();

var t = Object(this);
var len = t.length >>> 0;
if (typeof f !== "function")
throw new TypeError();

var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) {
if (i in t)
f.call(thisArg, t[i], i, t);
}
}
}
})(Array.prototype);

var jssearch = {

/**
* the actual words finally used to query (set by last search call)
*/
queryWords: [],

search: function(query) {
var words = jssearch.tokenizeString(query);
var result = {};

jssearch.queryWords = words.map(function(i) { return i.t; });

// do not search when no words given
if (!words.length) {
return result;
}

// result = jssearch.searchForWords(words);
// if ($.isEmptyObject(result)) {
words = jssearch.completeWords(words);
jssearch.queryWords = words.map(function(i) { return i.t; });
result = jssearch.searchForWords(words);
// }

var res = [];
for (var i in result) {
res.push(result[i]);
}
res.sort(function(a,b) { return b.weight - a.weight; });
return res;
},

searchForWords: function(words) {
var result = {};
words.forEach(function(word) {
if (jssearch.index[word.t]) {
jssearch.index[word.t].forEach(function(file) {
if (result[file.f]) {
result[file.f].weight *= file.w * word.w;
} else {
result[file.f] = {
file: jssearch.files[file.f],
weight: file.w * word.w
};
}
});
}
});
return result;
},

completeWords: function(words) {
var result = [];

words.forEach(function(word) {
if (!jssearch.index[word.t] && word.t.length > 2) {
// complete words that are not in the index
for(var w in jssearch.index) {
if (w.substr(0, word.t.length) === word.t) {
result.push({t: w, w: 1});
}
}
} else {
// keep existing words
result.push(word);
}
});
return result;
},

tokenizeString: function(string)
{
if (console) {
console.log('Error: tokenizeString should have been overwritten by index JS file.')
}
return [{t: string, w: 1}];
}
};
Loading

0 comments on commit 499c9ff

Please sign in to comment.