{"id":29867410,"url":"https://github.com/dpb587/cursorio-go","last_synced_at":"2025-07-30T13:36:28.701Z","repository":{"id":303035934,"uuid":"967067987","full_name":"dpb587/cursorio-go","owner":"dpb587","description":"Utilities for referencing byte and line+column offsets in UTF-8 streams.","archived":false,"fork":false,"pushed_at":"2025-04-15T22:08:22.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-05T09:42:56.647Z","etag":null,"topics":["go","offsets","tokenizer","util"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dpb587.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,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-15T22:04:47.000Z","updated_at":"2025-04-15T22:40:35.000Z","dependencies_parsed_at":"2025-07-05T09:43:01.713Z","dependency_job_id":"2d75c5d5-4271-4f0f-b7ef-f8e30f519c4b","html_url":"https://github.com/dpb587/cursorio-go","commit_stats":null,"previous_names":["dpb587/cursorio-go"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dpb587/cursorio-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpb587%2Fcursorio-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpb587%2Fcursorio-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpb587%2Fcursorio-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpb587%2Fcursorio-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dpb587","download_url":"https://codeload.github.com/dpb587/cursorio-go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpb587%2Fcursorio-go/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267875829,"owners_count":24158783,"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","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["go","offsets","tokenizer","util"],"created_at":"2025-07-30T13:36:17.129Z","updated_at":"2025-07-30T13:36:28.693Z","avatar_url":"https://github.com/dpb587.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cursorio-go\n\nUtilities for referencing byte and line+column offsets in UTF-8 streams.\n\n## Usage\n\nImport the module and refer to the code's documentation ([pkg.go.dev](https://pkg.go.dev/github.com/dpb587/cursorio-go/cursorio)).\n\n```go\nimport \"github.com/dpb587/cursorio-go/cursorio\"\n```\n\nSome sample use cases and starter snippets can be found in the [`examples` directory](examples).\n\n\u003cdetails\u003e\u003csummary\u003e\u003ccode\u003eexamples$ go run ./\u003cstrong\u003eline-dump\u003c/strong\u003e \u003c\u003c\u003c'\u003cstrong\u003eA-𝄞-Clef\u003c/strong\u003e'\u003c/code\u003e\u003c/summary\u003e\n\n```\nA\n^ byte-offset 0; byte-count 1; text-range L1C1:L1C2\n\nA-\n ^ byte-offset 1; byte-count 1; text-range L1C2:L1C3\n\nA-𝄞\n  ^ byte-offset 2; byte-count 4; text-range L1C3:L1C4\n\nA-𝄞-\n   ^ byte-offset 6; byte-count 1; text-range L1C4:L1C5\n==== range L1C1:L1C5;0x0:0x7\n\nA-𝄞-C\n    ^ byte-offset 7; byte-count 1; text-range L1C5:L1C6\n ==== range L1C2:L1C6;0x1:0x8\n\nA-𝄞-Cl\n     ^ byte-offset 8; byte-count 1; text-range L1C6:L1C7\n  ==== range L1C3:L1C7;0x2:0x9\n\nA-𝄞-Cle\n      ^ byte-offset 9; byte-count 1; text-range L1C7:L1C8\n   ==== range L1C4:L1C8;0x6:0xa\n\nA-𝄞-Clef\n       ^ byte-offset 10; byte-count 1; text-range L1C8:L1C9\n    ==== range L1C5:L1C9;0x7:0xb\n\n```\n\n\u003c/details\u003e\n\nMore complex usage can be seen from importers like [inspecthtml-go](https://github.com/dpb587/inspecthtml-go), [inspectjson-go](https://github.com/dpb587/inspectjson-go), and [rdfkit-go](https://github.com/dpb587/rdfkit-go).\n\n## Primitives\n\nThe `TextLineColumn` is a pair of `int64` values representing a line and its column. Within code it is 0-based, but its string form is 1-based and intended for humans. That is, the very first symbol of a stream starts from `TextLineColumn{0, 0}` which is printed as `L1C1`.\n\nThe `Offset` interface represents a position within a stream and is implemented by:\n\n* `ByteOffset` as an `int64` value and formatted as `0x%x`.\n* `TextOffset` as a `ByteOffset` + `TextLineColumn` tuple and formatted as `L%dC%d;0x%x`.\n\nThe `OffsetRange` interface represents a selection within a stream marked by two offsets. The `ByteOffsetRange` and `TextOffsetRange` implementations both contain two fields, `From` (inclusive) and `Until` (exclusive), for their respective offsets.\n\n## Text Writer\n\nThe `TextWriter` supports tracking the lines and columns of a Unicode document. It acts as a standard `io.Writer` with getter functions for the current offsets, but offers several additional functions which may be more useful to lower-level tokenizer/scanner-type implementations.\n\n* `WriteForOffset` will write a slice of bytes and return a `TextOffset`.\n* `WriteForOffsetRange` will write a slice of bytes and return their `TextOffsetRange`.\n* `WriteRunesForOffset` will write a slice of runes and return a `TextOffset`.\n* `WriteRunesForOffsetRange` will write a slice of runes and return their `TextOffsetRange`.\n\n\u003e [!NOTE]\n\u003e As a reminder, Unicode makes line and column tracking non-trivial with its multi-byte code points and grapheme clusters. Put another way, N-bytes != N-runes != N-\"columns\" of printed symbols. This tries to abstract those complexities.\n\nIn code, use `NewTextWriter` to create an instance with an initial offset and begin writing.\n\n```go\nw := cursorio.NewTextWriter(cursorio.TextOffset{})\n_ = w.WriteForOffsetRange([]byte([]rune{0x1f477, 0x1f3fc}))\n// cursorio.TextOffsetRange{\n//   From:cursorio.TextOffset{Byte:0, LineColumn:cursorio.TextLineColumn{0, 0}},\n//   Until:cursorio.TextOffset{Byte:8, LineColumn:cursorio.TextLineColumn{0, 1}},\n// }\n```\n\n## License\n\n[MIT License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpb587%2Fcursorio-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdpb587%2Fcursorio-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpb587%2Fcursorio-go/lists"}