tini

Tolerant INI file parser and printer with support for other haxe structures. Based off of TJSON.
https://github.com/TBar09/TINI

To install, run:

haxelib install tini 1.0.1 

See using Haxelib in Haxelib documentation for more information.

README.md

TINI

TIni is a simple-to-use .ini string parser & printer made in Haxe. This is inspired by JWambaugh's TJSON.

It's entirely cross-platform and should work on all platforms since it relies on string manipulation.

TIni was made as a simple parser in order to educate people wanting to learn about parsers (like hscript or tjson). While it's nowhere near as complex as something like hscript, it serves as a good starting ground for people wanting to learn about it.

Usage

Install TINI through Haxelib by running the following in the command line:

haxelib install tini

You can also install it through Github:

haxelib git tini https://github.com/TBar09/TINI.git

To use the haxelib in a project: - For Haxe projects, use -lib tini. - For OpenFL/Lime projects, use <haxelib name="tini"/>.


Here is basic usage:

; My INI file.ini

myVar="Hello world!!"
myStr=Hello world!
myFloat = 10.254

[MyGroup]
myGroupedStr="Hi, I'm in a group!!"
myBool = true
// Main.hx

import tini.TINI;

function main() {
	var myParser:IniParser = new IniParser(TINI.defaultRules);

	//You can also run TINI.parse() instead, which automatically parses the string and returns it's object.
	var myObject:Dynamic = myParser.parse(sys.io.File.getContent("My INI file.ini"));

	trace(myObject.myStr); // Hello world!
	trace(myObject.MyGroup.myBool); //true
	trace(Reflect.fields(myObject)); //["myVar", "myStr", "myFloat", "MyGroup"]
}

There is also an ini printer too:

// Main.hx

import tini.TINI;

function main() {
	var myObject = {
		myStr: "Hello world!!",
		MyGroup: {
			myBool: true
		}
	}

	//Just like with the parser, there is also a shorter TINI.stringify() method.
	var myPrinter:IniPrinter = new IniPrinter(TINI.defaultRules);

	/*
	;  Generated by the TIni library

	myStr="Hello world!!"

	[MyGroup]
	myBool=true
	*/
	trace(myPrinter.stringify(myObject));
}

Features

While TIni is a barebones ini file parser, it does have some features that make it stand out from other ini parsers.

Array & Maps

Ini files can declare arrays and string maps:

; My INI file.ini

myArr=[10.2, true, ["Hello", "world", "!!"]]

myStringMap=["one" => "Hello", "two" => "World"]
myIntMap=[1 => "Hello", 2 => "World", 3 => "!!!"]

Anonymous Structures

Ini files can declare full anonymous structures:

; My INI file.ini

myStruct={hello: "World", nestedStruct: {world: "Hello"}}

[!NOTE] Ini-declared structures are parser only! Trying to use nested structures with the ini printer will only create an ini group instead of a structure.

Saving Variables

Values inside of an ini file can be brought up again later in the file as a variable:

; My INI file.ini

myVar=10.2

[My Group]
; This saves as 10.2
myOtherVar=myVar

[!NOTE] Only the variable itself is allowed, so doing calculations like myOtherVar=myVar + 10 isn't supported. This is a limitation for now.

Classes & Enums

Ini files can save classes and enums into itself as a string, which can later be parsed back into what it was originally:

; My INI file.ini

myEnum=__ini_enm__Vehicle.TRUCK

; Enums with arguments work too!
myOtherEnum=__ini_enm__Vehicle.CUSTOM("My car", 150, true) 
// Main.hx

import tini.TINI;

enum Vehicle {
	CAR;
	TRUCK;
	CUSTOM(name:String, mph:Int, isCool:Bool);
}

function main() {
	var obj:Dynamic = TINI.parse(sys.io.File.getContent("My INI file.ini"));

	switch(obj.myOtherEnum) {
		case CAR:
			trace("This is a car");
		case TRUCK:
			trace("This is a truck");
		CUSTOM(name, mph, isCool):
			trace('This is a $name that can go ${Std.string(mph)} miles per-hour!');
	}
}

__root__ Keyword

If a group name is called __root__, then the current group will be dropped and any further assign lines will be written to the root structure itself and not inside a group.

; My INI file.ini

myVar=2

; myGroupedVar will be inside of group "My Group", while myRootVar will not.
[My Group]
myGroupedVar=10

[__root__]
myRootVar=20

Ini Rules

The Ini parser & printer supports custom rules that can change how a string/parser is parsed/printed:

// My INI file.ini

myVar>10.2
// Main.hx
import tini.TINI;

function main() {
	var iniParser:IniParser = new IniParser({
		ASSIGN_KEY: ">",
		COMMENT_KEY: "//",
		ARGUMENT_DELIMITER: ",",
		ANON_STRUCTURES_ALLOWED: true,
		CLASSES_ALLOWED: true,
		ENUM_ALLOWED: true,
		CLASS_KEY: "__ini_cls__",
		ENUM_KEY: "__ini_enm__"
	});

	var retObj:Dynamic = iniParser.parse(sys.io.File.getContent("My INI file.ini"));
	trace(retObj.myVar); //10.2
}

The first argument of both the IniParser and IniPrinter is a structure with custom rules. If it is left blank then the default rules in TINI.hx are used.

[!NOTE] For the static methods TINI.parse and TINI.stringify, the second argument is the custom rules.

Below is a full list of rules that you can change:

Rule nameDefault valueFunction
ASSIGN_KEY=The key that will tell the parser where to split the key and the value in a key->value assign line.
COMMENT_KEY;The key that will tell the parser if the line is a comment.
ARGUMENT_DELIMITER,The key that will split arguments in a string class or enum.
ROOT_KEYWORD_ALLOWEDtrueWhether the "root" keyword can be used in groups.
ANON_STRUCTURES_ALLOWEDtrueWhether anonymous structure parsing should be allowed.
CLASSES_ALLOWEDtrueWhether class instance parsing should be allowed.
CLASS_KEY__ini_cls__The prefix string that tells the parser that the line is a class instance.
ENUM_ALLOWEDtrueWhether enum instance parsing should be allowed.
ENUM_KEY__ini_enm__The prefix string that tells the parser that the line is an enum instance.

Limitations

Currently, TIni has a few limits:

  • No sub-groups, so you can't do [My Group.subgroup]. This is planned for a future version.
  • No in-line comments (myVar=10.2 ;I am a comment). This is planned for a future version.
Contributors
T-Bar
Version
1.0.1
Published
1 week ago
License
Apache

All libraries are free

Every month, more than a thousand developers use Haxelib to find, share, and reuse code — and assemble it in powerful new ways. Enjoy Haxe; It is great!

Explore Haxe

Haxe Manual

Haxe Code Cookbook

Haxe API documentation

You can try Haxe in the browser! try.haxe.org

Join us on GitHub!

Haxe is being developed on GitHub. Feel free to contribute or report issues to our projects.

Haxe on GitHub

⌂