読者です 読者をやめる 読者になる 読者になる

指定した単語を含むパワポファイル出力ツールを作ったよ

作ったきっかけ

Golang系のスライドどこいった...?」 っていうことが度々起こったため作りました。

slideshareのスライドを電車の中で読むために、いっぱいダウンロードするんですよね。 で、何日か経つと「あのときのあのスライドどこいった〜?」ってなるわけ。

作ったもの

-w word で指定するとwordを含むパワポファイルのフルパスを表示。

$ ./pptgrep -w GOOGLE
/home/k2la/test.pptx

-p startpoint で指定するとstartpoint内のファイルから探してくれる。

$ ./pptgrep -w APPLE -p ~
/home/k2la/test1.pptx
/home/k2la/test2.pptx
/home/k2la/test3.pptx

-r をつけて再帰的に探すこともできます

$ ./pptgrep -w Docker -r -p ~/Downloads
/home/k2la/Downloads/docker/test.pptx
/home/k2la/Downloads/docker/test02.pptx
/home/k2la/Downloads/slide0706/test.pptx

実装

パワポファイル(.pptx)

file コマンドで調べてみると

$ file test.pptx
test.pptx: Microsoft PowerPoint 2007+

こんな感じに出力されます。

で、これを unzip コマンドで解凍してみると

$ unzip test.pptx -d test
Archive:  test.pptx
  inflating: test/[Content_Types].xml
  inflating: test/_rels/.rels
  inflating: test/ppt/slides/_rels/slide1.xml.rels
  inflating: test/ppt/slides/_rels/slide2.xml.rels
  inflating: test/ppt/slides/_rels/slide3.xml.rels
  inflating: test/ppt/slides/_rels/slide4.xml.rels
  inflating: test/ppt/_rels/presentation.xml.rels
  inflating: test/ppt/presentation.xml
  inflating: test/ppt/slides/slide4.xml
  inflating: test/ppt/slides/slide3.xml
  inflating: test/ppt/slides/slide2.xml
  inflating: test/ppt/slides/slide1.xml
  inflating: test/ppt/slideLayouts/_rels/slideLayout3.xml.rels
  inflating: test/ppt/slideLayouts/_rels/slideLayout6.xml.rels
  inflating: test/ppt/slideLayouts/_rels/slideLayout8.xml.rels
  inflating: test/ppt/slideLayouts/_rels/slideLayout9.xml.rels
  inflating: test/ppt/slideLayouts/_rels/slideLayout7.xml.rels
  inflating: test/ppt/slideLayouts/_rels/slideLayout4.xml.rels
  inflating: test/ppt/slideLayouts/_rels/slideLayout5.xml.rels
  inflating: test/ppt/slideLayouts/_rels/slideLayout1.xml.rels
  inflating: test/ppt/slideLayouts/_rels/slideLayout2.xml.rels
  inflating: test/ppt/slideMasters/_rels/slideMaster1.xml.rels
  inflating: test/ppt/slideLayouts/_rels/slideLayout10.xml.rels
  inflating: test/ppt/slideLayouts/slideLayout10.xml
  inflating: test/ppt/slideLayouts/slideLayout2.xml
  inflating: test/ppt/slideLayouts/slideLayout1.xml
  inflating: test/ppt/slideLayouts/_rels/slideLayout11.xml.rels
  inflating: test/ppt/slideMasters/slideMaster1.xml
  inflating: test/ppt/slideLayouts/slideLayout3.xml
  inflating: test/ppt/slideLayouts/slideLayout4.xml
  inflating: test/ppt/slideLayouts/slideLayout5.xml
  inflating: test/ppt/slideLayouts/slideLayout9.xml
  inflating: test/ppt/slideLayouts/slideLayout11.xml
  inflating: test/ppt/slideLayouts/slideLayout8.xml
  inflating: test/ppt/slideLayouts/slideLayout6.xml
  inflating: test/ppt/slideLayouts/slideLayout7.xml
  inflating: test/ppt/theme/theme1.xml
 extracting: test/ppt/media/image1.jpeg
  inflating: test/ppt/theme/_rels/theme1.xml.rels
 extracting: test/docProps/thumbnail.jpeg
  inflating: test/ppt/presProps.xml
  inflating: test/ppt/tableStyles.xml
  inflating: test/ppt/viewProps.xml
  inflating: test/docProps/app.xml
  inflating: test/docProps/core.xml

こんな感じに解凍されます。

スライドのタイトルや内容の文字列は ppt/slides/slide*.xml に含まれています。

この中を調べていくことになります。

ソースコードの一部

以下のコードは

  • isPpt(ファイル): パワポファイルかどうかの判定や
  • containWord(パワポファイル, 検索語): unzipと文字列の検索

で構成されています。

package main

import (
    "archive/zip"
    "path/filepath"
    "regexp"
)

var slide = regexp.MustCompile(filepath.Join("ppt", "slides", "slide"))

func isPpt(path string) bool {
    e := filepath.Ext(path)
    if e == ".ppt" || e == ".pptx" {
        return true
    }
    return false
}

func containWord(archive, word string) bool {
    reader, err := zip.OpenReader(archive)
    if err != nil {
        return false
    }

    for _, file := range reader.File {
        if slide.MatchString(file.Name) {
            fileReader, err := file.Open()
            if err != nil {
                return false
            }
            var p = make([]byte, file.FileInfo().Size())
            fileReader.Read(p)
            defer fileReader.Close()
            r := regexp.MustCompile(word)
            if r.MatchString(string(p)) {
                return true
            }
        }
    }
    return false
}

パワポファイルかどうかの判定は、あまりよろしくないですが拡張子で判定しています。

文字列の検索部分は、正規表現で含んでいるかどうかを見ています。

リポジトリはこちら

GitHub - k2la/pptgrep