Dán liên kết vào hình ảnh trong clipboard khi chỉnh sửa Markdown


9

Tôi có một hình ảnh trên bảng tạm và tôi muốn dán nó vào tài liệu của mình dưới dạng văn bản [](img/image1.png).

Thay vì đầu tiên sao chép nó vào thư mục đó, tôi muốn làm điều đó với một lần pnhấn phím trong Vim. Vì vậy, nó móc p, kiểm tra xem tôi có đang chỉnh sửa tệp Markdown không, lưu hình ảnh từ bảng ghi tạm vào vị trí img/image1.pngvà chèn [](img/image1.png)vào tệp.

Điều này có thể với Vim?

Tôi sử dụng macOS và thiết bị đầu cuối Vim.


Để rõ ràng, đây có phải là "Tôi đã sao chép một hình ảnh trực tiếp như thể trong, nói, từ" hoặc "Tôi đã sao chép một tệp hình ảnh trong công cụ tìm"? (Tôi thực sự không biết liệu chúng có khác nhau không ...)
Joe

Câu trả lời:


2

Lệnh terminal thông thường để truy cập clipboard trên Mac là pbpaste. Tuy nhiên, điều này không hoạt động đối với dữ liệu hình ảnh, vì vậy chúng tôi phải sử dụng AppleScript:

nnoremap <silent> <buffer> p :call MarkdownClipboardImage()<cr>

function! MarkdownClipboardImage() abort
  " Create `img` directory if it doesn't exist
  let img_dir = getcwd() . '/img'
  if !isdirectory(img_dir)
    silent call mkdir(img_dir)
  endif

  " First find out what filename to use
  let index = 1
  let file_path = img_dir . "/image" . index . ".png"
  while filereadable(file_path)
    let index = index + 1
    let file_path = img_dir . "/image" . index . ".png"
  endwhile

  let clip_command = 'osascript'
  let clip_command .= ' -e "set png_data to the clipboard as «class PNGf»"'
  let clip_command .= ' -e "set referenceNumber to open for access POSIX path of'
  let clip_command .= ' (POSIX file \"' . file_path . '\") with write permission"'
  let clip_command .= ' -e "write png_data to referenceNumber"'

  silent call system(clip_command)
  if v:shell_error == 1
    normal! p
  else
    execute "normal! i[](" . file_path . ")"
  endif
endfunction

Thêm mã ở trên vào ~/.vim/after/ftplugin/markdown.vim.

Điều này sẽ lưu dữ liệu clipboard vào tệp "img / image1.png" nếu nó chứa dữ liệu PNG. Sau đó, nó chỉ sử dụng :normal!để chèn liên kết đánh dấu mong muốn.

Nếu bảng tạm không chứa dữ liệu PNG (hoặc nếu chúng tôi không có trong tệp Markdown), nó sẽ thực hiện một plệnh thông thường .

Nếu tôi đang sử dụng điều này, tôi sẽ thu dọn nó để hỗ trợ các loại hình ảnh khác và để con trỏ ở vị trí hữu ích hơn, nhưng điều này hoạt động tốt như một bằng chứng về khái niệm.

(Tôi cũng sử dụng <leader>pbản đồ theo đề xuất của Karl Yngve Lervåg  - đây có vẻ như là chức năng tôi muốn gọi cụ thể hơn - nhưng đó không phải là những gì bạn yêu cầu).

đọc thêm


Rất vui, tôi đã cập nhật câu trả lời của mình bằng một liên kết đến bạn, vì giải pháp của bạn thực sự trả lời yêu cầu MacOS.
Karl Yngve Lervåg

1
@ KarlYngveLervåg Cảm ơn, bạn rất tốt bụng. Tôi thậm chí sẽ không viết câu trả lời của mình nếu nó không dành cho bạn: bạn đã truyền cảm hứng cho tôi để tìm một giải pháp Mac gốc!
Giàu

3

Giải pháp sau đây sẽ hoạt động trên hầu hết các hệ thống Linux. Nó đòi hỏi một xclipcông cụ tương đối cập nhật . Để biết giải pháp hoạt động trên MacOS / OSX, hãy xem câu trả lời của @ Rich .


Tôi đã đề xuất một giải pháp lập bản đồ <leader>pthay vì ánh xạ lại p, vì tôi nghĩ rằng đây là một cách tiếp cận lành mạnh hơn. Các chức năng SaveFilesẽ kiểm tra clipboard với xclip. Nếu có tệp hình ảnh, nó sẽ được lưu vào img/imageN.<ext>, trừ khi tệp đã tồn tại. Nó cũng sẽ điền vào *thanh ghi với [](img/...)văn bản và sau đó dán nó.

nnoremap <silent> <leader>p :call SaveFile()<cr>

function! SaveFile() abort
  let targets = filter(
        \ systemlist('xclip -selection clipboard -t TARGETS -o'),
        \ 'v:val =~# ''image''')
  if empty(targets) | return | endif

  let outdir = expand('%:p:h') . '/img'
  if !isdirectory(outdir)
    call mkdir(outdir)
  endif

  let mimetype = targets[0]
  let extension = split(mimetype, '/')[-1]
  let tmpfile = outdir . '/savefile_tmp.' . extension
  call system(printf('xclip -selection clipboard -t %s -o > %s',
        \ mimetype, tmpfile))

  let cnt = 0
  let filename = outdir . '/image' . cnt . '.' . extension
  while filereadable(filename)
    call system('diff ' . tmpfile . ' ' . filename)
    if !v:shell_error
      call delete(tmpfile)
      break
    endif

    let cnt += 1
    let filename = outdir . '/image' . cnt . '.' . extension
  endwhile

  if filereadable(tmpfile)
    call rename(tmpfile, filename)
  endif

  let @* = '[](' . fnamemodify(filename, ':.') . ')'
  normal! "*p
endfunction

Giải pháp này thất bại âm thầm đối với tôi :(
Maxim Kochurov

Tôi đoán là bạn có một phiên bản cũ của xclip. Bạn nên cố gắng thực hiện các xcliplệnh trong thiết bị đầu cuối của bạn.
Karl Yngve Lervåg

1

Dựa trên các câu trả lời ở trên, tôi đã tạo một Plugin để vim giải quyết vấn đề của tôi cho macos và có thể cho linux. Hy vọng bạn sẽ tìm thấy plugin này hữu ích. Tôi cũng đánh giá cao bất kỳ đóng góp và yêu cầu tính năng.


Tôi không nghĩ rằng tôi từng thấy điều này trước đây. Cảm ơn tín dụng trong README của bạn! Tôi cũng bắt đầu viết một plugin, nhưng tôi chưa bao giờ thực hiện được tất cả các tính năng mà tôi đã lên kế hoạch.
Giàu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.