{"id":13475363,"url":"https://github.com/muesli/reflow","last_synced_at":"2025-05-14T10:11:19.420Z","repository":{"id":36445802,"uuid":"224502256","full_name":"muesli/reflow","owner":"muesli","description":"A collection of (ANSI-sequence aware) text reflow operations \u0026 algorithms","archived":false,"fork":false,"pushed_at":"2024-04-18T19:08:14.000Z","size":102,"stargazers_count":679,"open_issues_count":26,"forks_count":42,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-03T18:11:12.514Z","etag":null,"topics":["ansi","dedent","hacktoberfest","indentation","margin","padding","wordwrap"],"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/muesli.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"muesli"}},"created_at":"2019-11-27T19:24:45.000Z","updated_at":"2025-03-28T17:56:57.000Z","dependencies_parsed_at":"2022-08-08T15:00:26.105Z","dependency_job_id":"0bfec75e-21db-4b8d-8842-bb27c34c50c8","html_url":"https://github.com/muesli/reflow","commit_stats":{"total_commits":90,"total_committers":10,"mean_commits":9.0,"dds":"0.33333333333333337","last_synced_commit":"83f63799117108248750298720ed34dd55d5201a"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muesli%2Freflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muesli%2Freflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muesli%2Freflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/muesli%2Freflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/muesli","download_url":"https://codeload.github.com/muesli/reflow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248338025,"owners_count":21087149,"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":["ansi","dedent","hacktoberfest","indentation","margin","padding","wordwrap"],"created_at":"2024-07-31T16:01:19.754Z","updated_at":"2025-04-11T03:36:36.334Z","avatar_url":"https://github.com/muesli.png","language":"Go","readme":"# reflow\n\n[![Latest Release](https://img.shields.io/github/release/muesli/reflow.svg)](https://github.com/muesli/reflow/releases)\n[![Build Status](https://github.com/muesli/reflow/workflows/build/badge.svg)](https://github.com/muesli/reflow/actions)\n[![Coverage Status](https://coveralls.io/repos/github/muesli/reflow/badge.svg?branch=master)](https://coveralls.io/github/muesli/reflow?branch=master)\n[![Go ReportCard](https://goreportcard.com/badge/muesli/reflow)](https://goreportcard.com/report/muesli/reflow)\n[![GoDoc](https://godoc.org/github.com/golang/gddo?status.svg)](https://pkg.go.dev/github.com/muesli/reflow)\n\nA collection of ANSI-aware methods and `io.Writers` helping you to transform\nblocks of text. This means you can still style your terminal output with ANSI\nescape sequences without them affecting the reflow operations \u0026 algorithms.\n\n## Word-Wrapping\n\nThe `wordwrap` package lets you word-wrap strings or entire blocks of text.\n\n```go\nimport \"github.com/muesli/reflow/wordwrap\"\n\ns := wordwrap.String(\"Hello World!\", 5)\nfmt.Println(s)\n```\n\nResult:\n```\nHello\nWorld!\n```\n\nThe word-wrapping Writer is compatible with the `io.Writer` / `io.WriteCloser` interfaces:\n\n```go\nf := wordwrap.NewWriter(limit)\nf.Write(b)\nf.Close()\n\nfmt.Println(f.String())\n```\n\nCustomize word-wrapping behavior:\n\n```go\nf := wordwrap.NewWriter(limit)\nf.Breakpoints = []rune{':', ','}\nf.Newline = []rune{'\\r'}\n```\n\n## Unconditional Wrapping\n\nThe `wrap` package lets you unconditionally wrap strings or entire blocks of text.\n\n```go\nimport \"github.com/muesli/reflow/wrap\"\n\ns := wrap.String(\"Hello World!\", 7)\nfmt.Println(s)\n```\n\nResult:\n```\nHello W\norld!\n```\n\nThe unconditional wrapping Writer is compatible with the `io.Writer` interfaces:\n\n```go\nf := wrap.NewWriter(limit)\nf.Write(b)\n\nfmt.Println(f.String())\n```\n\nCustomize word-wrapping behavior:\n\n```go\nf := wrap.NewWriter(limit)\nf.Newline = []rune{'\\r'}\nf.KeepNewlines = false\nf.PreserveSpace = true\nf.TabWidth = 2\n```\n\n**Tip:** This wrapping method can be used in conjunction with word-wrapping when word-wrapping is preferred but a line limit has to be enforced:\n\n```go\nwrapped := wrap.String(wordwrap.String(\"Just an example\", 5), 5)\nfmt.Println(wrapped)\n```\n\nResult:\n```\nJust\nan\nexamp\nle\n```\n\n\n### ANSI Example\n\n```go\ns := wordwrap.String(\"I really \\x1B[38;2;249;38;114mlove\\x1B[0m Go!\", 8)\nfmt.Println(s)\n```\n\nResult:\n\n![ANSI Example Output](https://github.com/muesli/reflow/blob/master/reflow.png)\n\n## Indentation\n\nThe `indent` package lets you indent strings or entire blocks of text.\n\n```go\nimport \"github.com/muesli/reflow/indent\"\n\ns := indent.String(\"Hello World!\", 4)\nfmt.Println(s)\n```\n\nResult:\n```\n    Hello World!\n```\n\nThere is also an indenting Writer, which is compatible with the `io.Writer`\ninterface:\n\n```go\n// indent uses spaces per default:\nf := indent.NewWriter(width, nil)\n\n// but you can also use a custom indentation function:\nf = indent.NewWriter(width, func(w io.Writer) {\n    w.Write([]byte(\".\"))\n})\n\nf.Write(b)\nf.Close()\n\nfmt.Println(f.String())\n```\n\n## Dedentation\n\nThe `dedent` package lets you dedent strings or entire blocks of text.\n\n```go\nimport \"github.com/muesli/reflow/dedent\"\n\ninput := `    Hello World!\n  Hello World!\n`\n\ns := dedent.String(input)\nfmt.Println(s)\n```\n\nResult:\n\n```\n  Hello World!\nHello World!\n```\n\n## Padding\n\nThe `padding` package lets you pad strings or entire blocks of text.\n\n```go\nimport \"github.com/muesli/reflow/padding\"\n\ns := padding.String(\"Hello\", 8)\nfmt.Println(s)\n```\n\nResult: `Hello___` (the underlined portion represents 3 spaces)\n\nThere is also a padding Writer, which is compatible with the `io.WriteCloser`\ninterface:\n\n```go\n// padding uses spaces per default:\nf := padding.NewWriter(width, nil)\n\n// but you can also use a custom padding function:\nf = padding.NewWriter(width, func(w io.Writer) {\n    w.Write([]byte(\".\"))\n})\n\nf.Write(b)\nf.Close()\n\nfmt.Println(f.String())\n```\n","funding_links":["https://github.com/sponsors/muesli"],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuesli%2Freflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmuesli%2Freflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmuesli%2Freflow/lists"}