)]}'
{
  "commit": "3570070ce803501a5e86f1c38759180a42e7d62a",
  "tree": "7df89b1bfd4b3e59d919b25258b2834d9c8ce74d",
  "parents": [
    "048d75aa5f881235c88256b6d3fdaaaeadb5aa32"
  ],
  "author": {
    "name": "Travis Cross",
    "email": "tc@traviscross.com",
    "time": "Thu May 15 12:26:55 2025 +0000"
  },
  "committer": {
    "name": "Travis Cross",
    "email": "tc@traviscross.com",
    "time": "Thu May 15 14:54:37 2025 +0000"
  },
  "message": "Parse optionals and repeats without regexes\n\nRather than parsing optionals and repeats fully in the recursive\ndescent style, we were using regular expressions to do part of the\nmatching and parsing.  That\u0027s fine for what it is, but as we think\nabout extending the grammar language surrounding repeats further, it\nmight be more straightforward for this to be parsed in the more usual\nway.  So let\u0027s do that.  Doing this also results in better and more\ntargeted errors when parsing malformed syntax.\n\nWe had been supporting a space between an expression and the optional\nand repeat sigils `?`, `*`, and `+` (but not between an expression and\nthe `{a..b}` ranged repeat syntax).  In making this change, we drop\nthis support and adjust the affected productions.  We were only using\nthis in a handful of places, and the clarity of the productions seem\nthe same or better by removing these spaces.\n\nWe verified that, setting aside the removal of these spaces, the\nrendered output of the Reference is byte identical before and after\nthis change.\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "60ca740f676f03d2fec3e7033ddf62fe54c9ef84",
      "old_mode": 33188,
      "old_path": "mdbook-spec/src/grammar/parser.rs",
      "new_id": "7a92f47729653f78d6885ee9d80f8bb836a998e6",
      "new_mode": 33188,
      "new_path": "mdbook-spec/src/grammar/parser.rs"
    },
    {
      "type": "modify",
      "old_id": "33491587d889ce4da60b599c1746a7ce4b2beba7",
      "old_mode": 33188,
      "old_path": "src/items/generics.md",
      "new_id": "3a2e98a0ae6ccfa18e4efe0da5e8d389c47f25c5",
      "new_mode": 33188,
      "new_path": "src/items/generics.md"
    },
    {
      "type": "modify",
      "old_id": "2d9ddb5acb3be0a0e509f13c4f097237015f2ea8",
      "old_mode": 33188,
      "old_path": "src/patterns.md",
      "new_id": "e3a5c18dfbfbba30e28d5f600390cce860401084",
      "new_mode": 33188,
      "new_path": "src/patterns.md"
    }
  ]
}
