scuff


Namescuff JSON
Version 0.4.5 PyPI version JSON
download
home_pagehttps://github.com/akyuute/scuff
SummaryA slick config file format for humans.
upload_time2024-07-27 13:04:23
maintainerNone
docs_urlNone
authorakyuute
requires_python>=3.12
licenseMIT
keywords config files config file format data serialization language parsing compilers api ast structured data
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ######
Scuff
######

*A slick config file format for humans.*


Introduction
=============

**Scuff** is a language suite with a slick, efficient, flexible syntax, unique
features and useful tools.

Its purpose is to represent structured data effectively.
**Scuff's** greatest strengths are its syntactic simplicity and reliable
flexibility. It comes with a Python API and a simple command line tool for
moving data between JSON syntax, Python's and its own.

One excellent use for **Scuff** is to encode and parse configuration files.

**Scuff** implements its own custom lexer, recursive-descent parser and
transpiler to read and process data. Though written in Python, the parser
is immune from Python's recursion limit.


Installation
=============

To install **Scuff** and its tools for Python from the Python Package Index,
run the following in the command line:

.. code:: bash

    $ python -m pip install scuff


Grammar
========

Assigning Variables
--------------------

Variables are assigned with a *key* and a *value*.
Key names must be valid identifiers, meaning they must contain no spaces or
symbols except underscore (``_``).
Values can be assigned to variables with or without an equals sign (``=``):

.. code:: py

    my_favorite_number = 42
    my_favorite_color "Magenta"
    is_but_a_flesh_wound yes

When left without a value, variables will evaluate to ``null`` or ``None``:

.. code:: py

    set_to_null =
    also_null
    but_this_has_a_value 15


Data Types
-----------

- Numbers
    Numbers can be integers or floats::

        1 1.2 -1_000 0.123 .123_4

- Booleans
    The boolean values ``True`` and ``False`` are given using these variants::

        True true yes
        False false no

    They are case-insensitive, so ``yes`` and ``yES`` both evaluate to ``True``.

