yaml.vim 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. " Parsing of YAML metadata blocks
  2. function! pandoc#yaml#Init() abort
  3. let b:pandoc_yaml_data = {}
  4. try
  5. call extend(b:pandoc_yaml_data, pandoc#yaml#Parse())
  6. catch
  7. endtry
  8. endfunction
  9. " extract yaml header text from the current text, as a list of lines
  10. " TODO: multiple YAML metadata blocks can exist, and at any position in
  11. " the file, but this doesn't handle that yet.
  12. function! pandoc#yaml#Extract() abort
  13. let l:tmp_lines = []
  14. let l:cline_n = 1
  15. while l:cline_n < 100 " arbitrary, but no sense in having huge yaml headers either
  16. let l:cline = getline(l:cline_n)
  17. let l:is_delim = l:cline =~# '^[-.]\{3}'
  18. if l:cline_n == 1 && !l:is_delim " assume no header, end early
  19. return []
  20. elseif l:cline_n > 1 && l:is_delim " yield data as soon as we find a delimiter
  21. return l:tmp_lines
  22. else
  23. if l:cline_n > 1
  24. call add(l:tmp_lines, l:cline)
  25. endif
  26. endif
  27. let l:cline_n += 1
  28. endwhile
  29. return [] " just in case
  30. endfunction
  31. function! pandoc#yaml#Parse(...) abort
  32. if a:0 == 0 " if no arguments, extract from the current buffer
  33. let l:block = pandoc#yaml#Extract()
  34. else
  35. let l:block = a:1
  36. endif
  37. if l:block == []
  38. return -1
  39. endif
  40. let yaml_dict = {}
  41. " assume a flat structure
  42. for line in l:block
  43. let key = ''
  44. let val = ''
  45. try
  46. let [key, val] = matchlist(line,
  47. \ '\s*\([[:graph:]]\+\)\s*:\s*\(.*\)')[1:2]
  48. let key = substitute(key, '[ -]', '_', 'g')
  49. " trim "s at the beggining and end of values
  50. let val = substitute(val, '\(^"\|"$\)', '', 'g')
  51. let yaml_dict[key] = val
  52. catch
  53. endtry
  54. endfor
  55. return yaml_dict
  56. endfunction