Skip to content

Commit 9a0e855

Browse files
fixed bugs
1 parent 47f2aeb commit 9a0e855

8 files changed

Lines changed: 196 additions & 28 deletions

File tree

.github/workflows/npm-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ jobs:
3030
run: npm run build
3131

3232
- name: Publish to npm
33-
run: npm publish
33+
run: npm publish --provenance --access public
3434
env:
3535
NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# Release Notes
22

3+
## [v2.0.2](https://github.com/jsvibe/printfy/compare/v2.0.1...v2.0.2) - 01 August 2025
4+
5+
Update `README.md` to Enhance more documentatio. [@indianmodassir](https://github.com/indianmodassir)
6+
Fix bugs, `vprintf` and `vsprintf` was not proper working throwing argument error. we fixed it, [@indianmodassir](https://github.com/indianmodassir)
7+
38
## [v2.0.0](https://github.com/jsvibe/printfy/compare/v1.0.0...v2.0.0) - 01 August 2025
49

510
* Rename `sprint` method to `sprintf` in `printfy` module to better reflect its functionality. [@indianmodassir](https://github.com/indianmodassir)
611
* Rename `vsprint` method to `vsprintf` in `printfy` module to better reflect its functionality. [@indianmodassir](https://github.com/indianmodassir)
712
* Add `vprintf` in `printfy` for formatted output using variable arguments. [@indianmodassir](https://github.com/indianmodassir)
8-
* Fix bugs specifier `%%` was not proper working. [@indianmodassir](https://github.com/indianmodassir)
13+
* Fix bugs, specifier `%%` was not proper working. [@indianmodassir](https://github.com/indianmodassir)

README.md

Lines changed: 93 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ A lightweight JavaScript library implements C-style `printf` functionality.
1111

1212
## 🌟 Features
1313

14-
- Fully functional `printf`, `sprint`, and `vsprint` methods.
14+
- Fully functional `printf`, `sprintf`, and `vsprintf` methods.
1515
- C-style format specifiers support:
1616
- `%d`, `%f`, `%s`, `%x`, `%b`, `%o`, `%u`, `%c`, `%e`, `%g`, `%G`, etc.
1717
- Padding, alignment, width, and precision controls
@@ -51,7 +51,7 @@ Below are some of the most common ways to include printfy.
5151
**CDN Link**
5252

5353
```html
54-
<script src="https://cdn.jsdelivr.net/npm/printfy@2.0.1/dist/printfy.min.js"></script>
54+
<script src="https://cdn.jsdelivr.net/npm/printfy@2.0.2/dist/printfy.min.js"></script>
5555
```
5656

5757
You can add the script manually to your project:
@@ -64,15 +64,15 @@ You can add the script manually to your project:
6464
There are several ways to use [Webpack](https://webpack.js.org/), [Browserify](http://browserify.org/) or [Babel](https://babeljs.io/). For more information on using these tools, please refer to the corresponding project's documentation. In the script, including printfy will usually look like this:
6565

6666
```js
67-
import {sprint, printf, vsprint} from "printfy";
67+
import {sprintf, printf, vprintf, vsprintf} from "printfy";
6868
```
6969

7070
### Node.js
7171

7272
Fully compatible with [Node.js](https://nodejs.org/), this library lets you use familiar C-style printf formatting in server-side code—ideal for CLI tools, logging, and backend output formatting.
7373

7474
```js
75-
const {sprint, printf, vsprint} = require("printfy");
75+
const {sprintf, printf, vprintf, vsprintf} = require("printfy");
7676
```
7777

7878
---
@@ -87,19 +87,27 @@ printf("Hello %s, you have %d new messages", "Alice", 5);
8787
// Output: Hello Alice, you have 5 new messages
8888
```
8989

90-
### `sprint(format, ...args)`
90+
### `vprintf(format, args[])`
91+
Logs the formatted output to the console.
92+
93+
```js
94+
printf("Hello %s, you have %d new messages", [ "Alice", 5]);
95+
// Output: Hello Alice, you have 5 new messages
96+
```
97+
98+
### `sprintf(format, ...args)`
9199
Returns a formatted string (like `sprintf` in C).
92100

93101
```js
94-
let result = sprint("Value: %08.2f", 3.14);
102+
let result = sprintf("Value: %08.2f", 3.14);
95103
console.log(result); // Output: Value: 00003.14
96104
```
97105

98-
### `vsprint(format, args[])`
99-
Same as `sprint`, but accepts arguments as an array.
106+
### `vsprintf(format, args[])`
107+
Same as `sprintf`, but accepts arguments as an array.
100108

101109
```js
102-
vsprint("User: %s, Score: %d", ["Bob", 100]);
110+
vsprintf("User: %s, Score: %d", ["Bob", 100]);
103111
// Output: User: Bob, Score: 100
104112
```
105113

@@ -109,7 +117,7 @@ vsprint("User: %s, Score: %d", ["Bob", 100]);
109117

110118
| Specifier | Meaning | Example |
111119
|-----------|---------------------------------------|---------------------------------|
112-
| `%s` | String | `sprint("%s", "abc")``"abc"` |
120+
| `%s` | String | `sprintf("%s", "abc")``"abc"` |
113121
| `%S` | Uppercase string | `"abc"``"ABC"` |
114122
| `%d` | Integer (decimal) | `42` |
115123
| `%u` | Unsigned integer (64-bit) | `-1``"18446744073709551615"` |
@@ -137,15 +145,81 @@ vsprint("User: %s, Score: %d", ["Bob", 100]);
137145
## 🧪 Examples
138146

139147
```js
140-
sprint("Binary: %08b", 5); // Binary: 00000101
141-
sprint("Hex: %#x", 255); // Hex: ff
142-
sprint("Char: %c", 65); // Char: A
143-
sprint("Padded: %10s", "text"); // Padded: text
144-
sprint("Left: %-10s!", "text"); // Left: text !
145-
sprint("Float: %.2f", 3.14159); // Float: 3.14
146-
sprint("Scientific: %.2e", 1200); // Scientific: 1.20e+3
148+
sprintf("Binary: %08b", 5); // Binary: 00000101
149+
sprintf("Hex: %#x", 255); // Hex: ff
150+
sprintf("Char: %c", 65); // Char: A
151+
sprintf("Padded: %10s", "text"); // Padded: text
152+
sprintf("Left: %-10s!", "text"); // Left: text !
153+
sprintf("Float: %.2f", 3.14159); // Float: 3.14
154+
sprintf("Scientific: %.2e", 1200); // Scientific: 1.20e+3
155+
```
156+
157+
**[index$] – Argument Indexing**
158+
```js
159+
sprintf('%2$s is %1$d years old.', 22, 'Modassir');
160+
// Output: Modassir is 22 years old.
147161
```
148162

163+
**[padding] – Custom Padding Character**
164+
```js
165+
sprintf("%'~5d", 42);
166+
// Output: ~~~42
167+
168+
sprintf("%'~-5d", 42);
169+
// Output: 42~~~
170+
```
171+
172+
**[flag] – Format Flags**
173+
174+
Support flags `+` and `-` only.
175+
176+
```js
177+
sprintf("%+d", 42);
178+
// Output: +45
179+
180+
sprintf("%-d", 42);
181+
// Output: -45
182+
```
183+
184+
**[width] – Custom Width**
185+
```js
186+
sprintf("%6s", "JS");
187+
// Output: " JS"
188+
189+
sprintf("lang%6s", "JS");
190+
// Output: "lang JS"
191+
192+
sprintf("%-6s", "JS");
193+
// Output: "JS "
194+
195+
sprintf("%-6slib", "JS");
196+
// Output: "JS lib"
197+
```
198+
199+
**[.precision] – Precision (floating-point or string truncation)**
200+
```js
201+
sprintf("%.2f", 3.14159);
202+
// Output: 3.14
203+
204+
sprintf("%.4s", "OpenAI");
205+
// Output: Open
206+
```
207+
208+
**Full Format**
209+
```js
210+
sprintf('%2$\'#-+10.2f and %1$\'*_10s', "JS", 3.14159);
211+
// Output: +3.14#####JS*******
212+
```
213+
214+
🔹 Explanation:
215+
- `%2$`: Second argument (`3.14159`)
216+
- `'#`: padding character `#`
217+
- `-`: left align
218+
- `+`: show sign
219+
- `10`: total width 10
220+
- `.2f`: 2 decimal places
221+
- `%1$'*_10s`: First argument (`JS`), padded with `*` to width 10
222+
149223
---
150224

151225
## ⚠️ Errors & Warnings
@@ -160,13 +234,13 @@ sprint("Scientific: %.2e", 1200); // Scientific: 1.20e+3
160234
## 🔄 Comparison with Other Libraries
161235

162236
| Feature / Library | printfy ✅ | sprintf-js 🟡 | fast-printf 🟢 | printf (npm) 🔵 |
163-
| ---------------------- | ------------------ | ------------- | -------------- | -------------------- |
237+
| ---------------------- | ------------------ | --------------- | --------------- | ----------------- |
164238
| C-style specifiers | ✅ Full | ✅ Full | ✅ Partial | ✅ Partial |
165239
| %2\$ style arg index | ✅ Yes | ✅ Yes | ❌ No | ❌ No |
166240
| BigInt support | ✅ Yes | ❌ No | ❌ No | ❌ No |
167241
| %f vs %F (locale) | ✅ Separate | ❌ Combined | ❌ Combined | ❌ No |
168242
| Custom padding ('x) |`'x`, `0`, etc. | ❌ No | ❌ No | ❌ No |
169-
| String return (sprint) | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
243+
| String return (sprintf)| ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
170244
| Lightweight / No deps | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
171245
| Unicode emoji safe | Partial | Partial | ❌ No | ❌ No |
172246
| Performance | Good | Good | Best | Good |

lib/printfy.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* printfy pure JavaScript Libaray v2.0.1
2+
* printfy pure JavaScript Libaray v2.0.2
33
* A lightweight JavaScript library implements C-style `printf` functionality.
44
* https://github.com/jsvibe/printfy
55
*
@@ -346,7 +346,8 @@ function printf(format, values) {
346346
* @returns {string} Return a formatted string
347347
*/
348348
function vprintf(format, values) {
349-
printf.apply(this, arguments);
349+
values.unshift(format)
350+
printf.apply(this, values);
350351
}
351352

352353
/**
@@ -372,7 +373,8 @@ function sprintf(format, values) {
372373
* @returns {string} Return a formatted string
373374
*/
374375
function vsprintf(format, values) {
375-
return sprintf.apply(this, concat.apply([], format, values));
376+
values.unshift(format);
377+
return sprintf.apply(this, values);
376378
}
377379

378380

lib/printfy.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "printfy",
3-
"version": "2.0.1",
3+
"version": "2.0.2",
44
"description": "C-style printf formatting for JavaScript with padding and precision.",
55
"main": "lib/printfy.js",
66
"scripts": {

test/printfy.test.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// test.js for printfy v2.0.2
2+
// Run using: node test.js
3+
4+
const { printf, sprintf, vprintf, vsprintf } = require("../lib/printfy");
5+
6+
// Utility for clean output comparison
7+
function test(label, actual, expected) {
8+
const passed = actual === expected;
9+
console.log(`${passed ? '✔' : '✘'} ${label}`);
10+
if (!passed) {
11+
console.log(` Expected: "${expected}"`);
12+
console.log(` Received: "${actual}"\n`);
13+
}
14+
}
15+
16+
// Capture console output for printf/vprintf tests
17+
function captureConsoleOutput(callback) {
18+
const originalLog = console.log;
19+
let output = "";
20+
console.log = (msg) => { output += msg + "\n"; };
21+
callback();
22+
console.log = originalLog;
23+
return output.trim();
24+
}
25+
26+
// --- Basic String Tests ---
27+
test('String: simple', sprintf("Hello %s", "World"), "Hello World");
28+
test('String: padded', sprintf("Name: %10s", "Alice"), "Name: Alice");
29+
test('String: left-aligned', sprintf("Name: %-10s!", "Bob"), "Name: Bob !");
30+
test('String: precision', sprintf("%.4s", "Elephant"), "Elep");
31+
32+
// --- Integer Tests ---
33+
test('Decimal: positive', sprintf("Age: %d", 25), "Age: 25");
34+
test('Decimal: negative', sprintf("Debt: %d", -350), "Debt: -350");
35+
test('Zero-padded', sprintf("ID: %05d", 42), "ID: 00042");
36+
test('Left-align', sprintf("Left: %-5d!", 9), "Left: 9 !");
37+
test('Unsigned: large number', sprintf("Big: %u", -123), "Big: 18446744073709551493");
38+
39+
// --- Binary, Octal, Hex Tests ---
40+
test('Binary', sprintf("Bin: %08b", 10), "Bin: 00001010");
41+
test('Octal', sprintf("Oct: %o", 123), "Oct: 173");
42+
test('Hex lowercase', sprintf("Hex: %x", 255), "Hex: ff");
43+
test('Hex uppercase', sprintf("Hex: %X", 255), "Hex: FF");
44+
45+
// --- Character ---
46+
test('Character: %c', sprintf("Char: %c", 65), "Char: A");
47+
48+
// --- Float Tests ---
49+
test('Float: default precision', sprintf("Pi: %f", 3.14159), "Pi: 3.141590");
50+
test('Float: .2f', sprintf("Pi: %.2f", 3.14159), "Pi: 3.14");
51+
test('Float: fixed-point %F', sprintf("Fixed: %.3F", 12.3456), "Fixed: 12.346");
52+
test('Float: scientific %e', sprintf("Sci: %.2e", 123456), "Sci: 1.23e+5");
53+
test('Float: uppercase %E', sprintf("Sci: %.2E", 123456), "Sci: 1.23E+5");
54+
test('Float: auto %g', sprintf("Auto: %.4g", 123.456), "Auto: 123.5");
55+
test('Float: uppercase auto %G', sprintf("Auto: %.3G", 0.0001234), "Auto: 0.000123");
56+
57+
// --- Positional Arguments ---
58+
test('Positional args', sprintf("%2$s %1$s!", "World", "Hello"), "Hello World!");
59+
60+
// --- vsprintf and vprintf ---
61+
test('vsprintf basic', vsprintf("Total: %d, Name: %s", [99, "Item"]), "Total: 99, Name: Item");
62+
63+
// --- sprintf and vsprintf ---
64+
test('sprintf basic', sprintf("Hello %s!", "World"), "Hello World!");
65+
test('vsprintf array', vsprintf("Total: %d, Name: %s", [99, "Item"]), "Total: 99, Name: Item");
66+
67+
// --- printf Tests ---
68+
let result = captureConsoleOutput(() => printf("User: %s, ID: %04d", "Alice", 7));
69+
test('printf output', result, "User: Alice, ID: 0007");
70+
71+
result = captureConsoleOutput(() => printf("Hex: %X", 255));
72+
test('printf hex upper', result, "Hex: FF");
73+
74+
result = captureConsoleOutput(() => printf("Float: %.2f", 3.14159));
75+
test('printf float 2dp', result, "Float: 3.14");
76+
77+
// --- vprintf Tests ---
78+
result = captureConsoleOutput(() => vprintf("User: %s, Age: %d", ["Bob", 32]));
79+
test('vprintf array', result, "User: Bob, Age: 32");
80+
81+
result = captureConsoleOutput(() => vprintf("Hex: %02x", [15]));
82+
test('vprintf padded hex', result, "Hex: 0f");
83+
84+
result = captureConsoleOutput(() => vprintf("Char: %c", [65]));
85+
test('vprintf char', result, "Char: A");
86+
87+
console.log("\nAll tests completed.");

0 commit comments

Comments
 (0)