- Strings
    Single-line strings can be enclosed by single quotes (``'``), double
    quotes (``"``) or backticks (`````), and multiline strings are enclosed by
    three of any one:

    .. code:: py

        foo "abc"
        bar 'def'
        baz '''Hi,
                did you know
                    you're cute?
                        '''


..
    Strings placed right next to each other are concatenated:

    .. code:: py
        
        first = "ABC"
        second = "DEF"
        first_plus_second = "ABC"  "DEF"
        concatenated = "ABCDEF"
                    
- Lists
    Lists are enclosed by square brackets (``[]``).
    Elements inside lists are separated by spaces, commas or line breaks:

    .. code:: py

        groceries [
            "bread",
            "milk" "eggs"
            "spam"
        ]

- Mappings
    Mappings are groups of key-value pairs enclosed by curly braces (``{}``).
    Values may be any expression, even other mappings:

    .. code:: py

        me {
            name "Samantha"
            age 24
            job "Developer"
            favorite_things {
                editor "Vim"
                languages ["Python", "Rust"]
            }
        }

    Mappings may also take the form of dotted attribute lookups:

    .. code:: py

        outer.middle.inner yes

    evauates in Python to

    .. code:: py

        {'outer': {'middle': {'inner': True}}}


- Comments
    Single-line comments are made using the ``#`` symbol:

    .. code:: py

        option = "The parser reads this."
        # But this is a comment.
            #And so is this.
        option2 = "# But not this; It's inside a string."
        # The parser ignores everything between ``#`` and the end of the line.
         #   ignore = "Comment out any lines of code you want to skip."


Python Usage
============
Once you install **Scuff**, you can then import ``scuff`` as a Python module
and use its tools:

.. code:: py

    >>> import scuff
    >>> scuff.to_json('menu {border.color "#aa22bb", font.color "#cdcdcd"}')
    '{"menu": {"border": {"color": "#aa22bb"}, "font": {"color": "#cdcdcd"}}}'

    >>> type(scuff.to_py('Documents/file.conf'))
    <class 'dict'>

    >>> scuff.to_py('a.b ["c", "d"]')
    {'a': {'b': ['c', 'd']}}

    >>> scuff.parse('hovercraft ["eel" "eel" "eel" "eel"]')
    <ast.Module object at 0x74b59c109710>
    >>> print(scuff.dump(_))
    Module(
      body=[
        Assign(
          targets=[
            Name(id='hovercraft')],
          value=List(
            elts=[
              Constant(value='eel'),
              Constant(value='eel'),
              Constant(value='eel'),
              Constant(value='eel')]))])


Command Line Usage
==================
**Scuff** also comes with a command line tool for converting between formats:

.. code:: none

    usage: scuff [-h] [-j] [-p] [-a] [--debug] [-v] source [source ...]

    positional arguments:
      source           The file path(s) or literal Scuff to process.

    options:
      -h, --help       show this help message and exit
      -j, --to-json    Convert `source` to JSON.
      -p, --to-python  Convert `source` to Python.
      -a, --show-ast   Parse `source` and show its equivalent AST.
      --debug          Use debug mode. (Not implemented)
      -v, --version    show program's version number and exit

Multiple files and strings may be converted in multiple ways at once:

.. code:: bash

    $ python -m scuff --to-json ~/.config/mybar/mybar.conf 'foo {a{b [1,{c 3}]}}'
    {"field_order": ["hostname", "uptime", "cpu_usage", "cpu_temp", "mem_usage", "disk_usage", "battery", "net_stats", "datetime"], "field_icons": {"uptime": ["Up ", "\uf2f2 "], "cpu_usage": ["CPU ", "\uf3fd "], "cpu_temp": ["", "\uf06d "], "mem_usage": ["MEM ", "\uf2db "], "disk_usage": ["/: ", "\uf233 "], "battery": ["BAT ", "\uf242 "], "net_stats": ["", "\uf1eb"]}}

    {"foo": {"a": {"b": [1, {"c": 3}]}}}





            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/akyuute/scuff",
    "name": "scuff",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.12",
    "maintainer_email": null,
    "keywords": "config files, config file format, data serialization language, parsing, compilers, API, AST, structured data",
    "author": "akyuute",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/12/08/7cf6b3bd0ad01b11e16ac240c8630460b919b9a85c27b71a2f589c987630/scuff-0.4.5.tar.gz",
    "platform": "Platform Independent",
    "description": "######\nScuff\n######\n\n*A slick config file format for humans.*\n\n\nIntroduction\n=============\n\n**Scuff** is a language suite with a slick, efficient, flexible syntax, unique\nfeatures and useful tools.\n\nIts purpose is to represent structured data effectively.\n**Scuff's** greatest strengths are its syntactic simplicity and reliable\nflexibility. It comes with a Python API and a simple command line tool for\nmoving data between JSON syntax, Python's and its own.\n\nOne excellent use for **Scuff** is to encode and parse configuration files.\n\n**Scuff** implements its own custom lexer, recursive-descent parser and\ntranspiler to read and process data. Though written in Python, the parser\nis immune from Python's recursion limit.\n\n\nInstallation\n=============\n\nTo install **Scuff** and its tools for Python from the Python Package Index,\nrun the following in the command line:\n\n.. code:: bash\n\n    $ python -m pip install scuff\n\n\nGrammar\n========\n\nAssigning Variables\n--------------------\n\nVariables are assigned with a *key* and a *value*.\nKey names must be valid identifiers, meaning they must contain no spaces or\nsymbols except underscore (``_``).\nValues can be assigned to variables with or without an equals sign (``=``):\n\n.. code:: py\n\n    my_favorite_number = 42\n    my_favorite_color \"Magenta\"\n    is_but_a_flesh_wound yes\n\nWhen left without a value, variables will evaluate to ``null`` or ``None``:\n\n.. code:: py\n\n    set_to_null =\n    also_null\n    but_this_has_a_value 15\n\n\nData Types\n-----------\n\n- Numbers\n    Numbers can be integers or floats::\n\n        1 1.2 -1_000 0.123 .123_4\n\n- Booleans\n    The boolean values ``True`` and ``False`` are given using these variants::\n\n        True true yes\n        False false no\n\n    They are case-insensitive, so ``yes`` and ``yES`` both evaluate to ``True``.\n\n- Strings\n    Single-line strings can be enclosed by single quotes (``'``), double\n    quotes (``\"``) or backticks (`````), and multiline strings are enclosed by\n    three of any one:\n\n    .. code:: py\n\n        foo \"abc\"\n        bar 'def'\n        baz '''Hi,\n                did you know\n                    you're cute?\n                        '''\n\n\n..\n    Strings placed right next to each other are concatenated:\n\n    .. code:: py\n        \n        first = \"ABC\"\n        second = \"DEF\"\n        first_plus_second = \"ABC\"  \"DEF\"\n        concatenated = \"ABCDEF\"\n                    \n- Lists\n    Lists are enclosed by square brackets (``[]``).\n    Elements inside lists are separated by spaces, commas or line breaks:\n\n    .. code:: py\n\n        groceries [\n            \"bread\",\n            \"milk\" \"eggs\"\n            \"spam\"\n        ]\n\n- Mappings\n    Mappings are groups of key-value pairs enclosed by curly braces (``{}``).\n    Values may be any expression, even other mappings:\n\n    .. code:: py\n\n        me {\n            name \"Samantha\"\n            age 24\n            job \"Developer\"\n            favorite_things {\n                editor \"Vim\"\n                languages [\"Python\", \"Rust\"]\n            }\n        }\n\n    Mappings may also take the form of dotted attribute lookups:\n\n    .. code:: py\n\n        outer.middle.inner yes\n\n    evauates in Python to\n\n    .. code:: py\n\n        {'outer': {'middle': {'inner': True}}}\n\n\n- Comments\n    Single-line comments are made using the ``#`` symbol:\n\n    .. code:: py\n\n        option = \"The parser reads this.\"\n        # But this is a comment.\n            #And so is this.\n        option2 = \"# But not this; It's inside a string.\"\n        # The parser ignores everything between ``#`` and the end of the line.\n         #   ignore = \"Comment out any lines of code you want to skip.\"\n\n\nPython Usage\n============\nOnce you install **Scuff**, you can then import ``scuff`` as a Python module\nand use its tools:\n\n.. code:: py\n\n    >>> import scuff\n    >>> scuff.to_json('menu {border.color \"#aa22bb\", font.color \"#cdcdcd\"}')\n    '{\"menu\": {\"border\": {\"color\": \"#aa22bb\"}, \"font\": {\"color\": \"#cdcdcd\"}}}'\n\n    >>> type(scuff.to_py('Documents/file.conf'))\n    <class 'dict'>\n\n    >>> scuff.to_py('a.b [\"c\", \"d\"]')\n    {'a': {'b': ['c', 'd']}}\n\n    >>> scuff.parse('hovercraft [\"eel\" \"eel\" \"eel\" \"eel\"]')\n    <ast.Module object at 0x74b59c109710>\n    >>> print(scuff.dump(_))\n    Module(\n      body=[\n        Assign(\n          targets=[\n            Name(id='hovercraft')],\n          value=List(\n            elts=[\n              Constant(value='eel'),\n              Constant(value='eel'),\n              Constant(value='eel'),\n              Constant(value='eel')]))])\n\n\nCommand Line Usage\n==================\n**Scuff** also comes with a command line tool for converting between formats:\n\n.. code:: none\n\n    usage: scuff [-h] [-j] [-p] [-a] [--debug] [-v] source [source ...]\n\n    positional arguments:\n      source           The file path(s) or literal Scuff to process.\n\n    options:\n      -h, --help       show this help message and exit\n      -j, --to-json    Convert `source` to JSON.\n      -p, --to-python  Convert `source` to Python.\n      -a, --show-ast   Parse `source` and show its equivalent AST.\n      --debug          Use debug mode. (Not implemented)\n      -v, --version    show program's version number and exit\n\nMultiple files and strings may be converted in multiple ways at once:\n\n.. code:: bash\n\n    $ python -m scuff --to-json ~/.config/mybar/mybar.conf 'foo {a{b [1,{c 3}]}}'\n    {\"field_order\": [\"hostname\", \"uptime\", \"cpu_usage\", \"cpu_temp\", \"mem_usage\", \"disk_usage\", \"battery\", \"net_stats\", \"datetime\"], \"field_icons\": {\"uptime\": [\"Up \", \"\\uf2f2 \"], \"cpu_usage\": [\"CPU \", \"\\uf3fd \"], \"cpu_temp\": [\"\", \"\\uf06d \"], \"mem_usage\": [\"MEM \", \"\\uf2db \"], \"disk_usage\": [\"/: \", \"\\uf233 \"], \"battery\": [\"BAT \", \"\\uf242 \"], \"net_stats\": [\"\", \"\\uf1eb\"]}}\n\n    {\"foo\": {\"a\": {\"b\": [1, {\"c\": 3}]}}}\n\n\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A slick config file format for humans.",
    "version": "0.4.5",
    "project_urls": {
        "GitHub: repo": "https://github.com/akyuute/scuff",
        "Homepage": "https://github.com/akyuute/scuff"
    },
    "split_keywords": [
        "config files",
        " config file format",
        " data serialization language",
        " parsing",
        " compilers",
        " api",
        " ast",
        " structured data"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4ea85bae96db61bf8b8c9f1a603d2d88764ceda73484785c38724205ea0e1351",
                "md5": "68a0861b2ab0ee9ea56107a5fb7f8037",
                "sha256": "41727766d691482fbf98d2ca6f632ac4b4f52f6d792981c2539e230bf3e346c1"
            },
            "downloads": -1,
            "filename": "scuff-0.4.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "68a0861b2ab0ee9ea56107a5fb7f8037",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.12",
            "size": 23649,
            "upload_time": "2024-07-27T13:04:22",
            "upload_time_iso_8601": "2024-07-27T13:04:22.178495Z",
            "url": "https://files.pythonhosted.org/packages/4e/a8/5bae96db61bf8b8c9f1a603d2d88764ceda73484785c38724205ea0e1351/scuff-0.4.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "12087cf6b3bd0ad01b11e16ac240c8630460b919b9a85c27b71a2f589c987630",
                "md5": "118d0776f8a12b970f327945cb0920fe",
                "sha256": "7ada73d17a24dbadefa803fb2c36bfbb6002b96467221b060111eb18681a4787"
            },
            "downloads": -1,
            "filename": "scuff-0.4.5.tar.gz",
            "has_sig": false,
            "md5_digest": "118d0776f8a12b970f327945cb0920fe",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.12",
            "size": 23340,
            "upload_time": "2024-07-27T13:04:23",
            "upload_time_iso_8601": "2024-07-27T13:04:23.553253Z",
            "url": "https://files.pythonhosted.org/packages/12/08/7cf6b3bd0ad01b11e16ac240c8630460b919b9a85c27b71a2f589c987630/scuff-0.4.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-27 13:04:23",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "akyuute",
    "github_project": "scuff",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "scuff"
}
        
Elapsed time: 0.27270s