# 格式擴充

格式擴充插件的主要目的是使 Eagle 能夠預覽尚未支援的檔案格式。與其他類型插件不同，格式擴充插件在 `manifest.json` 中不需要定義 `main` 屬性，而是需要設定 `preview` 屬性。以下是一個範例程式碼：

```json
"preview": {}
```

在 `preview` 中可以定義要擴充的檔案副檔名。例如，如果想要讓 Eagle 支援 icns 圖示格式，可以輸入 `"icns": {}`：

```json
"preview" : {
    "icns": {}
}
```

另外，如果你需要同時設定多個副檔名，你可以使用 , 將不同副檔名隔開進行定義，比如：

```json
"preview" : {
    "icns,ico": {}
}
```

格式擴充插件可以分成兩個部分：

1. `"thumbnail.path"`：提供用於解析要擴充的檔案格式的縮圖的 `.js` 檔案。
2. `"viewer.path"`：提供用於預覽要擴充的格式的 `.html` 檔案。

```json
"preview": {
    "icns": {
        "thumbnail": {
            "path": "thumbnail/icns.js",
            "size": 400,
            "allowZoom": false
        },
        "viewer": {
            "path": "viewer/icns.html"
        }
    }
}
```

設定其它 `metadata.json` 欄位後，最終程式碼如下：

{% tabs %}
{% tab title="manifest.json" %}

```json
{
    "id": "LARSKLB8OTOC2",
    "version": "1.0.0",
    "platform": "all",
    "arch": "all",
    "name": "Preview Plugin",
    "logo": "/logo.png",
    "keywords": [
        "icns"
    ],
    "devTools": false,
    "preview": {
        "icns": {
            "thumbnail": {
                "path": "thumbnail/icns.js",
                "size": 400,
                "allowZoom": false
            },
            "viewer": {
                "path": "viewer/icns.html"
            }
        }
    }
}
```

{% endtab %}

{% tab title="thumbnail/icns.js" %}

```javascript
const fs = require('fs');
const icns = require('./../js/icns-util.js');
const imageSize = require('./../js/image-size.js');

module.exports = async ({ src, dest, item }) => {
    return new Promise(async (resolve, reject) => {
        try {
            // 1. parsing and generate thumbnail file to dest
            await icns.icns2png(src, dest);
            let size = await imageSize(dest);

            // 2. Check if the result is correct
            if (!fs.existsSync(dest) || size.width === 0) {
                return reject(new Error(`icns file thumbnail generate fail.`));
            }

            // 3. update the item dimensions
            item.height = size?.height || item.height;
            item.width = size?.width || item.width;

            // 4. return the result
            return resolve(item);
        }
        catch (err) {
            return reject(err);
        }
    });
}
```

{% endtab %}

{% tab title="viewer/icns.html" %}

```html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>ICNS Viewer</title>
    <style>
        html, body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
        #viewer {
            pointer-events: none;
            object-fit: contain;
            object-position: center;
            width: 100%;
            height: 100%;
            max-width: 100vw;
            max-height: 100vh;
        }
    </style>
</head>
<body>
    <img id="viewer"/>
    <script>
        const urlParams = new URLSearchParams(window.location.search);
        const id = urlParams.get('id');
        const filePath = urlParams.get('path');
        const width = urlParams.get('width');
        const height = urlParams.get('height');
        const theme = urlParams.get('theme');
        const lang = urlParams.get('lang');

        const viewer = document.querySelector('#viewer');

        // 1. Load the thumbnail image first
        // 👍 Avoid loading for too long, and UI has no content
        viewer.src = filePath.replace(".icns", "_thumbnail.png");

        // 2. Load the file and replace thumbnail
        (async function() {
            const icns = require('./../js/icns-util.js');
            let buffer = await icns.icns2buffer(filePath);
            let base64 = `data:image/png;base64,${buffer.toString('base64')}`;
            viewer.src = base64;
        })();
    </script>
</body>
</html>
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
請注意，目前格式擴充插件不支援 Eagle Plugin API 和 DevTools 除錯功能。
{% endhint %}

{% hint style="info" %}
**完整範例程式碼：**\
<https://github.com/eagle-app/eagle-plugin-examples/tree/main/Preview>
{% endhint %}
