{"id":17942622,"url":"https://github.com/petercamilleri/format_output","last_synced_at":"2025-04-03T13:27:39.314Z","repository":{"id":56847542,"uuid":"162026040","full_name":"PeterCamilleri/format_output","owner":"PeterCamilleri","description":"Formatted bullet points or columns to the console or strings.","archived":false,"fork":false,"pushed_at":"2021-05-19T18:30:25.000Z","size":51,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-09T04:17:09.748Z","etag":null,"topics":["formatting","ruby","rubygem"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/PeterCamilleri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-16T17:48:18.000Z","updated_at":"2023-03-05T04:20:47.000Z","dependencies_parsed_at":"2022-09-09T02:30:32.860Z","dependency_job_id":null,"html_url":"https://github.com/PeterCamilleri/format_output","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/PeterCamilleri%2Fformat_output","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterCamilleri%2Fformat_output/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterCamilleri%2Fformat_output/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterCamilleri%2Fformat_output/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PeterCamilleri","download_url":"https://codeload.github.com/PeterCamilleri/format_output/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247008786,"owners_count":20868424,"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":["formatting","ruby","rubygem"],"created_at":"2024-10-29T03:06:31.407Z","updated_at":"2025-04-03T13:27:39.284Z","avatar_url":"https://github.com/PeterCamilleri.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FormatOutput\n\nThe format_output gem is used to facilitate the creation of CLI programs in\nRuby by formatting data as bullet points, columns, or word wrap to the console,\nstrings, or arrays of strings.\n\nThis gem started out life buried deep within the mysh gem where it served as\nthe data formatting facility for that program. Such was the usefulness of these\nmethods that the long task of splitting them away from mysh was started.\n\nAlong the way, additional capabilities were added to flesh out range of\navailable formatting transformations. The following  are taken from the\nformat_output unit test suite and include:\n\n### Columns\n\nNeat, efficient columns of data are nice:\n\n    0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95\n    1 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96\n    2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 82 87 92 97\n    3 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 83 88 93 98\n    4 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 84 89 94 99\n\n### Bullet Points\n\nHow about making some (bullet) points:\n\n    Name      Wiley Coyote\n    Education Super Genius\n    Incident  Run over by a large truck\n    Status    Flattened and accordion like\n\n### Word Wrap\n\nWell long text can be hard to (word) wrap your head around:\n\n    There are many many stars in the\n    heavens. Lots really. Like billions and\n    billions\n\n    There are many many fishies in the sea.\n    Lots really. Like billions and billions\n\n    There are many many birds in the sky.\n    Lots really. Like billions and billions\n\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'format_output'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install format_output\n\n## Usage\n\n### Formatting Control Parameters\n\nThe formatting of output is controlled by four parameters. These are:\n\nParameter| Description                                                       | Default\n---------|-------------------------------------------------------------------|-----------\nwidth    |The overall width of the output \"stage\".                           | 80\nleft     |The size of the left margin. White space to the left of the data.  | 0\nbody     |The center of the \"stage\" where the formatted data resides.        | 80\nright    |The size of the right margin. White space to the right of the data.| 0\n\nThese relationships are illustrated below:\n\n    |\u003c-------------------------- width ---------------------------\u003e|\n    |\u003cleft  margin\u003e|\u003c------------ body ------------\u003e|\u003cright margin\u003e|\n                     1  4  7  10  13  16  19  22  25\n                     2  5  8  11  14  17  20  23\n                     3  6  9  12  15  18  21  24\n\n      width = 60\n      left  = 14\n      right = 14\n      body  = 32\n\nIn many cases however, the programmer will not need to modify these parameters.\nThat is the defaults values provided are suitable for most application.\n\nIf the defaults are not suitable, there are two approaches that are available:\n\n1. The global parameters can be changed. For example:\n\n    FormatOutput.width = 132\n\n2. The parameters can be set for one call only. For example:\n\n    my_array.format_output_columns(left: 5, right: 5)\n\n\nNote: The format_output parameters are connected in that they define the same\nformatting work area. As a result, the following interactions occur:\n\n    FormatOutput.left            # Gets the left margin\n    FormatOutput.left  = value   # Sets the left margin\n    FormatOutput.right           # Gets the left margin\n    FormatOutput.right = value   # Sets the left margin\n    FormatOutput.width           # Gets the full width\n    FormatOutput.width = value   # Sets the full width\n    FormatOutput.body            # Gets width - (left + right)\n    FormatOutput.width = value   # Sets width = value + left + right\n\nAs can be seen, setting the body and setting the other parameters does interact\nquite a bit. So these rules should be followed:\n\n* Always set left and right margins before setting the body. Otherwise, the\nbody setting will be modified to a value other than the set value.\n* Don't set both the body and the width or unexpected results may be observed.\n\nWhen parameters are passed in for individual calls, they take effect at the\nsame time so the ordering is not significant. Still, setting body and width\nwill have unpredictable results.\n\n### API Levels\n\nEach of the three types of formatting has three levels of support. These are\nsummarized as follows:\n\nColumns                   | Word Wrap                  | Bullet Points            | Returns\n--------------------------|----------------------------|--------------------------|----------------\nputs_format_output_columns|puts_format_output_word_wrap|puts_format_output_bullets| nil\nformat_output_columns     |format_output_word_wrap     |format_output_bullets     | a string\nformat_output_raw_columns |format_output_raw_word_wrap |format_output_raw_bullets | [strings]\n\nThe puts_etc methods return nil because they directly print the results of the\nformatting using the puts method. The intermediate methods return a string,\nreplete with any needed new line characters. Finally the \"raw\" methods return\nan array of strings in place of said new line sequences.\n\nRegardless of how output of the results is achieved, the formatting done is the\nsame for all three levels. The next sections focus on that formatting.\n\n### Columns\n\nThe column format is used to display data in neat columns. Yes sure, you can\njust do a puts on an array of data and it will blast it to the console, one\nitem per line, but that can be a lot off lines scrolling meaninglessly off the\nscreen.\n\nColumn formatting tries to use as few lines of output as it can. For example:\n\n```ruby\n# Some simple number, squared, and cubed columns\ncolumn_data = Array.new(25) { |i| \"#{i}, #{i*i}, #{i*i*i}  \" }\nputs \"Numbers, squares, and cubes.\", \"\"\ncolumn_data.puts_format_output_columns(width: 72)\n```\n\nThe output is:\n\n    Numbers, squares, and cubes.\n\n    0, 0, 0      7, 49, 343      14, 196, 2744   21, 441, 9261\n    1, 1, 1      8, 64, 512      15, 225, 3375   22, 484, 10648\n    2, 4, 8      9, 81, 729      16, 256, 4096   23, 529, 12167\n    3, 9, 27     10, 100, 1000   17, 289, 4913   24, 576, 13824\n    4, 16, 64    11, 121, 1331   18, 324, 5832\n    5, 25, 125   12, 144, 1728   19, 361, 6859\n    6, 36, 216   13, 169, 2197   20, 400, 8000\n\nNow this is not meant to be optimal, but to instead show how neat columns are\ncreated even with items of varying length.\n\n### Word Wrap\n\nThe word wrap format is used to take very long lines of text and convert it\ninto a number of shorter lines. The trick is to avoid splitting words and\nmaking the text hard to read.\n\n```ruby\n# Maybe (word) wrap your head around a little Shakespear?\nlong_text = \"Wherefore rejoice? What conquest brings he home? What tributaries follow him to Rome, to grace in captive bonds his chariot-wheels? You blocks, you stones, you worse than senseless things!\"\nputs \"\", \"\", \"Word wrapping the Great Bard!\", \"\"\nlong_text.puts_format_output_word_wrap(width: 72)\n```\n\nThe output is:\n\n    Word wrapping the Great Bard!\n\n    Wherefore rejoice? What conquest brings he home? What tributaries\n    follow him to Rome, to grace in captive bonds his chariot-wheels? You\n    blocks, you stones, you worse than senseless things!\n\nNow, if the input is an array of really long strings, the word wrapper will\nconvert each of those lines into a neatly word wrapped paragraph with a blank\nline between them.\n\n### Bullet Points\n\nThe bullet point formatter is used to create an output consisting of one or\nmore bullet points. So how is a bullet point defined? There are two essential\ncomponents, illustrated here:\n\n    tag1 detail1\n    tag2 detail2\n    tag3 etc etc etc\n\nSo what is the input? An array of bullet point data of course! That is an array\nof arrays. The following array describes the sample bullet point above:\n\n```ruby\ndatum = [[\"tag1\", \"detail1\"],[\"tag2\", \"detail2\"],[\"tag3\", \"etc etc etc\"]]\ndatum.puts_format_output_bullets\n```\n\nNow, this array contained in the outer array describes the actual bullet points\nthat are created. This inner array may contain zero or more elelemts.\n\n#### Zero Elements and Empty Bullets\n\nWhen an empty array is used, the bullet formatter skips that entry. This can be\nuseful when gathering data for a report and for one item no data is found.\nThere are three ways to create an empty bullet point:\n\n```ruby\n[]\n[\"zero\", []]\n[\"zero\", nil]\n```\n\nNote that the following, is not fully empty\n\n```ruby\n[\"zero\", \"\"]\n```\n\nYields a bullet point with a bullet of \"zero\" and no detail text.\n\n#### One Element\n\nWhen an array with one element is used, that element becomes the detail and the\ndefault bullet (\"*\") is used:\n\n```ruby\n[\"one with a (default) bullet.\"]\n```\n\nproduces:\n\n    *     one with a (default) bullet.\n\n#### Two Elements\n\nWhen an array with two elements is used, the first is the bullet and the second\nis the detail. This is by far the most common:\n\n```ruby\n[\"two\", 2],\n```\n\nproduces:\n\n    two   2\n\n\n#### Three or more Elements\n\nWhen an array with three or more elements is used, the first is the bullet and\nthe second is the detail. The rest of the elements are additional details for\nthis bullet point. Like this:\n\n```ruby\n[\"three\", 3, \"more than two\", \"more than one\", \"more than zero\"],\n```\n\nproduces:\n\n    three 3\n          more than two\n          more than one\n          more than zero\n\n#### The Details\n\nNow we can turn our attention to the actual details and to a lesser extent, the\ntags. These can be:\n\n1. A String\n2. An object that responds favorably to the to_s method.\n\nIn addition, the details may be an Array.\n\nSo when the details are a string that string is used as the details. And yes,\nif the string is too long to fit, it gets word wrapped! Like this:\n\n```ruby\n['five', \"I can see for miles and miles and more miles and yet more miles and a lot of miles and damn more miles\"]\n```\n\nproduces:\n\n    five  I can see for miles and miles and more miles and yet more miles\n          and a lot of miles and damn more miles\n\nNote, this courtesy does not extend to the bullet tags. They must exhibit a\nsensible level of brevity!\n\nFurther, when the details are contained in there own little array, they are\ndisplayed in columns if they don't fit in one line. Look here:\n\n```ruby\n[\"four\", (1..100).to_a]\n```\n\nproduces:\n\n    four  1 6  11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91 96\n          2 7  12 17 22 27 32 37 42 47 52 57 62 67 72 77 82 87 92 97\n          3 8  13 18 23 28 33 38 43 48 53 58 63 68 73 78 83 88 93 98\n          4 9  14 19 24 29 34 39 44 49 54 59 64 69 74 79 84 89 94 99\n          5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100\n\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\nOR...\n\n* Make a suggestion by raising an\n [issue](https://github.com/PeterCamilleri/format_output/issues)\n. All ideas and comments are welcome.\n\n## License\n\nThe gem is available as open source under the terms of the\n[MIT License](./LICENSE.txt).\n\n## Code of Conduct\n\nEveryone interacting in the format_output project’s codebases, issue trackers,\nchat rooms and mailing lists is expected to follow the\n[code of conduct](./CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetercamilleri%2Fformat_output","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpetercamilleri%2Fformat_output","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpetercamilleri%2Fformat_output/lists"}