{"id":17465225,"url":"https://github.com/dusktreader/snick","last_synced_at":"2025-10-23T17:44:09.517Z","repository":{"id":42641660,"uuid":"315425972","full_name":"dusktreader/snick","owner":"dusktreader","description":"Several text manipulation gadgets that are useful when dealing with indentation in text","archived":false,"fork":false,"pushed_at":"2024-10-17T18:40:59.000Z","size":77,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-28T04:39:03.477Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","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/dusktreader.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2020-11-23T19:57:09.000Z","updated_at":"2024-10-20T03:08:17.000Z","dependencies_parsed_at":"2024-10-19T20:36:34.266Z","dependency_job_id":null,"html_url":"https://github.com/dusktreader/snick","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dusktreader%2Fsnick","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dusktreader%2Fsnick/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dusktreader%2Fsnick/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dusktreader%2Fsnick/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dusktreader","download_url":"https://codeload.github.com/dusktreader/snick/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241447572,"owners_count":19964314,"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-10-18T11:09:15.568Z","updated_at":"2025-10-23T17:44:09.503Z","avatar_url":"https://github.com/dusktreader.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Latest Version](https://img.shields.io/pypi/v/snick?label=pypi-version\u0026logo=python\u0026style=plastic)](https://pypi.org/project/snick/)\n[![Python Versions](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fdusktreader%2Fsnick%2Fmain%2Fpyproject.toml\u0026style=plastic\u0026logo=python\u0026label=python-versions)](https://www.python.org/)\n[![Build Status](https://github.com/dusktreader/snick/actions/workflows/main.yml/badge.svg)](https://github.com/dusktreader/snick/actions/workflows/main.yml)\n\n# Gadgets for managing indented text\n\nThis library provides several text manipulation gadgets that are useful when dealing with indentation in text. You might\nfind them helpful when you are:\n\n* logging blocks of text\n* testing output\n* formatting machine generated text in a human readable way\n\n\n## What's with the name?\n\nThere's really no very good synonyms for the verb, 'indent'. However, there are several for the act of creating a small\ndent in something. one of my favorites was 'snick'. It means \"to cut a small notch or incision in\". I think I'll use\nthat!\n\n\n## Methods\n\nMost of these methods have additional options and arguments that can be used to augment their output. This is just a\ncursory over-view. Please consult the source code for more details\n\n\n### `dedent()`\n\nThis method unindents a block of text by aligning all lines with the left most\n\nThis is very good if you wish to use python triple-quote strings in your code, like to start the text on its own line,\nbut do not wish to leave them indented:\n\n```python\nclass Whatever:\n\n    @staticmethod\n    def print_some_stuff():\n        print(snick.dedent(\"\"\"\n            Here is some text\n                here is some other text\n                we don't want this indented\n                when it's printed\n                  (to the console)\n        \"\"\"))\n```\n\ncalling `Whatever.print_some_stuff()` will result in dedented output:\n\n```\nHere is some text\n    here is some other text\n    we don't want this indented\n    when it's printed\n      (to the console)\n```\n\n\nThe dedent method also has an optional `should_strip` parameter that, if set to False, will preserve the newlines before\nand after triple quoted text:\n\n```python\n    dummy_text = \"\"\"\n        Here is some text\n            here is some other text\n            we don't want this indented\n            when it's printed\n              (to the console)\n    \"\"\"\n```\n\nCalling `print(snick.dedent(dummy_text, should_strip=False)` will result in dedented output that preserves leading and\nfollowing newlines like so:\n\n```\n\nHere is some text\n    here is some other text\n    we don't want this indented\n    when it's printed\n      (to the console)\n\n```\n\n\n### `indent()`\n\nThis method indents a block of text. It's a thin wrapper around `textwrap.indent()`. However, it includes a default\nprefix of 4 spaces. This could be handy if you want to indent some lines of text that you join with newline:\n\n```python\nprint(snick.indent('\\n'.join([\n    'would be so nice',\n    'to indent these',\n    'i guess',\n])))\n```\n\nThe snippet above will produce:\n\n```\n   would be so nice\n   to indent these\n   i guess\n```\n\nThe `indent` method also provides an option to skip the first line of text:\n\n```python\nprint(snick.indent('\\n'.join([\n    'do not indent me',\n    'indent me, though',\n    'and me',\n])))\n```\n\nThe snippet above will produce:\n\n```\ndo not indent me\n    indent me, though\n    and me\n```\n\n\n### `dedent_all()`\n\nThis function just applies a dedent to each argument you pass it separately and then joins them together. This is useful\nif you want to dynamically produce some items that you need to add to some other long string. Here's an example:\n\n```python\nprint(snick.dedent_all(\n    \"\"\"\n    Here is a long bit of text\n    as an introduction to the\n    following dynamic items:\n    --------------------------\n    \"\"\",\n    *(f\"* Item #{i}\" for i in range(1, 4)),\n))\n```\n\nThe snippet above would produce:\n\n```python\nHere is a long bit of text\nas an introduction to the\nfollowing dynamic items:\n--------------------------\n* Item #1\n* Item #2\n* Item #3\n```\n\n\n### `unwrap()`\n\nThis method unwraps a block of text. It does this by joining all lines into a single string. It works on indented text\nas well. This might be convenient if you have a very indented block of code and you need to type a long string out. You\ncould unwrap a triple-quoted block:\n\n```python\nif True:\n    if True:\n        if True:\n            if True:\n                if True:\n                    if True:\n                        if True:\n                            if True:\n                                print(snick.unwrap(\"\"\"\n                                    I need to have a very long string here, but\n                                    it would go way outside of the line length\n                                    limit and cause me all sorts of grief with\n                                    the style checker. So, unwrap can help me\n                                    here\n                                \"\"\"))\n```\n\nThe above code block would print this:\n```\nI need to have a very long string here, but it would go way outside of the line length limit and cause me all sorts of grief with the style checker. So, unwrap can help me here\n```\n\n\n### `conjoin`\n\nThis method is a lot like the python built-in `join`. The difference is that you don't need to wrap the stuff to wrap in\nan iterable like a list or tuple. Instead, you can just pass the items as arguments to the `conjoin()` function. Here's\nan example:\n\n```python\nprint(snick.conjoin(\n    \"Here are some lines\",\n    \"that I would like to join\",\n    \"and it would be silly\",\n    \"to have to wrap them in a\",\n    \"list instead of just passing\",\n    \"them as plain old arguments\",\n))\n```\n\nThe above code would print this:\n```\nHere are some lines\nthat I would like to join\nand it would be silly\nto have to wrap them in a\nlist instead of just passing\nthem as plain old arguments\n```\n\nThe `conjoin()` function also has a keyword argument `join_str` where you can override the default value (newline) with\nstring you like.\n\n\n### `strip_whitespace()`\n\nThis method just removes all whitespace from a string. This includes newlines, tabs, spaces, etc. This method is handy\nfor writing tests that need to ignore whitespace used for readability/formatting:\n\n```python\nprint(snick.strip_whitespace(\"\"\"\n    some text with    whitespace\n    and whatnot\n\"\"\"))\n```\n\nThe above code block would print out the following:\n```\nsometextwithwhitespaceandwhatnot\n```\n\n\n### `strip_trailing_whitespace()`\n\nThis method just removes all trailing whitespace from each line in a multi-line string:\n\n```python\nprint(snick.strip_trailing_whitespace(\n    snick.conjoin(\n        \"  here is a string with a bundle of    \",\n        \"  trailing whitespace. \",\n        \"  we want it all gone.                    \",\n    )\n)\n```\n\nThe above code block would print out the following:\n```\n  here is a string with a bundle of\n  trailing whitespace.\n  we want it all gone.\n```\n\n\n### `strip_ansi_escape_sequences()`\n\nThis method removes all ANSI escape sequences from text. These are commonly inserted into text by terminal applications\nthat make use of color and effects in the output.\n\nHere's what text looks like when you show the control characters in the code:\n\n```\n\\033[31mhere's some text\\033[0m with\n\\033[32mansi control codes\\033[0m added\n\\033[33mincluding a few\\033[0m\n\\033[34mdifferent colors\\033[0m\n\\033[1mand bold text\\033[0m.\n```\n\nThis will print nicely with red, green, blue and yellow text. However, if you need to include the text in a context\nwhere the control characters can't be interpreted (like some instances in Github actions), they will only cause\nproblems. To remove them, use `strip_ansi_escape_sequences()`:\n\n```python\nprint(snick.strip_ansi_escape_sequences(snick.dedent(\n    \"\"\"\n    \\033[31mhere's some text\\033[0m with\n    \\033[32mansi control codes\\033[0m added\n    \\033[33mincluding a few\\033[0m\n    \\033[34mdifferent colors\\033[0m\n    \\033[1mand bold text\\033[0m.\n    \"\"\"\n)\n```\n\nThis will result in plan text like this:\n\n```\nhere's some text with\nansi control codes added\nincluding a few\ndifferent colors\nand bold text.\"\n```\n\n\n### `indent_wrap()`\n\nThis method is used to wrap a long string and indent each wrapped line. It might be useful for wrapping and indenting\nsome string that's produced programmatically\n\n```python\nprint(\"Here's some filler text:\")\nprint(f\"    {snick.indent_wrap(lorem.text())}\")\n```\n\nThe code block above might generate something like this:\n\n```\nHere's some filler text:\n    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod\n    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\n    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\n    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat\n    non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n```\n\n\n### `pretty_print()`\n\nThis method can be used to pretty-print a dictionary:\n\n```python\nsnick.pretty_print(\"'a': {'b': 1, 'c': {'d': 2}, 'e': 3}, 'f': 4}\")\n```\n\nThe code block above would produce formatted output like this:\n```\n{\n  'a': {\n    'b': 1,\n    'c': {\n      'd': 2,\n    },\n    'e': 3,\n  },\n  'f': 4,\n}\n```\n\n\n### `pretty_format()`\n\nThis method is the same as `pretty_print()` but returns the string instead of printing to a IO stream\n\n\n### `enboxify()`\n\nThis method just draws a box around some text. This is especially useful for logging when you want to make something\nreally pop out:\n\n```python\nprint(snick.enboxify(\"\"\"\n    here's some text that we\n    want to put into a box.\n    That will make it look\n    so very nice\n\"\"\"))\n```\n\nThe code-block above will produce output like this:\n\n```\n****************************\n* here's some text that we *\n* want to put into a box.  *\n* That will make it look   *\n* so very nice             *\n****************************\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdusktreader%2Fsnick","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdusktreader%2Fsnick","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdusktreader%2Fsnick/lists"}