{"id":13626697,"url":"https://github.com/gruebite/zzz","last_synced_at":"2025-04-16T15:31:31.948Z","repository":{"id":44158795,"uuid":"306171381","full_name":"gruebite/zzz","owner":"gruebite","description":"Simple and boring human readable data format for Zig.","archived":false,"fork":false,"pushed_at":"2023-03-23T17:19:47.000Z","size":119,"stargazers_count":87,"open_issues_count":4,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-08-02T22:27:35.351Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"0bsd","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gruebite.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-10-21T23:27:15.000Z","updated_at":"2024-06-08T01:06:13.000Z","dependencies_parsed_at":"2024-01-25T05:09:22.911Z","dependency_job_id":"2b114841-9226-4494-819a-10417bfa0df6","html_url":"https://github.com/gruebite/zzz","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruebite%2Fzzz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruebite%2Fzzz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruebite%2Fzzz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gruebite%2Fzzz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gruebite","download_url":"https://codeload.github.com/gruebite/zzz/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223716688,"owners_count":17191092,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:02:26.923Z","updated_at":"2024-11-08T16:31:25.826Z","avatar_url":"https://github.com/gruebite.png","language":"Zig","funding_links":[],"categories":["Zig","Libraries"],"sub_categories":[],"readme":"# zzz\n\nSimple and boring human readable data format for Zig.\n\nzzz syntax describes a tree of strings.  It has little syntactic noise and is really easy to implement. The spec does not force any specific rules for escaping or number parsing by design.  Nodes in the tree are string slices.\n\nzzz's focus is to be a simple and lightweight format. This library implements two trees: a static tree which has zero allocations, and a dynamic tree which manages slice and node allocations. Here's an example using the static tree:\n\n```js\n// 100 is the max number of nodes.\nvar tree = zzz.StaticTree(100){};\ntry zzz.appendText(\u0026tree, \"foo:bar\");\n// There is always a root, and its value is empty.\nassert(tree.root.value == \"\");\nassert(tree.root.findNthChild(0, \"foo\") != null);\nassert(tree.root.findNthDescendant(0, \"bar\") != null);\n// Print the tree to standard out.\ntree.root.show();\n```\n\n**Note:** This implementation is being iterated on while I use this for another project. API stability isn't a guarantee quite yet, and will also be subject to changes as Zig changes.\n\n## Use-cases\n\n- Configuration files\n- Game object descriptions\n- Embedded devices\n- Simple serialization format\n\n## Quick example\n\nD\u0026D Kobold stat block. Raw text [here](https://raw.githubusercontent.com/gruebite/zzz/main/examples/example-data/kobold.zzz).\n\n(YAML highlighting used)\n\n```yaml\n# Comments begin with a hash symbol.\n\n# : describes a parent child relationship\nname: Kobold\n\n# , describes a sibling relationship\ntags: small, humanoid, lawful evil\narmor class: 12\n\n# : can appear on the same line, here \"(2d6 - 2)\" is a child of \"5\"\nhit points: 5 : (2d6 - 2)\n\n# This can be used for meta tagging\nspeed: 30 : ft\n\n# Continuing on a newline. The indentation is exactly 2 spaces to describe a parent/child relationship\nstats:\n  str: 7: -2\n  dex: 15: 2\n  con: 9: -1\n  int: 8: -1\n  wis: 7: -2\n  cha: 8: -1\n\n# ; is used to go up in the tree. Here we ascend up from the \"ft\" node\nsenses: darkvision:60:ft;; passive perception:8\nlanguages: common, draconic\nchallenge: 1/8\n\n# Multline strings follow the same rules as Lua's. The first newline on an empty line is skipped\nabilities:\n  sunlight sensitivity: [[\nWhile in sunlight, the kobold has disadvantage on attack\nrolls, as well as on Wisdom (Perception) checks that rely on sight.]]\n  pack tactics: [[\nThe kobold has advantage on an attack roll against a\ncreature if at least one of the kobold's allies is within\n5 feet of the creature and the ally isn't incapacitated.]]\n```\n\n## JSON example\n\nTranslated from http://www.json.org/example.html\n```yaml\nmenu:\n  id: file\n  value: File\n  popup:\n    menuitem:\n      : value: New\n        onclick: CreateNewDoc()\n      : value: Open\n        onclick: OpenDoc()\n      : value: Close\n        oneclick: CloseDoc()\n```\n```json\n{\"menu\": {\n  \"id\": \"file\",\n  \"value\": \"File\",\n  \"popup\": {\n    \"menuitem\": [\n      {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"},\n      {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"},\n      {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}\n    ]\n  }\n}}\n```\n\n# Building \u0026 examples\n\nFor more examples see the source comments and tests.\n\n`zig build test`\n\n`zig build examples`\n\n# Other languages\n\n- **Rust**: https://github.com/MouseProducedGames/ruzzzt\n\n# Syntax highlighting\n\n- **kak**: https://github.com/katesuyu/zzz.kak\n\n# Spec\n\nzzz text describes a tree of strings. Special characters (and spaces) are used to go up and down the tree. The tree has an implicit empty root node.\n\n### Descending the tree:\n```\ngrandparent:parent:child:grandchild\n```\nOutput:\n```\nnull -\u003e \"grandparent\" -\u003e \"parent\" -\u003e \"child\" -\u003e \"grandchild\"\n```\n\n### Traversing the children of root (siblings):\n```\nsibling1,sibling2,sibling3\n```\nOutput:\n```\nnull -\u003e \"sibling1\"\n     -\u003e \"sibling2\"\n     -\u003e \"sibling3\"\n```\n\n### Going up to the parent:\n```\nparent:child;anotherparent\n```\nOutput:\n```\nnull -\u003e \"parent\" -\u003e \"child\"\n     -\u003e \"anotherparent\"\n```\n\n### White space and newlines are significant. A newline will take you back to the root:\n```\nparent:child\nanotherparent\n```\nOutput:\n```\nnull -\u003e \"parent\" -\u003e \"child\"\n     -\u003e \"anotherparent\"\n```\n\n### Exactly two spaces are used to to go down a level in the tree:\n```\nparent:child\n  sibling\n```\nOutput:\n```\nnull -\u003e \"parent\" -\u003e \"child\"\n                 -\u003e \"sibling\"\n```\n\n### You can only go one level deeper than the previous line's depth. Anything more is an error:\n```\nparent:child\n    sibling\n```\nOutput:\n```\nError!\n```\n\n### Trailing commas, semicolons, and colons are optional. So the above (correct one) can be written as:\n```\nparent\n  child\n  sibling\n```\nOutput:\n```\nnull -\u003e \"parent\" -\u003e \"child\"\n                 -\u003e \"sibling\"\n```\n\n### Strings are trimmed:\n```\nparent:     child:      grand child      ;\n```\nOutput:\n```\nnull -\u003e \"parent\" -\u003e \"child\" -\u003e \"grand child\"\n```\n\n### Strings can be quoted with double quotes, single quotes, or Lua strings:\n```\n\"parent\":[[ child ]]:[==[grand child]=]]==]:'great grand child'\n```\nOutput:\n```\nnull -\u003e \"parent\" -\u003e \" child \" -\u003e \"grand child]=]\" -\u003e \"great grand child\"\n```\n\n### Lua strings will skip the first newline if it's empty:\n```\n[[\nsome text]]\n```\nOutput:\n```\nnull -\u003e \"some text\"\n```\n\n### Strings are not escaped and taken as-is.\n```\n\"\\n\\t\\r\"\n```\nOutput:\n```\nnull -\u003e \"\\n\\t\\r\"\n```\n\n### Comments begin with # and run up to the end of the line. Their indentation follows the same rules as nodes.\n```\n# A comment\na node\n  # Another comment\n  a child\n```\nOutput:\n```\nnull -\u003e \"a node\" -\u003e \"a child\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgruebite%2Fzzz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgruebite%2Fzzz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgruebite%2Fzzz/lists"}