idea插件之——在markdown複製粘貼圖片

Markdown paste image

每次在idea的markdown中要粘貼圖片的時候,要麼複製連接,要麼須要將軟件手動上傳到七牛雲,本人根據了holgerbrandl/pasteimages這個本地的軟件修改了下源碼,變成了如今的做品,同時,還能支持擴展,可是這部分還沒完成,代碼存放位置,插件下載地址
此工具可運行在Intellij、Python、PhpStorm等jetbrains的全部軟件中,使用效果以下:
html

插件開發過程

1.搭建環境
2.實現Action接口
3.Setting的設置
4.拓展cdn
5.插件打包java

總體介紹

主要是邏輯的關係,plugin.xml爲配置文件、PasteImageHandler控制器,若是是ctrl+v這個動做,則進入PasteImageFromClipboard,而後開始邏輯判斷
git

1.搭建環境

因爲使用的是idea的旗艦版,軟件中自帶了idea的插件開發包,new->project,選擇plugin
github

而後點擊下一步,再而後是finish。頁面結構以下:
api

配置文件:緩存

<idea-plugin>
  <id>com.your.company.unique.plugin.id</id><!--插件的id,若是須要上次到idea倉庫讓別人使用,不能跟其餘的一致-->
  <name>Plugin display name here</name><!--插件名字-->
  <version>1.0</version><!--版本名字-->
  <vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>
  <!--插件的簡要描述-->
  <description><![CDATA[
      Enter short description for your plugin here.<br>
      <em>most HTML tags may be used</em>
    ]]></description>
  <!--版本變化信息-->
  <change-notes><![CDATA[
      Add change notes here.<br>
      <em>most HTML tags may be used</em>
    ]]>
  </change-notes>
  <!--idea版本-->
  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
  <idea-version since-build="145.0"/>
  <!--產品選擇-->
  <!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
       on how to target different products -->
  <!-- uncomment to enable plugin in all products
  <depends>com.intellij.modules.lang</depends>
  -->
  <!--拓展組件註冊,本地開發的時候不要衝突,特別前後次序問題-->
  <extensions defaultExtensionNs="com.intellij">
    <!-- Add your extensions here -->
  </extensions>
  <!--Action註冊-->
  <actions>
    <!-- Add your actions here -->
  </actions>

</idea-plugin>

2.實現接口

Hello World的講解看看這位做者的吧。
(1)首先,在img2md中定義一個PasteImageHandler類,並在xml中註冊,該類的意思是是每次在markdown文件中使用ctrl+v(粘貼)的時候,先調用下面這個函數,若是符合條件,則進入:PasteImageFromClipboard。markdown

if ("Markdown".equals(fileType.getName())) {
    Image imageFromClipboard = ImageUtils.getImageFromClipboard();
    if (imageFromClipboard != null) {
        assert caret == null : "Invocation of 'paste' operation for specific caret is not supported";
        PasteImageFromClipboard action = new PasteImageFromClipboard();
        AnActionEvent event = createAnEvent(action, dataContext);
        action.actionPerformed(event);
        return;
    }
}

plugin.xml的配置文件以下:app

<extensions defaultExtensionNs="com.intellij">
        <editorActionHandler action="EditorPaste" implementationClass="img2md.PasteImageHandler" order="first"/>
    </extensions>

(2)右鍵src,新建AnAction的一個繼承類:PasteImageFromClipboard,重寫actionPerformed方法,該方法聲明要作什麼。其中,定義了一個ImageInsertSettingPanel來對粘貼以後的彈出的選項。
maven




隨後,plugin.xml中就多了一個action:ide

<actions>
    <action id="PastePic" class="img2md.PasteImageFromClipboard" text="PastePic"
            description="Paste an image from clipboard at the current cursor position">
        <add-to-group group-id="EditMenu" anchor="last"/>
        <keyboard-shortcut keymap="$default" first-keystroke="shift meta V"/>
    </action>
</actions>

彈出的選項窗以下,能夠選擇文件名字,文件目錄,是否透明化,是否圓角,圖片大小,若是不想要此彈窗,我在設置中設置了一個功能按鈕,下面會講到。


3.Setting的設置

原本是隻作七牛雲的,若是是七牛雲,中間的那個自定義框不須要管,只須要填好key和secret便可使用。

實現過程:
(1)右鍵,new>GUI FORM:

(2)在MySetting.form選好本身須要的按鈕,便可在MySetting.java中實現邏輯

(3)須要重寫的方法
找出類的實現關係:

idea sdk中配置了某些方法是能夠不實現的,例如getHelpTopic、createComponent等,經常使用的方法通常以下:

public interface UnnamedConfigurable {
    @Nullable
    JComponent createComponent();//打開設置的時候頁面,若是須要偵聽某些button,須要在這裏配置,可無
    boolean isModified();//是否能夠定義,通常爲true,想寫死的話就返回false
    void apply() throws ConfigurationException;//設置填好後點擊apply或者ok,這裏咱們保存填寫的東西
    default void reset() {//初始化,打開設置的初始化信息
    }
    default void disposeUIResources() {//關閉以後的資源
    }
}

保存填寫的信息,idea sdk給咱們提供了一個api,PropertiesComponent.getInstance(),感受略像緩存,有人說保存在xml中,具體我也不太瞭解,有待深刻。
(4)配置PasteImageFromClipboard的流程:

  • 判斷上傳的圖片是否爲空,若是爲空,則彈出提示框
  • 判斷當前文件是否是markdown的文件,若是是,進入編輯階段
  • 判斷是否以簡潔模式(即ctrl+v後不彈出選項框)
  • 講""配置到markdown中
  • 操做成功。
    有興趣能夠看看代碼

