Skip to content

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

Open
@mscalora

Description

@mscalora

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

Activity

wdavidw

wdavidw commented on Jan 23, 2018

@wdavidw
Member

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

revelt

revelt commented on Apr 18, 2018

@revelt
Contributor

@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

mscalora commented on Apr 18, 2018

@mscalora
Author

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

wdavidw commented on Sep 3, 2018

@wdavidw
Member

Any suggestion on this issue ?

revelt

revelt commented on Sep 4, 2018

@revelt
Contributor

@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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @wdavidw@mscalora@revelt

        Issue actions

          string formatting - truncate, pad left and pad right · Issue #23 · adaltas/node-printf