Config-JFDI 0.04 should be on CPAN shortly
Config::JFDI mimics Catalyst::Plugin::ConfigLoader (without the need to load Catalyst). The new features in this release are:
I've just released Doc::Simply, a tool for generating documentation from JavaScript (or C, C++, etc.) comments.
I use it to for my b9j documentation
The idea came to me while developing some JavaScript: I was craving a way to drop in free-form documentation in a .js file as easily as I could in a .pm with perlpod.
The Doc::Simply format is modeled after Plain-Old-Documentation, but it is not an exact mimic. Body formatting, for example, is in Markdown (no C<>, L<>, ...)
However, if you are craving pure POD, then it shouldn't be too difficult to bolt a proper parser/generator on top of Doc::Simply
You can run it from the command-line as doc-simply
doc-simply < source.js > documentation.html
doc-simply --help
An example:
/*
* @head1 NAME
*
* Calculator - Add 2 + 2 and return the result
*
*/
// @head1 DESCRIPTION
// @body Add 2 + 2 and return the result (which should be 4)
/*
* @head1 FUNCTIONS
*
* @head2 twoPlusTwo
*
* Add 2 and 2 **and** return 4
*
*/
function twoPlusTwo() {
return 2 + 2; // Should return 4
}
/*
* @head1 AUTHOR
*
* Alice <alice@example.com>
*
* [http://example.com](http://example.com)
*
*/
... which will generate this document
You can download it from http://search.cpan.org/CPAN/authors/id/R/RK/RKRIMEN/Doc-Simply-0.02.tar.gz
... or install it via cpan:
cpan -i Doc::Simply
I've put together an interactive example of my JavaScript URI object:
The example will also show the code necessary to perform the given operation (next to the result)
b9j.uri.URI overview:
The code is available at http://appengine.bravo9.com/b9j/b9j.uri.js (19kb compressed / 5kb gzipped)
See also the documentation for b9j.uri
Following my b9j.path release, I just finished up work on URI object-class for javascript.
It uses Steven Levithan's parseUri 1.2 to do the parsing.
Some example usage:
var uri = new b9j.uri.URI( "http://example.com/a/b?a=1&b=2&c=3&c=4&c=5" )
var host = uri.host()
var child = uri.child("c.html") // http://example.com/a/b/c.html?a=1&b=2& ...
child.query().add({ c: [ 6, 7 ], d: 8 }) // ... ?a=1&b=2&c=3&c=4&c=5&c=6&c=7&d=8
child.query().set("b", 9) // ... ?a=1&b=9&c ...
return child.toString()
Again, while CPAN has URI.pm for URI-handling, JavaScript didn't really have an equivalent (parsing yes -- modifying/generating no).
b9j.path provides a way to parse, manipulate, and generate URI/UNIX-style paths.
CPAN provides lots of different options for path-handling and path-manipulation, but there didn't seem to be anything really available in JavaScript-land.
To fill the gap, I've released b9j.path:
var path = new b9j.path.Path("/a/b/c")
// /a/b/c/xyzzy
var child = path.child("xyzzy")
// /a/b
var parent = path.parent()
// ... and much, much, more...
It's part of my b9j javascript pack available at: http://appengine.bravo9.com/b9j/b9j-latest.zip
YUI Test is a great tool for javascript testing, but it has a couple of small issues:
b9jTest addresses the problems above by:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>b9jTest example</title>
<link rel="stylesheet" type="text/css"
href="http://appengine.bravo9.com/b9j/b9jTest.css">
<script type="text/javascript"
src="http://appengine.bravo9.com/b9j/b9jTest.js"></script>
</head>
<body class="yui-skin-sam">
<div id="testLogger"></div>
<script type="text/javascript">
b9jTest(function(test) {
test.areEqual("xyzzy", "xyzzy");
test.areEqual("apple", "apple");
test.areEqual("banana", "banana");
});
</script>
</body>

