Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/roperzh/jroff

Man pages parser written in JavaScript, supports `an` and `doc` macros - WIP
https://github.com/roperzh/jroff

ast groff javascript man-page man-pages-parser

Last synced: about 2 months ago
JSON representation

Man pages parser written in JavaScript, supports `an` and `doc` macros - WIP

Awesome Lists containing this project

README

        

![jroff](https://cloud.githubusercontent.com/assets/4419992/11488319/61d7086e-97a4-11e5-9ea7-2276c409c208.png)

![travis](https://travis-ci.org/roperzh/jroff.svg?branch=master)
[![Code Climate](https://codeclimate.com/github/roperzh/jroff/badges/gpa.svg)](https://codeclimate.com/github/roperzh/jroff)
[![Test Coverage](https://codeclimate.com/github/roperzh/jroff/badges/coverage.svg)](https://codeclimate.com/github/roperzh/jroff/coverage)

## About

*For a real-life example of Jroff in action, check out [grapse](http://www.roperzh.com/grapse).*

Jroff is a man page parser written in JavaScript, featuring:

- Partial support for groff-native commands
- Full support for `an` macros
- Full support for `doc` macros

The main functionality of the library is to produce an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) ready to
be consumed by a generator.

At the moment, only a single HTML generator has been implemented, but the plan is
to implement several more in the near future.

## Usage
*An annotated version of the code can be found [here](http://www.roperzh.com/jroff/)*

### HTML Generator
Using the generator is fairly simple. You only have to create
a new instance and call the `generate` method every
time you want to parse a string containing groff text.

The `generate` function takes two arguments: the source string and an
optional name from the macro library that will be used to parse the result:

```javascript
// Instantiate a new generator
var generator = new Jroff.HTMLGenerator();
// Generate the HTML output
var result = generator.generate('.Op Fl 0 Ns Op Ar octal', 'doc');
```
This is what we see when we print the result variable:

```html
[-0 [octal]]
```

### Parser

The parser takes a string as a source, being capable of building an AST
from it. Using the parser is very straightforward, but it is nearly
useless without a generator:

```javascript
// Instantiate a new parser class
var parser = new Jroff.Parser('.Op Fl lorem ipsum');
// Build the AST
var ast = parser.buildAST();
```
This is what we see when we inspect the `ast` variable:

```json
[{
"value": "Op",
"kind": 2,
"nodes": [{
"value": " ",
"kind": 5,
"nodes": []
}, {
"value": "Fl",
"kind": 3,
"nodes": [{
"value": " lorem ipsum",
"kind": 5,
"nodes": []
}]
}]
}]
```

### Defining New Macros

You can define a specific macro for your project by
adding a new item in the `Jroff.macros.defaults` object, using
the macro name as a key and the function with a specific macro
functionality as the value:

```javascript
Jroff.macros.defaults.sp = function (spacing) {
spacing = spacing || '2';
return '


';
};
```
Internally, all macros are defined like this. You can check out `src/macros/defaults.js` for more examples.

## Contributing

For regular development, you need to have `Node.js >=0.10` installed in
your system. Then,

Clone the repository.

```console
git clone [email protected]:roperzh/jroff_final.git
cd jroff_final
```

Install the required dependencies.

```console
npm install
```

Finally, build your local copy and run the tests.

```console
make all
```

### Brief Description of the Organization of the Code

`dist`: This folder stores the bundled versions of the code.

`src/core`: As the name of the folder suggests, this is the core of the library.
There is no HTML-related code here, only code to parse and build the AST.

`src/generators`: Generators are entities that can consume the AST
generated by the parser and produce an output. At the moment, only one HTML
generator has been implemented.

`src/macros`: Stores macro commands and macro packages.
At the moment, it only supports `an` and `doc` packages.
Macros supported by groff are stored in `default.js`

`src/utils`: Utility functions and miscellany.

### Brief Description of Make Commands

***make dist:*** beautifies and builds minified and concatenated versions
of the code.

***make hint:*** runs [eslint](http://eslint.org/) over the test files
and the concatenated, non-minified version of the code.

***make beautify:*** runs [js-beautify](https://github.com/beautify-web/js-beautify)
over all JavaScript files.

***make doc:*** generates local documentation based on the current version
of the code. This is useful for previewing documentation before publishing it.
See the next section for more details.

### Documenting New Code

This library uses [jsdoc3](https://github.com/jsdoc3/jsdoc) to generate documentation, so all new code must be documented using jsdoc
tags. A useful reference can be found [here](http://usejsdoc.org/index.html).

Also, due to [some limitations](https://github.com/jsdoc3/jsdoc/issues/930) with
jsdoc and [UMD](https://github.com/umdjs/umd), the `@alias` tag must be added to all functions,
constructors, and namespaces manually.

### Generating Documentation

The Makefile includes a useful command that generates and pushes the
documentation onto GitHub and GitHub pages. You can simply run:

```console
make doc-build
```

**Note:** Please make sure to stash or commit all your changes
before generating the documentation.

If you want to preview the changes before pushing the documentation, you can generate
it with the `doc` task and then open `docs/index.html`
on your browser.

An example of this using OS X:

```console
make doc
open docs/index.html
```

### Benchmarks

Running benchmarks is a complicated task, even more so in this case
since there aren't other libraries to use as a reference and compare
the results with.

Therefore, what these benchmarks are for is to compare different versions
of the library with three arbitrary man pages: `Git`, `Node.js`,
and `Ruby`

This benchmark should be used only for drawing estimative comparisons between
versions or complex features.

If you want to run the benchmarks and compare the new data with the latest stored results:

```console
make bench
```

Alternatively, you can store the results of the benchmark in the
cache file (`benchmarks/benchmarks.json`) with an `-s` flag:

```console
make bench flags='-s'
```
### To-Dos

- [ ] Add support for nested numeric lists
- [ ] Add support for `-width` arguments in lists
- [ ] Add missing macros

### Links

- [Macros](http://www.schweikhardt.net/man_page_howto.html#q5)
- [`an` macros](http://linux.die.net/man/7/man)
- [`doc` macros](https://www.dragonflybsd.org/cgi/web-man?command=mdoc&section=7)
- [Troff specs](http://cm.bell-labs.com/sys/doc/troff.pdf)

## License

All the code contained in this repository, unless explicitly stated, is
licensed under an MIT license.

A copy of the license can be found in the [LICENSE](LICENSE) file.