Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

string formatting - truncate, pad left and pad right #23

Open
mscalora opened this issue Jan 21, 2018 · 5 comments
Open

string formatting - truncate, pad left and pad right #23

mscalora opened this issue Jan 21, 2018 · 5 comments

Comments

@mscalora
Copy link

It would be very useful to be able to truncate strings to a certain length and also pad left and right, currently only padding left appears to be supported. maybe upper case S could support traditional extended string formatting like

%10S       - pad right
%-10S      - pad left
%.10S      - truncate right
%-.10S     - truncate left
%10.10S    - pad and truncate right
%-10.10S   - pad and truncate left

I would consider creating a patch request if the idea is palatable

@wdavidw
Copy link
Member

wdavidw commented Jan 23, 2018

I'm ok with the idea. Is there some standart directed by printf relative to right padding ?

@revelt
Copy link
Contributor

revelt commented Apr 18, 2018

@wdavidw the spec does cover padding: http://www.cplusplus.com/reference/cstdio/printf/

Having said that, from example above, I couldn't understand what would %-10S for example mean from it. Because % is always there, - stands for left-justify within given field; now hard part - 10 is width and S would be specifier, but I can't find specifier with capital S, only lowercase...

@mscalora
Copy link
Author

mscalora commented Apr 18, 2018

The C standard docs I have seen are a bit vague about how some features like precision apply to strings. Using Apple's clang/LLVM, not sure whose runtime, gnu maybe:

#include <stdio.h>

int main(void) {
   printf("12345678901234567890\n");

   printf("\n%%s|\n\n");
   printf("%s|\n", "short");
   printf("%s|\n", "really-long-string");

   printf("\n%%10s|\n\n");
   printf("%10s|\n", "short");
   printf("%10s|\n", "really-long-string");

   printf("\n%%-10s|\n\n");
   printf("%-10s|\n", "short");
   printf("%-10s|\n", "really-long-string");

   printf("\n%%.10s|\n\n");
   printf("%.10s|\n", "short");
   printf("%.10s|\n", "really-long-string");

   printf("\n%%-.10s|\n\n");
   printf("%-.10s|\n", "short");
   printf("%-.10s|\n", "really-long-string");

   printf("\n%%10.10s|\n\n");
   printf("%10.10s|\n", "short");
   printf("%10.10s|\n", "really-long-string");

   printf("%%-10.10s|\n\n");
   printf("%-10.10s|\n", "short");
   printf("%-10.10s|\n", "really-long-string");

   return 0;
}

I get:

$ ./test
12345678901234567890

%s|

short|
really-long-string|

%10s|

     short|
really-long-string|

%-10s|

short     |
really-long-string|

%.10s|

short|
really-lon|

%-.10s|

short|
really-lon|

%10.10s|

     short|
really-lon|
%-10.10s|

short     |
really-lon|
$

The only places my suggestion differs are %-.10s and %-10.10s where clib truncates right. I tried negative precision like %.-10s but clang produces an "invalid specifier" error though this could allow pad-left-truc-right or pad-right-truc-left like %-10.10s and %10.-10s while %-10.-10s would then need to be used for pad-left-trunc-left but I don't think that is really very useful to mix left and right in the same format specifier.

I think I suggested uppercase S to preserve current behaviour for s. It is sometimes used as an extension for double byte strings where the C standard uses %ls.

For reference:

sprintf = require('printf');

function printf() {
  process.stdout.write(sprintf.apply(this, arguments));
}

printf("12345678901234567890\n");

printf("\n%%s|\n\n");
printf("%s|\n", "short");
printf("%s|\n", "really-long-string");

printf("\n%%10s|\n\n");
printf("%10s|\n", "short");
printf("%10s|\n", "really-long-string");

printf("\n%%-10s|\n\n");
printf("%-10s|\n", "short");
printf("%-10s|\n", "really-long-string");

printf("\n%%.10s|\n\n");
printf("%.10s|\n", "short");
printf("%.10s|\n", "really-long-string");

printf("\n%%-.10s|\n\n");
printf("%-.10s|\n", "short");
printf("%-.10s|\n", "really-long-string");

printf("\n%%10.10s|\n\n");
printf("%10.10s|\n", "short");
printf("%10.10s|\n", "really-long-string");

printf("%%-10.10s|\n\n");
printf("%-10.10s|\n", "short");
printf("%-10.10s|\n", "really-long-string");

produces:

$ node test.js
12345678901234567890

%s|

short|
really-long-string|

%10s|

     short|
really-long-string|

%-10s|

short     |
really-long-string|

%.10s|

short|
really-long-string|

%-.10s|

short|
really-long-string|

%10.10s|

     short|
really-long-string|
%-10.10s|

short     |
really-long-string|

@wdavidw
Copy link
Member

wdavidw commented Sep 3, 2018

Any suggestion on this issue ?

@revelt
Copy link
Contributor

revelt commented Sep 4, 2018

@wdavidw If you meant me, sorry I'm completely out of touch with this issue; this library is working fine for my needs currently, I'm using it daily, all is fine. Thank you for great work, I should have written it myself if you haven't created it because I have to deliver code in both Nunjucks (Node) and Jinja (Python) and "out-of-box", this filter is missing outside Python. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants