Printj
:scroll: sprintf for JS
Install / Use
/learn @SheetJS/PrintjREADME
printj
Extended sprintf implementation (for the browser and nodejs). Emphasis on
compliance, performance and IE6+ support.
PRINTJ.sprintf("Hello %s!", "World");
A self-contained specification of the printf format string is included below in this README, as well as a summary of the support against various printf implementations
Table of Contents
<details> <summary><b>Table of Contents</b> (click to show)</summary> <!-- toc -->- printf format string specification
- C Data Model
- Integer Conversions
- Restricting Integer Values
- Length Specifiers for Integer Conversions
- Rendering Unsigned Integers in Base 10 ("u" and "U" conversions)
- Rendering Unsigned Integers in Base 8 ("o" and "O" conversions)
- Rendering Unsigned Integers in Base 16 ("x" and "X" conversions)
- Rendering Signed Integers in Base 10 ("d" "i" and "D" conversions)
- Floating Point Conversions
- Character Conversions
- Non-Numeric Conversions
- Extensions
- Miscellaneous Notes
Installation
With npm:
$ npm install printj
In the browser:
<script src="printj.js"></script>
The browser exposes a variable PRINTJ
When installed globally, npm installs a script printj that renders the format
string with the given arguments. Running the script with -h displays help.
The script will manipulate module.exports if available. This is not always
desirable. To prevent the behavior, define DO_NOT_EXPORT_PRINTJ
ES Module Support
The bundle ships with a printj.mjs script that acts as an ES Module.
NodeJS
NodeJS 12+ support ES modules. The default import uses the CommonJS script:
import PRINTJ from "printj";
It is possible to use the ESM powered script referencing printj.mjs directly:
import * as PRINTJ from "printj/printj.mjs"; // pull all exports
import { sprintf } from "printj/printj.mjs"; // pull `sprintf`
Browser Module Support
Chrome 61+ and Safari 11+ support module imports in the web browser. The .mjs
script can be imported from a script type=module block:
<script type="module">
import { sprintf } from './printj.mjs';
console.log(sprintf("%02hhx", 123));
</script>
Usage
In all cases, the relevant function takes a format and arguments to be rendered.
The return value is a JS string.
-
PRINTJ.sprintf(format, ...args)assumes the arguments are passed directly -
PRINTJ.vsprintf(format, argv)assumes the arguments are passed in an array
For example:
> // var PRINTJ = require('printj'); // uncomment this line if in node
> var sprintf = PRINTJ.sprintf, vsprintf = PRINTJ.vsprintf;
> sprintf("Hello %s", "SheetJS") // 'Hello SheetJS'
> sprintf("%d + %d = %d", 2,3,2+3) // '2 + 3 = 5'
> vsprintf("%d + %d = %d", [2,3,5]) // '2 + 3 = 5'
> sprintf("%1$02hhx %1$u %1$i %1$o", -69) // 'bb 4294967227 -69 37777777673'
The command line script takes a format and arguments:
usage: printj [options] <format> [args...]
Options:
-h, --help output usage information
-d, --dump print debug information about format string
Arguments are treated as strings unless prefaced by a type indicator:
n:<integer> call parseInt (ex. n:3 -> 3)
f:<float> call parseFloat (ex. f:3.1 -> 3.1)
b:<boolean> false when lowercase value is "FALSE" or "0", else true
s:<string> interpret as string (ex. s:n:3 -> "n:3")
j:<JSON> interpret as an object using JSON.parse
e:<JS> evaluate argument (ex. e:1+1 -> 2, e:"1"+1 -> "11")
samples:
$ printj '|%02hhx%d|' n:50 e:0x7B # |32123|
$ printj '|%2$d + %3$d is %1$d|' e:1+2 n:1 n:2 # |1 + 2 is 3|
$ printj '|%s is %s|' s:1+2 e:1+2 # |1+2 is 3|
$ printj '|%c %c|' s:69 n:69 # |6 E|
Testing
make test will run the nodejs-based test.
make stress will run a larger test encompassing every possible conversion. It
requires access to a C compiler.
License
Please consult the attached LICENSE file for details. All rights not explicitly granted by the Apache 2.0 license are reserved by the Original Author.
Badges
printf format string specification
The printf family of functions attempt to generate and output a string of
characters from a series of arguments, following a user-supplied "format string"
specification. The format string contains normal characters that are written to
the output string as well as specifiers that describe which parameter to insert
and how to render the parameter. This specification describes how a conformant
implementation should process the format string and generate an output string.
Any discrepancies between this document and the reference implementation are
considered bugs in the implementation.
Original C Interface
Every function in the printf family follows the same logic to generate strings
but have different interfaces reflecting different input and output behaviors.
Some functions have wide variants that use wide wchar_t * strings rather than
normal C char *. The following variants are required by the POSIX spec:
| function | max length | output destination | vintage | wide form |
|:-----------|:-----------|:----------------------|:--------|:-----------|
| printf | unbounded | standard output | K&R | wprintf |
| fprintf | unbounded | stream (FILE *) | K&R | fwprintf |
| sprintf | unbounded | string (char *) | K&R | swprintf |
| snprintf | parameter | string (char *) | C99 | |
| dprintf | unbounded | POSIX file descriptor | POSIX | |
Each function has a dual function, whose name begins with v, that accepts the
parameters as a va_list rather than formal parameters. In all cases, they
return the number of characters written or a negative value to indicate error:
int sprintf(char *ostr, const char *fmt, ...);
int vsprintf(char *ostr, const char *fmt, va_list arg_list);
int swprintf(wchar_t *ostr, const wchar_t *fmt, ...);
int vswprintf(wchar_t *ostr, const wchar_t *fmt, va_list arg_list);
JS and C strings
C "strings" are really just arrays of numbers. An extern
