Export a Vimscript Dictionary as JSON
Export a Vimscript Dictionary as JSON
I have a found a plugin that enables Vim to parse JSON. I need to export VimScript dictionaries as JSON. Currently I am just using:
let str = string(dict) substitute(str, "'", '"', 'g')
This is working but is bound to break when I run into dictionaries with embedded quotes. What is a better way?
Answer by Kent for Export a Vimscript Dictionary as JSON
I wrote a little function to echo
the json string, with "
double quote escaped. not sure if it works for your needs:
function! ToJson(input) if type(a:input) == type({}) echo "{" let di = 0 for key in keys(a:input) let di += 1 if type(key) == type('') echo '"'.substitute(key, '"', '\\"','g').'":' else echo '"'.key.'":' endif call ToJson(a:input[key]) echo di
a dict like:
let d1={'one':'"""', 'two':123, 333:['11',22,'"_"_"'], 'four':"''"}
will be output as:
{ "four": "''" , "one": "\"\"\"" , "two": "123" , "333": [ "11" , "22" , "\"_\"_\"" ] }
I didn't do much debug/testing. also the format looks not nice, but I guess you don't care about the format since you used string()
...
the above output could be formatted into (by an online json formatter):
{ "four":"''", "one":"\"\"\"", "two":"123", "333":[ "11", "22", "\"_\"_\"" ] }
hope it helps.
Answer by benjifisher for Export a Vimscript Dictionary as JSON
I am not sure whether this should be a separate answer, an edit to @Kent's answer, or a comment on @Kent's answer. Here is a version of @Kent's function with a few simplifications:
function! ToJson(input) let json = '' if type(a:input) == type({}) let json .= "{" let di = 0 for key in keys(a:input) let di += 1 let json .= '"'.escape(key, '"').'":' let json .= ToJson(a:input[key]) let json .= di
Instead of echoing the result, this returns it as a String. Also, I use escape()
instead of substitute()
. Finally, I think (Check this!) that it is safe to use escape()
as I did without first checking that the argument is a String.
Here is a shorter version, using map()
. I do not know whether depth of recursion matters more for this version or the others, but if your input is big enough for that to matter, it probably goes faster if we let map()
handle the recursion.
function! ToJson(input) let json = '' if type(a:input) == type({}) let parts = copy(a:input) call map(parts, '"\"" . escape(v:key, "\"") . "\":" . ToJson(v:val)') let json .= "{" . join(values(parts), ",") . "}" elseif type(a:input) == type([]) let parts = map(copy(a:input), 'ToJson(v:val)') let json .= "[" . join(parts, ",") . "]" else let json .= '"'.escape(a:input, '"').'"' endif return json endfunction
Using either version, I get the same result as @Kent's function, except for whitespace. I have not tested it with anything more complex than @Kent's d1
. It might be safer to use deepcopy()
than copy()
.
Answer by Ingo Karkat for Export a Vimscript Dictionary as JSON
The WebAPI.vim plugin has a JSON parser and encoder:
:let jsonString = webapi#json#encode({...})
Answer by albfan for Export a Vimscript Dictionary as JSON
Based on @benjifisher answer, I evolved ToJson
.
Indentation is hacky, but mostly works.
" Inspect variables " " input: variable " level: actual level of nest " max: maximum level of nest let json = '' function! ToJson(input, level, max) if a:level < a:max if type(a:input) == type({}) let parts = copy(a:input) call map(parts, '"\"" . escape(v:key, "\"") . "\":" . ToJson(v:val, ' . (a:level+1) . ',' . a:max . ")") let space = repeat(" ", a:level) let json .= space . " {\r\n " . space . join(values(parts), ",\r\n " . space) . "\r\n" . space ." }" elseif type(a:input) == type([]) let parts = map(copy(a:input), 'ToJson(v:val,' . (a:level+1) . ',' . a:max . ')') let json .= "[" . join(parts, ",\r\n") . "]\r\n" elseif type(a:input) == type(function("tr")) let dictFunc = substitute(string(a:input), "function('\\(.\\+\\)')", "\\1", "") if dictFunc+0 > 0 let funcName = '{' . dictFunc . '}' else let funcName = a:input endif let json .= '"'.escape(genutils#ExtractFuncListing(funcName, 0, 0), '"') . "\"" else let json .= '"'.escape(a:input, '"') . "\"" endif else try let json .= '"' . escape(string(a:input), '"') . "\"" catch "string() can throw an E724 (too much nest) let json .= '"' . escape(keys(a:input), '"') . "\"" endtry endif return json endfunction
To show function definitions you need a dependency from https://github.com/vim-scripts/genutils:
https://github.com/vim-scripts/genutils/blob/master/autoload/genutils.vim#L57
Omit that part if it does not apply to you, is supposed to be used on a visual vim debugger vim-breakpts to inspect complex variables
Answer by benjifisher for Export a Vimscript Dictionary as JSON
Two and a half years after my original answer, there is a simpler alternative: upgrade to Vim 8 and use json_encode()
or (if you do not need strict JSON) js_encode()
.
Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72
0 comments:
Post a Comment