- 
                Notifications
    
You must be signed in to change notification settings  - Fork 206
 
feat: support parse and stringify with comments #247
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
base: main
Are you sure you want to change the base?
Changes from all commits
3e3d9e2
              6e2190c
              2e835c4
              bd7f21e
              77b762a
              c199a7e
              79f6d72
              69c7264
              9c83f30
              040639c
              8ae5a06
              f17c0ee
              4213a94
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| const { hasOwnProperty } = Object.prototype | ||
| const COMMENTS_ID = Symbol.for('comments_id') | ||
| 
     | 
||
| const encode = (obj, opt = {}) => { | ||
| if (typeof opt === 'string') { | ||
| 
        
          
        
         | 
    @@ -12,6 +13,8 @@ const encode = (obj, opt = {}) => { | |
| /* istanbul ignore next */ | ||
| opt.platform = opt.platform || (typeof process !== 'undefined' && process.platform) | ||
| opt.bracketedArray = opt.bracketedArray !== false | ||
| const preserveComments = opt.preserveComments || false | ||
| const commentsDictionary = hasOwnProperty.call(obj, COMMENTS_ID) ? obj[COMMENTS_ID] : {} | ||
| 
     | 
||
| /* istanbul ignore next */ | ||
| const eol = opt.platform === 'win32' ? '\r\n' : '\n' | ||
| 
          
            
          
           | 
    @@ -46,24 +49,40 @@ const encode = (obj, opt = {}) => { | |
| for (const k of keys) { | ||
| const val = obj[k] | ||
| if (val && Array.isArray(val)) { | ||
| if (preserveComments && hasOwnProperty.call(commentsDictionary, k)) { | ||
| out += commentsDictionary[k] | ||
| } | ||
| for (const item of val) { | ||
| out += safe(`${k}${arraySuffix}`).padEnd(padToChars, ' ') + separator + safe(item) + eol | ||
| } | ||
| } else if (val && typeof val === 'object') { | ||
| children.push(k) | ||
| } else { | ||
| if (preserveComments && hasOwnProperty.call(commentsDictionary, k)) { | ||
| out += commentsDictionary[k] | ||
| } | ||
| out += safe(k).padEnd(padToChars, ' ') + separator + safe(val) + eol | ||
| } | ||
| } | ||
| 
     | 
||
| if (opt.section && out.length) { | ||
| out = '[' + safe(opt.section) + ']' + (opt.newline ? eol + eol : eol) + out | ||
| let sectionComments = '' | ||
| if (preserveComments && hasOwnProperty.call(commentsDictionary, opt.section)) { | ||
| sectionComments = commentsDictionary[opt.section] | ||
| } | ||
| out = sectionComments + '[' + safe(opt.section) + ']' + (opt.newline ? eol + eol : eol) + out | ||
| } | ||
| 
     | 
||
| for (const k of children) { | ||
| if (/comments/.test(k)) { | ||
| continue | ||
| } | ||
| const nk = splitSections(k, '.').join('\\.') | ||
| const section = (opt.section ? opt.section + '.' : '') + nk | ||
| const child = encode(obj[k], { | ||
| const childObject = hasOwnProperty.call(obj, COMMENTS_ID) ? | ||
| Object.assign(obj[k], { [COMMENTS_ID]: obj[COMMENTS_ID] }) : | ||
| obj[k] | ||
| const child = encode(childObject, { | ||
| ...opt, | ||
| section, | ||
| }) | ||
| 
          
            
          
           | 
    @@ -104,16 +123,26 @@ function splitSections (str, separator) { | |
| } | ||
| 
     | 
||
| const decode = (str, opt = {}) => { | ||
| // The `typeof` check is required because accessing the `process` directly fails on browsers. | ||
| /* istanbul ignore next */ | ||
| opt.platform = opt.platform || (typeof process !== 'undefined' && process.platform) | ||
                
      
                  wraithgar marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||
| /* istanbul ignore next */ | ||
| const eol = opt.platform === 'win32' ? '\r\n' : '\n' | ||
| opt.bracketedArray = opt.bracketedArray !== false | ||
| const out = Object.create(null) | ||
| let p = out | ||
| let section = null | ||
| const commentsDictionary = {} | ||
| let lineCommentArray = [] | ||
| // section |key = value | ||
| const re = /^\[([^\]]*)\]\s*$|^([^=]+)(=(.*))?$/i | ||
| const lines = str.split(/[\r\n]+/g) | ||
| const duplicates = {} | ||
| 
     | 
||
| for (const line of lines) { | ||
| if (line && line.match(/^[#;]/)) { | ||
| lineCommentArray.push(line) | ||
| } | ||
| if (!line || line.match(/^\s*[;#]/) || line.match(/^\s*$/)) { | ||
                
      
                  wraithgar marked this conversation as resolved.
               
          
            Show resolved
            Hide resolved
         | 
||
| continue | ||
| } | ||
| 
        
          
        
         | 
    @@ -130,6 +159,10 @@ const decode = (str, opt = {}) => { | |
| continue | ||
| } | ||
| p = out[section] = out[section] || Object.create(null) | ||
| if (lineCommentArray.length > 0) { | ||
| commentsDictionary[section] = lineCommentArray.join(eol) + eol | ||
| lineCommentArray = [] | ||
| } | ||
| continue | ||
| } | ||
| const keyRaw = unsafe(match[2]) | ||
| 
          
            
          
           | 
    @@ -163,8 +196,16 @@ const decode = (str, opt = {}) => { | |
| // array by accidentally forgetting the brackets | ||
| if (Array.isArray(p[key])) { | ||
| p[key].push(value) | ||
| if (lineCommentArray.length > 0) { | ||
| commentsDictionary[key] = lineCommentArray.join(eol) + eol | ||
| lineCommentArray = [] | ||
| } | ||
| } else { | ||
| p[key] = value | ||
| if (lineCommentArray.length > 0) { | ||
| commentsDictionary[key] = lineCommentArray.join(eol) + eol | ||
| lineCommentArray = [] | ||
| } | ||
| } | ||
| } | ||
| 
     | 
||
| 
          
            
          
           | 
    @@ -204,6 +245,8 @@ const decode = (str, opt = {}) => { | |
| delete out[del] | ||
| } | ||
| 
     | 
||
| out[COMMENTS_ID] = commentsDictionary | ||
| 
     | 
||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this will work because the  Here's an example: I think the best strategy here would be to follow what  Another option would be new methods like   | 
||
| return out | ||
| } | ||
| 
     | 
||
| 
          
            
          
           | 
    ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -94,3 +94,9 @@ test('encode within browser context', function (t) { | |
| t.matchSnapshot(e) | ||
| t.end() | ||
| }) | ||
| test('stringify with comments', function (t) { | ||
| 
         There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. .decode  | 
||
| const d = i.parse(data) | ||
| const s = i.stringify(d, { preserveComments: true }) | ||
| t.matchSnapshot(s) | ||
| t.end() | ||
| }) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cool
/