b9jTest() is a global function that accepts a function that is called with a testing object. The testing object provides access to the standard YUI assertions and more.
Documentation:
http://appengine.bravo9.com/b9j/documentation/b9jTest.html
Download:
b9jTest.js
b9jTest.css
Example of copying text into the clipboard
Firefox won't allow copying text into the clipboard via javascript for a variety of reasons.
For better or worse, you can get around this problem with a little .swf (Flash):
function copyIntoClipboard(text) {
var flashId = 'flashId-HKxmj5';
/* Replace this with your clipboard.swf location */
var clipboardSWF = 'http://appengine.bravo9.com/copy-into-clipboard/clipboard.swf';
if(!document.getElementById(flashId)) {
var div = document.createElement('div');
div.id = flashId;
document.body.appendChild(div);
}
document.getElementById(flashId).innerHTML = '';
var content = '<embed src="' +
clipboardSWF +
'" FlashVars="clipboard=' + encodeURIComponent(text) +
'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
document.getElementById(flashId).innerHTML = content;
}
The above trick will also work in Safari, IE, and Opera.
Download clipboard.swf
Alternatively, you can use the Google App Engine hosted version at
http://appengine.bravo9.com/copy-into-clipboard/clipboard.swf
(Originally adapted from http://www.jeffothy.com/weblog/clipboard-copy/)
Getopt::Chain will help you make your command-line scripts work like this:
./script --opt --opt=<value> cmd --opt ...
./script cmd ...
NOTE: Any option specification covered by Getopt::Long is fair game.
Here is some example usage:
#!/usr/bin/perl -w
use strict;
use Getopt::Chain;
# A partial, pseudo-reimplementation of git(1):
Getopt::Chain->process(
options => [qw/ version bare git-dir=s /]
run => sub {
my $context = shift;
my @arguments = @_; # Remaining, unparsed arguments
# ... do stuff before any subcommand ...
}
commands => {
init => {
options => [qw/ quiet|q --template=s /]
run => sub {
my $context = shift;
my @arguments = @_; # Again, remaining unparsed arguments
# ... do init stuff ...
}
}
commit => {
options => [qw/ all|a message|m=s /]
run => sub {
my $context = shift;
# ... do commit stuff ..
}
}
add => ...
help => ...
...
}
)
# The above will allow the following (example) usage:
#
# ./script --version
# ./script --git-dir path/to/repository init
# ./script --git-dir path/to/repository commit -a --message '...'
# ./script commit -m '~'
The source repository is on GitHub: http://github.com/robertkrimen/getopt-chain/tree/master
my $params = Hash::Param->new(parameters => {
qw/a 1 b 2 c 3/,
d => [qw/4 5 6 7/],
})
$result = $params->param( a ) # Returns 1
$result = $params->param( d ) # Returns 4
@result = $params->param( d ) # Returns 4, 5, 6, 7
@result = $params->params # Returns a, b, c, d
$result = $params->params # Returns { a => , b => 2,
c => 3, d => [ 4, 5, 6, 7 ] }
@result = $params->params( a, b, d ) # Returns 1, 2, [ 4, 5, 6, 7 ]
%result = $params->slice( a, b ) # Returns a => 1, b => 2
$params->param( a => 8 ) # Sets a to 8
$params->param( a => 8, 9 ) # Sets a to [ 8, 9 ]
The source repository is on GitHub: http://github.com/robertkrimen/hash-param/tree/master
my $comments = String::Comments::Extract::C->extract($source)
String::Comments::Extract is a tool for extracting comments from C/C++/JavaScript/Java. The extractor is implemented using an actual tokenizer (written in C via XS [adapted from JavaScript::Minifier::XS]). By using a tokenizer, it can correctly deal with notoriously problematic cases, such as comment-like structures embedded in strings:
std::cout << "This is not a // real C++ comment " << std::endl
printf("/* This is not a real C comment */\n");
# The extractor will ignore both of the above
The source repository is on GitHub: http://github.com/robertkrimen/string-comments-extract/tree/master