ndf-parse#

Submodules:

This package is designed for prcessing Eugen Systems ndf files. It allows for easier code manipulations than out-of-the-box differ for Eugen mods.

class Edit(tree: List, file_path: str, save: bool)#

Holds data about currently edited file.

tree#

Model of a currently edited tree.

Type:

CellValue

file_path#

Relative path to a destination file. Path should be relative to a mod root, i.e. GameData/Generated/..., more on that here.

Type:

str

save#

Whether to write out the file after edits are done or not.

Type:

bool

class Mod(mod_src: str, mod_dst: str)#

This class holds links to source and destination mods. It also holds methods and wrappers designed to streamline editing, mainly the edit() method.

mod_src#

Path to an unedited source mod. Can be relative to CWD.

Type:

str

mod_dst#

Path to a generated destination mod. Can be relative to CWD.

Type:

str

edits#

List of current edits. It tracks nested edit() calls and should not be edited by hand.

Type:

list[Edit]

current_edit#

Currently active edit.

Type:

Edit

Note

Paths are relative to an execution path, more on that here.

Examples

>>> import ndf_parse as ndf
>>> mod = ndf.Mod('path/to/unedited/mod', 'path/to/generated/mod')
>>> with mod.edit('GameData/path/to/file.ndf') as source:
...     ...  # edits to the source
>>> # at the end of `with` file gets automatically written out
None
edit(file_path: str, save: bool = True, ensure_no_errors: bool = True) Mod#

Creates a new edit. It is designed to work with with clause. Avoid using it outside of the with unless you know what you are doing.

Parameters:
  • file_path (str) – File to be edited. Path should be relative to a mod root, i.e. GameData/Generated/..., more on that here.

  • save (bool, default=True) – If True then file gets written out at the end of the with statement.

  • ensure_no_errors (bool, default=True) – Ensures that original ndf code has no syntax errors. Fails if there are any and this parameter is True. Be mindful of checking strictness.

Returns:

Returns it’s parent Mod object. Required for with statement to work correctly.

Return type:

Mod

check_if_src_is_newer() bool#

Nukes the destination mod and recreates a pristine copy of the destination mod if the source mod is newer (if modification date of the source is newer than of the destination).

Returns:

True if the destination mod was rebuilt.

Return type:

bool

update_dst()#

Forcefully rebuilds a clean version of the destination mod, no checks performed.

parse_src(file_path: str, ensure_no_errors: bool = True) List#

Parses a file from a source mod.

This function does not write any modified data back to a destination file. It’s merely a convenience function for retrieving another mod file model to fetch some data without risking to write any modifications back out.

Parameters:
  • file_path (str) – Relative path to a source file. Path should be relative to a mod root, i.e. GameData/Generated/..., more on that here.

  • ensure_no_errors (bool, optional, default=True) – If on then fails in case there are any syntactic errors in the ndf code. Be mindful of checking strictness.

Returns:

Model representation of the source mod file.

Return type:

List

Examples

>>> import ndf_parse as ndf
>>> mod = ndf.Mod('path/to/unedited/mod', 'path/to/generated/mod')
>>> with mod.edit('GameData/path/to/units_file.ndf') as units:
...     # This is a pseudocode, it does not match an actual mod
...     # structure, it's intended to only show a possible use case.
...     # We up the speed for any unit that has a 155mm weapon.
...     weapons = mod.parse_src('GameData/path/to/weapons_file.ndf')
...     for unit_row in units:
...         weapon_class = unit_row.value.by_member('WeaponClass').value
...         weapon_row = weapons.by_namespace(weapon_class)
...         if weapon_row.value.by_member('Caliber').value == '155':
...             unit = unit_row.value
...             speed_row = unit.by_member('Speed')
...             speed_row.value += ' * 2'
parse_dst(file_path: str, ensure_no_errors: bool = True) List#

Parses a file from a destination mod.

This function is identical to parse_src() in it’s functionality and intent.

Parameters:
  • file_path (str) – Relative path to a destination file. Path should be relative to a mod root, i.e. GameData/Generated/..., more on that here.

  • ensure_no_errors (bool, optional, default=True) – If on then fails in case there are any syntactic errors in the ndf code. Be mindful of checking strictness.

Returns:

Model representation of the source mod file.

Return type:

List

convert(data: AnyStr, ensure_no_errors: bool = True) List#

Converts string/byte data to a List object. Should be used to parse ndf files as a whole.

Parameters:
  • data (AnyStr) – ndf code to parse.

  • ensure_no_errors (bool, default=True) – If True then fail if ndf code contains syntax errors. Be mindful of checking strictness.

Returns:

Model representation of a file.

Return type:

List

expression(data: AnyStr, ensure_no_errors: bool = True) Dict[str, Any]#

Converts string/byte data to a an expression wrapped in a dict. Should be used to parse individual expressions for further injection into an existing model.

Parameters:
  • data (AnyStr) – ndf code to parse.

  • ensure_no_errors (bool, optional, default=True) – If True then fail if ndf code contains syntax errors. Be mindful of checking strictness.

Returns:

A dict containing an item along with possible extra row attributes.

Return type:

dict

Examples

>>> import ndf_parse as ndf
>>> src = """Obj is Typ(
...     Memb1 = "SomeStr"
...     Memb2 = 12
... )"""
>>> source = ndf.convert(src)
>>> arg = ndf.expression("export A is 12")
>>> arg
{'value': '12', 'namespace': 'A', 'visibility': 'export'}
>>> source.add(**arg)  # ** will deconstruct dict into method's parameters
List[1](visibility='export', namespace='A', value='12')
>>> memb = ndf.expression("Memb3 = [1,2,3,Obj2(Memb1 = 5)]")
>>> memb
{'value': [List[0](visibility=None, ... }
>>> source[0].value.add(**memb)
Object[2](member='Memb3', type=None, ...)
>>> ndf.printer.print(source)
Obj is Typ
(
    Memb1 = "SomeStr"
    Memb2 = 12
    Memb3 =
    [
        1,
        2,
        3,
        Obj2
        (
            Memb1 = 5
        )
    ]
)
export A is 12
walk(item, condition) Iterator#

Recursively walks a model representation of an ndf file.

Parameters:
  • item (str | DeclarationsList | DeclListRow) – Source to walk.

  • condition (Callable[[Any], bool]) –

    Function that is responsible for filtering items. Should return True if an item matches desired criteria.

    Note

    This function can accept multiple types so it’s a user’s responsibility to validate the item.

Yields:

str | DeclarationsList | DeclListRow – Items that match the condition criteria (i.e. on which the condition returns True).

Examples

Usage of this function is covered here