(5)七牛雲的使用
使用七牛雲的時候,須要將七牛雲sdk以及其依賴的一個一個包都手動導進去,用不了maven。

![](http://ohlrxdl4p.bkt.clouddn.com/images/1a137b8b20170917025333.png)

而後寫一個QiniuUtil,用來上傳文件:

public class QiniuUtil {
    //本身的七牛
    private static Logger log = LoggerFactory.getLogger(QiniuUtil.class);
    public static final Configuration cfg = new Configuration(Zone.zone0());
    //...其餘參數參考類註釋
    public static final UploadManager uploadManager = new UploadManager(cfg);

    public static String getToken(String bucket) {//獲取七牛的token
        System.out.println("qiniuyun");
        String access_key = PropertiesComponent.getInstance().getValue("ACCESS_KEY");
        String secret_key = PropertiesComponent.getInstance().getValue("SECRET_KEY");
        if (access_key != null && secret_key != null) {
            Auth auth = Auth.create(access_key, secret_key);
            String token = auth.uploadToken(bucket);
            return token;
        } else {
            return null;
        }

    }

    public static void putFile(String bucket, String key, String filePath) {//上傳文件,第一個是bucket,第二個是文件名,第三個是文件的路徑
        try {
            Response res = uploadManager.put(filePath, key, getToken(bucket));
            if (!res.isOK()) {
                log.error("Upload to qiniu failed;File path: " + filePath + ";Error: " + res.error);
            }
        } catch (QiniuException e) {
            e.printStackTrace();
            Response r = e.response;
            log.error(r.toString());
            try {
                log.error(r.bodyString());
            } catch (QiniuException e1) {
                log.error(e1.getMessage());
            }
        }
    }
}

以後,在PasteImageFromClipboard中添加保存的代碼便可。

QiniuUtil.putFile("images", "images/" + imagepath, imageFile.getPath());

若是想實現使用其餘的,好比騰訊雲、阿里雲、又拍雲這些,添加方式能夠像七牛雲同樣,添加包,寫個util便可,可是,當今的作雲的愈來愈多,不能一一實現,咱們能夠提供一個模板,供開發者使用,只要本身實現了代碼添加包便可。

4.拓展其餘雲

原本是隻作七牛雲的,可是想了一想,只作七牛雲好像沒啥意思,想拓展騰訊雲、阿里雲、又拍雲等等,顧提供了一個樣本類,供開發者使用。

public class Main {
    public boolean sendpic(String filepath) {//提供文件路徑
        return true;//返回結果
    }
}

填寫完代碼以後,還仍需一個添加包的列表,添加完包以後進行調試,這裏採用java的動態部署,生成動態類,規定主函數爲Main,必須有個sendpic的方法,將圖片的路徑傳過去,本身實現上傳的代碼

testYourCodeButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            File file = new File(System.getProperty("user.dir"));//類路徑(包文件上一層)
            URL url = file.toURI().toURL();
            ClassLoader loader = new URLClassLoader(new URL[]{url});//建立類加載器
            Class<?> cls = loader.loadClass("Main");//加載指定類,注意必定要帶上類的包名
            Object obj = cls.newInstance();//初始化一個實例
            Method method = cls.getMethod("sendpic", String.class);//方法名和對應的參數類型
            String imagepath = "1.png";//用來測試的圖片
            String success = method.invoke(obj, imagepath).toString();//調用獲得的上邊的方法method
            if (!success.equals("true")) {
                StringBuilder stringBuilder = new StringBuilder(Common.ERROR_CODE);
                customcode.setText(stringBuilder.append(customcode.getText()).toString());
            }
        } catch (Exception ee) {
            ee.printStackTrace();
        }
    }
});

調用此動態類的動做在PasteImageFormClipboard中,

try {
    File file = new File(System.getProperty("user.dir"));//類路徑(包文件上一層)
    URL url = file.toURI().toURL();
    ClassLoader loader = new URLClassLoader(new URL[]{url});//建立類加載器
    System.out.println("loader");
    Class<?> cls = loader.loadClass("Main");//加載指定類,注意必定要帶上類的包名
    Object obj = cls.newInstance();//初始化一個實例
    Method method = cls.getMethod("sendpic", String.class);//方法名和對應的參數類型
    method.invoke(obj, imagepath);//調用獲得的上邊的方法method
    //TODO 若是失敗則彈出失敗框
} catch (Exception ee) {
    ee.printStackTrace();
}

固然,拓展使用其餘cdn僅僅是個人設想。。。。因爲996,實在沒時間去實現了,各位有興趣能夠去star或者fork一下,連接點這

5.插件打包

寫好代碼以後,須要打包讓本身或者別人使用,右鍵項目—>prepare plugin module xxx for deployment,而後在項目的目錄就能夠看到一個zip包,而後,在setting的plugin中install plugin from disk便可。

昨天,發現這個項目已經有人實現了,比我造了三天,還傳到了jetbrains的公共倉庫,感受寫的比個人好,你們可使用一下

同時,歡迎訪問個人我的網站,要是能star一下個人網站的代碼就更好了網站代碼,感謝

相關文章
相關標籤/搜索