npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jsinf

v1.1.2

Published

A JSINF reference implementation

Downloads

7

Readme

jsinf

This comprises the reference decoder for jsinf format.

npm Package build status

Are you looking for something other than YAML or JSON for your configuration files? Perhaps JSINF is an answer. If you know the standard .INI files of windows, then this copes with those... but it also does a lot more:

  • Returns the config as a standard Javascript object, that you can easily convert to JSON if you wish.
  • Supports nested objects (unlike a standard .INI file). eg, can read .gitignore.
  • Supports values that extend over multiple lines!
  • Supports 'default' blocks. That is, you don't even need to start with some_property = !!!

The API, is similar to JSON with parse and stringify:

var jsinf = require('jsinf');
...
var obj = jsinf.parse(some_data);

var text = jsinf.stringify(obj);

Note:

  • Of course, comments and whitespace are not retained when using jsinf.stringify(jsinf.parse(some_data)), but the data integrity will remain intact. (See the tests to verify this).

A Quick Look at the Format

a_property = some value

[section1]
key1 = value1
key2 = value2

[section2]
# this is a comment.
key1 = value3

[section2.nested]
#A comment for a nested object
nested_key = A
value that
runs over many lines,
but can't have a blank line.

---
A block of text that gets assigned
to the property called 'value'

You can put pretty much anything in
here. You don't need the final --- if the 
end of the file is reached.

#this is not a comment. It stays in  
#with this text block unmolested.
---

Installation

Easiest is with npm, in an existing npm project:

npm install jsinf --save

Usage

const jsinf = require('jsinf');

...

var inf_file = `
[section]
value1 = a value
value2 = another value

[another section]
# a comment!
value2 = some 3rd value
`;


var inf_data = jfinf.decode(inf_file);
console.log(inf_data.section.value1); // prints 'a value';

The Format

The format is extremely forgiving and designed for non-technical people.

Nested Objects

[section.sub section]
name=John D. Smith

becomes the equivalent JSON:

{
	"section" : {
		"sub section" : {
			"name": "John D. Smith"
		}
	}
}

The default seperator is a dot '.', however you can change it easily:

// use # as a sub section divider.
var inf_data = jsinf.decode(inf_file, { subsection_divider: '#'}); 

Note:

  • Valid chars for subsections are any word or number, and '-' , '.', '/', '#', '$' and '\'

Multi-line support

[section]
address=32 Fallows Way
Timbuctoo
Somewhere in Africa

Note that blank lines are not allowed. You may wish to consider 'Default Value' and 'Block Default Value' options instead.

Default Values

[section]
I am some
text that 
runs over several
lines!

And can have single blank lines in it.

becomes:

{
	"section": {
		"value": "I am some\ntext that..."
	}
}

Block Default Value

If you have strong requirements for a large block with lots of 'noise' in it, then you may wish to consider a block:

[section]
name=John D. Smith
---
I am a block

that runs until --- is found on it's own line

[this is not a section]
# this is not a comment
---

Note:

You can change the property name that is used:

// use 'text' as the default.
var inf_data = jsinf.decode(inf_file, { default_key: 'text'}); 
console.log(inf_data.section.text); // prints 'I am a block\n\n...'

The data would look like:

{
	"section": {
		"name" : "John D. Smith"
		"text": "I am a block\n\n..."
	}
}

Note:

  • There can only be one block per section. If multiple are detected, the last one is used.

You can change the separator sequence with:

// Change the divider to 5 (or more) consecutive asterisks.
var inf_data = jsinf.decode(inf_file, { block_divider: '\\*{5,}'}); 

Parse Options

The following options are available when parsing:

  default_key: 'value'		// This specifies where 'default values' are placed. Default is 'value'

, subsection_divider: '.'   // This specifies how we split a [section.sub section.subsub section]
	 						// If Empty, does not split at all, and everything is just a 'section'
	 						// Can be a function:
							//	 .eg for a .gitconfig styled: [diff "difftool"]:
, subsection_divider: function(section) { 
		return section.split(' ').map(function(name) {  // splits on a space
			return name.replace(/^\"(.*?)\"$/, '$1') }); // trims out sub-section surrounding quotes
		}

, subsection_nameclean: 	// This allows the 'clean up' of a sub-section name.
	 						// By default the string is trimmed of whitespace and (matching) surrounding quotes
	 						// eg.
		function(name) { 
			return name.replace( /^\"(.*?)\"$/, '$1');
		}

/*
key, comment & section_name charsets
 allows (some) control of what is ok and what is not
 if a RegExp is defined, then full control is given (Unless careful, problems will ensue)
*/
, valid_key_chars: "-./\\#$'\""	// Word Characters A-Za-z90-9_ are included by default. 
								// Use a RegExp for full control (TAKE CARE! don't use an equals!):
, valid_key_chars: /[\w\-\.\/\#\$\\\'\"]*[\w]/ 

, valid_section_chars: " -./\\#$'\"" // <== has a 'space' in there
, valid_section_chars: /[\w\'\"]*?[\w\-\.\/ \#\$\\\'\"]*[\w\'\"]/ 	// TAKE CARE! don't use an equals!

, valid_comment_chars: "#;"
, valid_comment_chars: /^[#;](.*)(?:\n|$)/ 

, block_divider: '\\-{3,}' // also '\\-\\-\\-+'
, block_divider: /\-{3,}/

, allow_code: true			// Allow values with code blocks. eg { (123+4).toString() + (new Date()).toString() + " ok!"}
							// If concerned with security/ config is from an untrusted source: SET THIS TO FALSE!

, allow_arrays: true		// allow values as an array: eg [ value1, value2, value3 ]. 
							// Limited usage. Only for simple Array types (without commas). Is equal to:
							//	"value1, value2, value3".split(',').map(function(item) { return item.replace(/^\s*(.*?)\s*$/,'$1')})

, log: true					// Enable logging of internals. Good for debugging, but that's about it.
, log: function(str) { console.log(str); }

##Stringify Options

The following options are available when stringifying:

  default_key: 'value'		// This specifies where 'default values' are placed. Default is 'value'

, subsection_divider: '.'   // This specifies how we split a [section.sub section.subsub section]
	 						// (If Empty, does not split at all, and everything is just a 'section', NOT RECOMMENDED)


, block_divider: '---'      // This MUST match the 'parse' regular expression, but must be a fixed string here

, log: true					// Enable logging of internals. Good for debugging, but that's about it.
, log: function(str) { console.log(str); }