{"id":25301620,"url":"https://github.com/p2js/rsformat","last_synced_at":"2025-04-07T01:27:46.997Z","repository":{"id":260508356,"uuid":"881469420","full_name":"p2js/rsformat","owner":"p2js","description":"Formatting/printing library for JavaScript that takes after rust's string formatting","archived":false,"fork":false,"pushed_at":"2025-03-18T14:28:22.000Z","size":24,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-18T15:39:52.217Z","etag":null,"topics":["fmt","format","javascript","printf","println","string-manipulation","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/rsformat","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/p2js.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-10-31T16:25:49.000Z","updated_at":"2025-03-18T14:28:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"4b2cd186-fdfb-4eb7-97a9-f58bac3ae273","html_url":"https://github.com/p2js/rsformat","commit_stats":null,"previous_names":["p2js/rsformat"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p2js%2Frsformat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p2js%2Frsformat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p2js%2Frsformat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/p2js%2Frsformat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/p2js","download_url":"https://codeload.github.com/p2js/rsformat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247576669,"owners_count":20961012,"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":["fmt","format","javascript","printf","println","string-manipulation","typescript"],"created_at":"2025-02-13T06:48:10.280Z","updated_at":"2025-04-07T01:27:46.991Z","avatar_url":"https://github.com/p2js.png","language":"TypeScript","readme":"# RSFormat\n\nRSFormat is a string formatting/printing library for JavaScript. It offers a minimal, yet powerful and flexible alternative to the string formatting and printing provided by `console.log`.\n\n## Motivation\n\n`console.log` is an odd method: its output can be affected by functions called before/after it (such as `console.group`), or their order affected by what parameters there are. For example, when calling `console.log(string, number)`, number can come either after or inside `string` depending on the value of `string`.\n\nRSFormat provides alternative functions with standardised behaviour: its `format`, `println` and all other functions will always output in the same manner, and have a standardised syntax which will only print the initial string, formatted with the parameters provided afterwards.\n\nRust formatting also includes a lot of convenient operators for formatting text, such as padding/alignment, printing numbers in a given base, specifying decimal precision, etc.. This makes it a more ergonomic and convenient approach to printing things to the console.\n\n## Usage\n\nyou can install rsformat using [npm](https://www.npmjs.com/package/rsformat):\n\n```\nnpm install rsformat\n```\n\n### Basic formatting and printing to console\n\nRSFormat functions are called using a format string, and any number of format arguments following it.\n\nAny instance of `{}` in the format strings will get replaced with a value.\n\nYou can specify what value you want in the parameters by using a number inside the insertion point.\n\n```js\nimport { format, println } from 'rsformat';      // ESM\nconst { format, println } = require('rsformat'); // CommonJS\n\nlet name = 'everyone';\n\nlet greeting = format('Hello {}!', name); // Evaluates to the string 'Hello, everyone!'\n\nprintln('I have {1} apples and {0} oranges', 13, 14); // Will print 'I have 14 apples and 13 oranges' to the console\n```\n\n### Format Specifiers\n\nFormat specifiers can be used by adding `:` inside the insertion point (after the optional argument number), and will format the value differently inside the string. See the [rust format docs](https://doc.rust-lang.org/std/fmt/#syntax) for more detailed information on format specifiers.\n\nThis implementation differs from the rust one in a few ways:\n\n- Named arguments before or in format specifiers or in values aren't allowed, only numbers can be used.\n- The `-` sign (unused in rust) is unsupported.\n- Pointer format type `p` is unsupported.\n- Hexadecimal debug types `x?` and `X?` are unsupported. \n- Specifying precision with `*` is unsupported.\n\n#### Different formatting types\n\n```js\n// Debug format specifier: ?, uses util.inspect rather than toString\n\nprintln('{}', { a: 1 }); //prints '[object Object]'\nprintln('{:?}', { a: 1 }); //prints \"{ a:1 }\"\n\n// Number base specifiers: x, X, b, o - for lower/uppercase hexadecimal, binary, octal\n\nformat('{} is {0:x} in hex, {0:b} in binary and {0:o} in octal', 15); // '15 is f in hex, 1111 in binary and 17 in octal'\n\n// Scientific notation specifiers: e, E - for lower/uppercase scientific notation\n\nlet hugeNumber = 1000n;\nformat('{:E}', hugeNumber); // '1E3';\n```\n\n#### Padding, Alignment\n\nValues can be aligned using any fill character (will default to a space ` `), and either left, center or right aligned with `\u003c`, `^` or `\u003e` respectively (will default to right alignment `\u003e`). You will also have to specify a width with an integer after the alignment:\n\n```js\n/*\nWill print a pyramid of 'a's:\n'  a  '\n' aaa '\n'aaaaa'\n*/\nlet pyramidLevels = ['a', 'aaa', 'aaaaa'];\nfor(let value of pyramidLevels) {\n    println('{:^5}', value);\n}\n```\n\n```js\nformat('{:.\u003e7}', [1,2]); // '....1,2'\n```\n\n#### Pretty Printing\n\nIn some instances (namely debug, binary, octal and hexadecimal formatting), adding a `#` before the format specifier will use an alternative 'pretty' printing style. This amounts to using non-compact `util.inspect` for debug printing (spanning multiple lines), and adding 0b/0o/0x as a prefix for the numbers formatted as powers of two.\n\n```js\nformat('{:#X}', 255); // '0xFF'\n```\n\n#### Specific Number Formatting\n\nSpecifically for `number` and `bigint` values, a 0 can be placed before the width to pad the number with 0s instead. This will account for signs and possible formatting differences.\n\n```js\nformat('{:#07x}', 15) // '0x0000F'\n```\n\nDecimal precision can be specified for numbers by adding a . and specifying an integer for precision.\n\n```js\nformat('{:.3}', 1.23456789); // '1.234'\nformat('{:.3}', -1);         // '-1.000'\n```\n\nAdding a + to the formatting specifier will print the sign regardless of whether the number is negative.\n\n```js\nformat('{:+}', 1); // '+1'\n```\n\n## Custom output\n\nIf you want to use the print function to output to anything other than `process.stdout` and `process.stderr`, you can import the `Printer` function to create your own print functions, using any output and error streams that are instances of node's `Writable`.\n\n```ts\n// Custom output example (ts)\nimport { Printer } from 'rsformat/print';\nimport { Writable } from 'stream';\n\nlet someOutputStream: Writable = /* ... */;\nlet someErrorStream: Writable = /* ... */;\n\nlet { print, println, eprint, eprintln } = Printer(someOutputStream, someErrorStream);\n```\n\n## A Note on Performance\n\nYou might think that these utilities might have a performance impact on RSFormat's printing functions. And while they do, the functions are still consistently faster than `console.log`.\n\nA simple benchmark setup like the one below will demonstrate that `println` is more performant, even when doing things like base conversions and text alignment, compared to `console.log` logging a simple string:\n\n```js\n// benchmark.mjs\nimport { println } from 'rsformat';\n\nconst time = (fn, iter) =\u003e {\n    let time = Date.now();\n    while (iter-- \u003e 0) {\n        fn();\n    }\n    return Date.now() - time;\n}\n\nlet iterations = 100000;\n\nlet logTime = time(() =\u003e console.log('hello'), iterations);\nlet printlnTime = time(() =\u003e println('{:\u003e+#7X}', 255), iterations);\n\nprintln('console.log time for {} executions: {}ms', iterations, logTime);\nprintln('rsformat.println time for {} executions: {}ms', iterations, printlnTime);\n```\n\n```\n\u003e node benchmark.mjs\n...After a lot of output...\n\nconsole.log time for 100000 executions: 7217ms\nrsformat.println time for 100000 executions: 5900ms\n```\n\n_Tested on node.js using a Windows laptop on an Intel core I7-1360P, on battery power. Performance will vary, but this benchmark was just to show that RSFormat has no performance penalty._","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp2js%2Frsformat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fp2js%2Frsformat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp2js%2Frsformat/lists"}