The implementation of custom command for uploading image in Typora

Posted by lucasw on Mon, 15 Jun 2020 07:31:19 +0200

Typora is a mark down editor that I like very much. Usually, I write notes in typora before I post them on my blog. At this time, the pictures in md need to be copied one by one. In order to reduce these tedious operations, typora also supports the function of drawing bed, so we decided to operate it.

Typora uses PicGo to indirectly support Weibo, qiniu cloud, Tencent cloud COS, and take photos of cloud, GitHub, Alibaba cloud OSS, SM.MS , imgur, etc. In addition, typora also supports the use of custom commands to upload images to the drawing bed.

For the sake of free and guaranteed speed, I plan to use Tencent's coding self built git warehouse as the drawing bed. PicGo doesn't support the drawing bed. I used go to write a gadget as a custom command for Typora. I will record some pits I stepped on below.

How to call custom commands in Typora

First open the settings and fill in the path of your custom command

When you insert a picture, Typora will pass the path of the picture as a parameter to your command. The length and number of parameters are uncertain. The official documents are vague here, which is a pit for me.

\Users\Lenovo\Desktop\piccoding\main.exe "C:\\Users\\Lenovo\\AppData\\Local\\Temp/typora-icon2.png" "C:\\Users\\Lenovo\\AppData\\Local\\Temp/typora-icon.png"

After the image is uploaded, Typora needs you to output the URL of the image to it on the console according to the specified format (this is also a small pit for me).

Upload Success:
https://stormbuf.coding.net/p/piccoding/d/piccoding/git/raw/master/typora-icon2.png
https://stormbuf.coding.net/p/piccoding/d/piccoding/git/raw/master/typora-icon.png

The first line must be Upload Success:, then the second non empty line starts, one line one image URL.

Implementation of custom command

Typora only gives you the path of the picture and the URL to get the picture, but it doesn't matter how the middle custom command deals with the picture.

Here's how to implement the custom command:

  1. Get picture path
  2. Judge whether the image exists in git local warehouse. If so, skip to step 5
  3. Copy image to git local warehouse
  4. Call the external program git to complete the add, commit and push of GIT
  5. Stitching fixed prefix of git remote warehouse file URL with picture name to generate picture URL
  6. Output picture URL

The concrete implementation is very simple. Let's learn from it

// Prefix for picture URL
var prePicURL = ""

// git local warehouse Path
var picPath = ""

func main() {
	flag.Parse()
	file := flag.Args()

	if len(file) == 0 {
		os.Exit(1)
	}
	picURLs := make([]string, len(file))

	for _, v := range file {
		if !isFileExist(v) {
			if cpFile(v) {
				upload(v)
				// filepath.Base(v) Get file name
				picURLs = append(picURLs, prePicURL+filepath.Base(v))
			}
		} else {
			picURLs = append(picURLs, prePicURL+filepath.Base(v))
		}
	}

	fmt.Println("Upload Success:")
	for _, v := range picURLs {
		fmt.Println(v)
	}

}

func isFileExist(fileName string) bool {
    //os.Stat Get file information
	_, err := os.Stat(picPath + filepath.Base(fileName)) 
	if err != nil {
		if os.IsExist(err) {
			return true
		}
		return false
	}
	return true

}

func cpFile(fileName string) bool {

	srcFile, err := os.Open(fileName)
	if err != nil {
		fmt.Println(err)
		return false
	}

	defer srcFile.Close()
	reader := bufio.NewReader(srcFile)

	destFile, err := os.OpenFile(picPath+filepath.Base(fileName), os.O_WRONLY|os.O_CREATE, 0777)
	if err != nil {
		fmt.Println(err)

		return false
	}
	writer := bufio.NewWriter(destFile)
	defer destFile.Close()

	_, _ = io.Copy(writer, reader)

	return true
}

func upload(fileName string) {

	cmd1 := exec.Command("git", "add", ".")
	cmd2 := exec.Command("git", "commit", "-m", filepath.Base(fileName))
	cmd3 := exec.Command("git", "push")

	cmd1.Dir = picPath
	cmd2.Dir = picPath
	cmd3.Dir = picPath

	_ = cmd1.Run()
	_ = cmd2.Run()
	_ = cmd3.Run()

}

Topics: git github