LongTengDao / j-toml

A Node.js implementation of TOML written by LongTengDao. Belong to "Plan J"./龙腾道为汤小明语写的 Node.js 实现。从属于“简计划”。
https://npmjs.com/package/@ltd/j-toml
GNU Lesser General Public License v3.0
55 stars 6 forks source link

Controlling spaces in list output #17

Closed guybedford closed 2 years ago

guybedford commented 2 years ago

Currently lists output like:

extensions = [ 'value' ]

I couldn't find an easy configuration option to control this spacing. Specifically I'm looking to achieve the output:

extensions = ['value']

If I've missed something in the docs please let me know.

LongTengDao commented 2 years ago

Thank you for your feedback. @guybedford

I try to let this under users' control in new published version. There are two features about this need in this version:

  1. Value parsed by TOML.parse will auto remember how you writing spaces in single-line static arrays. [^1]
  2. The TOML.inline accept 2nd parameter now, which allow user to change the spacing mode for parsed value, or define mode for brand new value:
2nd param empty sample non-empty sample
3 (default) [ ] [ 1, 2 ]
2 [] [ 1, 2 }
1 [ ] [1, 2]
0 [] [1, 2]

[^1]: 1 and 2 and 3 is not possible to distinguish from source code, because an array can't be both empty and non-empty at the same time. So the mode will be 3 when met [ ] or [ 1, 2 ], and 0 when met [] or [1, 2]. Maybe I can add options of TOML.parse, to specify default mode for the other unknown case, if necessary.

I didn't design the api in TOML.stringify's options, because people may want [ [1, 2], [1, 2] ]. I try my best to consider various need's balance... Try v1.28.0, and let me know if you have better idea.

Best wishes.

guybedford commented 2 years ago

@LongTengDao the use case I'm working on involves loading TOML, modifying it, then saving it again. It's basically a --format function like prettier or something like that. So ideally I'd want global formatting rules that then lead into the fine-grained per-list formatting rules. Perhaps there's a heurisitic like a list longer than n chars becomes a multi-line list. But with regards to this exact formatting question, ideally I'd want a global option for this spacing that would apply if there are no specific per-list configurations. Let me know if there's something that might apply for this use case?

LongTengDao commented 2 years ago

@guybedford I thought and thought, but there are still too many possibilities about TOML writing styles. I think high-level serialization ability should provided by a walking through function, based on the library's low-level built-in api, like:

const all_inline_0 = function callee (value) {
  if ( typeof value==='object' && value ) {
    if ( Array.isArray(value) ) {
      if ( TOML.isInline(value) ) {// any condition you want
        TOML.inline(value, 0);
      }
      for ( const item of value ) { callee(item); }
    }
    else {
      for ( const key of Object.getOwnPropertyNames(value) ) { callee(value[key]); }
    }
  }
};

const parsed = TOML.parse(source, { joiner: '\n' });
all_inline_0(parsed);
TOML.stringify(parsed, { newline: '\n' });
guybedford commented 2 years ago

@LongTengDao thanks for putting some more thought to this. Could there at least be a global stringify option like inlineListPadding: true / false?

LongTengDao commented 2 years ago

@guybedford Try v1.29.0? (forceInlineArraySpacing :0 | 1 | 2 | 3) ;)

guybedford commented 2 years ago

Works perfectly - thank you! I matched Rust formatting style with the usage at https://github.com/guybedford/chomp-extensions/blob/main/swc.js#L226.