pirka 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.document +3 -0
 - data/.gitignore +6 -0
 - data/.yardopts +1 -0
 - data/COPYING.txt +674 -0
 - data/ChangeLog.md +4 -0
 - data/Gemfile +14 -0
 - data/README.md +201 -0
 - data/Rakefile +27 -0
 - data/app/detect.rb +166 -0
 - data/app/highlight.rb +161 -0
 - data/app/lib.rb +52 -0
 - data/app/subcommand.rb +35 -0
 - data/app/update.rb +67 -0
 - data/app.rb +74 -0
 - data/bin/pirka +17 -0
 - data/lib/pirka/config.rb +110 -0
 - data/lib/pirka/library.rb +152 -0
 - data/lib/pirka/version.rb +22 -0
 - data/lib/pirka.rb +1 -0
 - data/pirka.gemspec +49 -0
 - data/test/fixtures/YWJj.yaml +10 -0
 - data/test/helper.rb +18 -0
 - data/test/test_library.rb +152 -0
 - data/test/test_pirka.rb +12 -0
 - metadata +296 -0
 
    
        data/Gemfile
    ADDED
    
    
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,201 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Pirka
         
     | 
| 
      
 2 
     | 
    
         
            +
            =====
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            * [Homepage](https://gitlab.com/KitaitiMakoto/pirka)
         
     | 
| 
      
 5 
     | 
    
         
            +
            * [Documentation](http://www.rubydoc.info/gems/pirka)
         
     | 
| 
      
 6 
     | 
    
         
            +
            * [Email](mailto:KitaitiMakoto at gmail.com)
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            Description
         
     | 
| 
      
 9 
     | 
    
         
            +
            -----------
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            Pirka highlights source code syntax in EPUB books
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            Features
         
     | 
| 
      
 14 
     | 
    
         
            +
            --------
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            * Highlights synatax in EPUB files
         
     | 
| 
      
 17 
     | 
    
         
            +
            * Extracts `<code>` elements from EPUB files and asks you which programing language they are, and then uses them to highlight
         
     | 
| 
      
 18 
     | 
    
         
            +
            * Downloads shared code and language information from Git repository
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            Examples
         
     | 
| 
      
 21 
     | 
    
         
            +
            --------
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ### Highlighting source code syntax in EPUB books ###
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                $ pirka path/to/book.epub
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            It's a short cut to:
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                $ pirka highlight path/to/book.epub
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ### Detecting source code from EPUB books ###
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                $ pirka detect path/to/book.epub
         
     | 
| 
      
 34 
     | 
    
         
            +
                Detecting code from "Book Title"
         
     | 
| 
      
 35 
     | 
    
         
            +
                Library file was saved to:
         
     | 
| 
      
 36 
     | 
    
         
            +
                path/to/library.yaml
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            `library.yaml` here includes:
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            * location of `<code>` element(expressed by [EPUB CFI][] but you don't need to undarstand it.)
         
     | 
| 
      
 41 
     | 
    
         
            +
            * `language` field with blank value
         
     | 
| 
      
 42 
     | 
    
         
            +
            * file path in EPUB file(zip archive)
         
     | 
| 
      
 43 
     | 
    
         
            +
            * source code
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            Example:
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  epubcfi(/6/64!/4/2/30/2):              # location
         
     | 
| 
      
 48 
     | 
    
         
            +
                    language:                            # language name. blank at first
         
     | 
| 
      
 49 
     | 
    
         
            +
                    item: OEBPS/text/p-003-003.xhtml     # file path in zip archive
         
     | 
| 
      
 50 
     | 
    
         
            +
                    code: |                              # source code
         
     | 
| 
      
 51 
     | 
    
         
            +
                      f1 = open("|cat", "w")
         
     | 
| 
      
 52 
     | 
    
         
            +
                      f2 = open("|sed 's/a/b/'", "w")
         
     | 
| 
      
 53 
     | 
    
         
            +
                      f1.print "Hello\n"
         
     | 
| 
      
 54 
     | 
    
         
            +
                      f2.print "abc\n"
         
     | 
| 
      
 55 
     | 
    
         
            +
                      f1.close
         
     | 
| 
      
 56 
     | 
    
         
            +
                      f2.close
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            In Pirka context, the file is called *library*.
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            `pirka highlight` command determines programming languages of source code according to this file.
         
     | 
| 
      
 61 
     | 
    
         
            +
            Read source code, determine languages, write it at `language` field, remove `code` field, and then
         
     | 
| 
      
 62 
     | 
    
         
            +
            you can highlight the EPUB file by `pirka highlight`.
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            You also determine languages interactively. Set `-i`(`--interactive`) option:
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                $ pirka detect -i path/to/book.epub
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            [EPUB CFI]: http://www.idpf.org/epub/linking/cfi/
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
            ### Updating libraries ###
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                $ pirka update
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            Pirka provides official library files for some EPUB books as Git repository((https://gitlab.com/KitaitiMakoto/pirka-library)[https://gitlab.com/KitaitiMakoto/pirka-library]). `pirka update` command fethes the files from the repository and you benefit from it.
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            Additionally, you can host library files by your own and make Pirka recognizes it by configuration file. See later section for that.
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            ### Listing supported books ###
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                $ pirka lib
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            `pirka lib` command lists books Pirka can highlight with:
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
            * Release Identifier(special identifier for EPUB books)
         
     | 
| 
      
 85 
     | 
    
         
            +
            * location of library file
         
     | 
| 
      
 86 
     | 
    
         
            +
            * title
         
     | 
| 
      
 87 
     | 
    
         
            +
            * some other metadata
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            ### Configuration ###
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            Pirka can be configured by environment variables, config file and command-line options.
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
            #### Environment variables ####
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            XDG_DATA_HOME
         
     | 
| 
      
 96 
     | 
    
         
            +
            : Affects directory to save library files.
         
     | 
| 
      
 97 
     | 
    
         
            +
            : Library files are saved to `$XDG_DATA_HOME/pirka/local`
         
     | 
| 
      
 98 
     | 
    
         
            +
            : The directory is used to search library, too.
         
     | 
| 
      
 99 
     | 
    
         
            +
            : Default: `$HOME/.local/share`
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            XDG_DATA_DIRS
         
     | 
| 
      
 102 
     | 
    
         
            +
            : Affects directory to save library files.
         
     | 
| 
      
 103 
     | 
    
         
            +
            : You can specify multiple directory by seperating with a colon like `XDG_DATA_DIRS=/dir1:/dir2`.
         
     | 
| 
      
 104 
     | 
    
         
            +
            : `/dir1/pirka/local` and `/dir2/pirka/local` are used to search library, for example.
         
     | 
| 
      
 105 
     | 
    
         
            +
            : Default: `/usr/local/share:/usr/share`
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            XDG_CONFIG_HOME
         
     | 
| 
      
 108 
     | 
    
         
            +
            : Affects directory to search and save config file.
         
     | 
| 
      
 109 
     | 
    
         
            +
            : `$XDG_CONFIG_DIRS/pirka.yaml` is recognized as config file.
         
     | 
| 
      
 110 
     | 
    
         
            +
            : Default: `$HOME/.config`
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
            XDG_CONFIG_DIRS
         
     | 
| 
      
 113 
     | 
    
         
            +
            : Affects directory to search config file.
         
     | 
| 
      
 114 
     | 
    
         
            +
            : You can specify multiple directory by seperating with a colon like `XDG_CONFIG_DIRS=/dir1:/dir2`.
         
     | 
| 
      
 115 
     | 
    
         
            +
            : `/dir1/pirka.yaml` and `/dir2/pirka.yaml` are searched as config file.
         
     | 
| 
      
 116 
     | 
    
         
            +
            : Default: `/etc/xdg`
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            #### Config file ####
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            Config file is a YAML file. Properties below are recognized:
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
            data_home
         
     | 
| 
      
 123 
     | 
    
         
            +
            : Directory to save and search library files.
         
     | 
| 
      
 124 
     | 
    
         
            +
            : Default: `$XDG_CONFIG_HOME/pirka/local`
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            additional_directories
         
     | 
| 
      
 127 
     | 
    
         
            +
            : Directories to search library files.
         
     | 
| 
      
 128 
     | 
    
         
            +
            : Expressed by sequence(array).
         
     | 
| 
      
 129 
     | 
    
         
            +
            : Default: `[]`
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            library_repositories
         
     | 
| 
      
 132 
     | 
    
         
            +
            : Git repository URIs used by `pirka lib` command.
         
     | 
| 
      
 133 
     | 
    
         
            +
            : Expressed by sequence(array).
         
     | 
| 
      
 134 
     | 
    
         
            +
            : Default: `[]`
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
            #### Command-line options ####
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            You can configure Pirka by `pirka` command's global options:
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
            `-c`, `--config=FILE`
         
     | 
| 
      
 141 
     | 
    
         
            +
            : Path to config file.
         
     | 
| 
      
 142 
     | 
    
         
            +
            : Default: /Users/ikeda/.config/pirka.yaml
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
            `-s`, `--data-home=DIRECTORY`
         
     | 
| 
      
 145 
     | 
    
         
            +
            : Same to config file's `data_home` property.
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
            `-d`, `--directory=DIRECTORY`
         
     | 
| 
      
 148 
     | 
    
         
            +
            : Same to config file's `additional_directories` property.
         
     | 
| 
      
 149 
     | 
    
         
            +
            : Able to multilpe times.
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
            You can also see help by
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                $ pirka --help
         
     | 
| 
      
 154 
     | 
    
         
            +
                Pirka highlights source code syntax in EPUB files
         
     | 
| 
      
 155 
     | 
    
         
            +
                
         
     | 
| 
      
 156 
     | 
    
         
            +
                Usage: pirka [global options] [<command>] [options]
         
     | 
| 
      
 157 
     | 
    
         
            +
                
         
     | 
| 
      
 158 
     | 
    
         
            +
                Global options:
         
     | 
| 
      
 159 
     | 
    
         
            +
                    -c, --config=FILE                Config file. Defaults to /Users/ikeda/.config/pirka.yaml
         
     | 
| 
      
 160 
     | 
    
         
            +
                    -s, --data-home=DIRECTORY        Directory to *SAVE* library data
         
     | 
| 
      
 161 
     | 
    
         
            +
                    -d, --directory=DIRECTORY        Directory to *SEARCH* library data.
         
     | 
| 
      
 162 
     | 
    
         
            +
                                                     Specify multiple times to add multiple directories.
         
     | 
| 
      
 163 
     | 
    
         
            +
                
         
     | 
| 
      
 164 
     | 
    
         
            +
                Commands:
         
     | 
| 
      
 165 
     | 
    
         
            +
                    highlight        Highlights source code in EPUB file
         
     | 
| 
      
 166 
     | 
    
         
            +
                    detect           Detects source code from EPUB file and generate library file
         
     | 
| 
      
 167 
     | 
    
         
            +
                    update           Update library files by remote files
         
     | 
| 
      
 168 
     | 
    
         
            +
                    lib              Show library infomation
         
     | 
| 
      
 169 
     | 
    
         
            +
                If command is ommitted, highlight is used with no option
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
            Requirements
         
     | 
| 
      
 172 
     | 
    
         
            +
            ------------
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
            * Ruby 2.2 or later
         
     | 
| 
      
 175 
     | 
    
         
            +
            * C compiler to compile [Nokogiri][] gem
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
            [Nokogiri]: http://www.nokogiri.org/
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
            Install
         
     | 
| 
      
 180 
     | 
    
         
            +
            -------
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                $ gem install pirka
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
            ### Make faster ###
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
            By default, Pirka uses [archive-zip][] gem, a pure Ruby implementation, for zip archive but you can make command execution faster by using [Zip/Ruby][] gem, a C implementation. Just install Zip/Ruby:
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                $ gem install zipruby
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
            Pirka, actually internally-used [EPUB Parser][], tries to load Zip/Ruby and use it if available.
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
            [archive-zip]: https://github.com/javanthropus/archive-zip
         
     | 
| 
      
 193 
     | 
    
         
            +
            [Zip/Ruby]: https://bitbucket.org/winebarrel/zip-ruby/wiki/Home
         
     | 
| 
      
 194 
     | 
    
         
            +
            [EPUB Parser]: http://www.rubydoc.info/gems/epub-parser/file/docs/Home.markdown
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
            Copyright
         
     | 
| 
      
 197 
     | 
    
         
            +
            ---------
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
            Copyright (c) 2017 KITAITI Makoto
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
            See {file:COPYING.txt} for details.
         
     | 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            begin
         
     | 
| 
      
 6 
     | 
    
         
            +
              require 'bundler/setup'
         
     | 
| 
      
 7 
     | 
    
         
            +
            rescue LoadError => e
         
     | 
| 
      
 8 
     | 
    
         
            +
              abort e.message
         
     | 
| 
      
 9 
     | 
    
         
            +
            end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            require 'rake'
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            task :default => :test
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            require 'rubygems/tasks'
         
     | 
| 
      
 16 
     | 
    
         
            +
            Gem::Tasks.new
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            require 'rake/testtask'
         
     | 
| 
      
 19 
     | 
    
         
            +
            Rake::TestTask.new do |test|
         
     | 
| 
      
 20 
     | 
    
         
            +
              test.libs << 'test'
         
     | 
| 
      
 21 
     | 
    
         
            +
              test.pattern = 'test/**/test_*.rb'
         
     | 
| 
      
 22 
     | 
    
         
            +
              test.verbose = true
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            require 'yard'
         
     | 
| 
      
 26 
     | 
    
         
            +
            YARD::Rake::YardocTask.new  
         
     | 
| 
      
 27 
     | 
    
         
            +
            task :doc => :yard
         
     | 
    
        data/app/detect.rb
    ADDED
    
    | 
         @@ -0,0 +1,166 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "optparse"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "optparse/pathname"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "epub/parser"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "epub/cfi"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "epub/searcher"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "rouge"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "rouge/lexers/fluentd"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require "colored"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require "pirka/library"
         
     | 
| 
      
 10 
     | 
    
         
            +
            require_relative "subcommand"
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            module Pirka
         
     | 
| 
      
 13 
     | 
    
         
            +
              class App
         
     | 
| 
      
 14 
     | 
    
         
            +
                class Detect
         
     | 
| 
      
 15 
     | 
    
         
            +
                  PROGRAM_NAME = "detect"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  DESCRIPTION = "Detects source code from EPUB file and generate library file"
         
     | 
| 
      
 17 
     | 
    
         
            +
                  ARGS = %w[EPUB_FILE]
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  include Subcommand
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def initialize(config)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    super
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                    @library_path = nil
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @interactive = false
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    @available_lexers = Rouge::Lexer.all.sort_by(&:tag).each_with_object({}).with_index {|(lexer, lexers), index|
         
     | 
| 
      
 28 
     | 
    
         
            +
                      lexers[(index + 1).to_s] = lexer
         
     | 
| 
      
 29 
     | 
    
         
            +
                    }
         
     | 
| 
      
 30 
     | 
    
         
            +
                    initial = nil
         
     | 
| 
      
 31 
     | 
    
         
            +
                    @lexers_display = @available_lexers.collect {|(index, lexer)|
         
     | 
| 
      
 32 
     | 
    
         
            +
                      init = lexer.title[0].upcase
         
     | 
| 
      
 33 
     | 
    
         
            +
                      if initial == init
         
     | 
| 
      
 34 
     | 
    
         
            +
                        option = ""
         
     | 
| 
      
 35 
     | 
    
         
            +
                      else
         
     | 
| 
      
 36 
     | 
    
         
            +
                        option = "\n"
         
     | 
| 
      
 37 
     | 
    
         
            +
                        initial = init
         
     | 
| 
      
 38 
     | 
    
         
            +
                      end
         
     | 
| 
      
 39 
     | 
    
         
            +
                      option << "#{index})".bold << " " << lexer.title
         
     | 
| 
      
 40 
     | 
    
         
            +
                      option << "(#{lexer.aliases.join(', ')})" unless lexer.aliases.empty?
         
     | 
| 
      
 41 
     | 
    
         
            +
                      option
         
     | 
| 
      
 42 
     | 
    
         
            +
                    }.join("  ")
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @commands = ["s) skip", "q) quit", "c) show code", "o) show options"].join("  ")
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @commands = {
         
     | 
| 
      
 45 
     | 
    
         
            +
                      "s" => "skip",
         
     | 
| 
      
 46 
     | 
    
         
            +
                      "q" => "quit",
         
     | 
| 
      
 47 
     | 
    
         
            +
                      "c" => "show code",
         
     | 
| 
      
 48 
     | 
    
         
            +
                      "o" => "show options"
         
     | 
| 
      
 49 
     | 
    
         
            +
                    }.collect {|(key, command)|
         
     | 
| 
      
 50 
     | 
    
         
            +
                      "#{key})".bold << " " << command
         
     | 
| 
      
 51 
     | 
    
         
            +
                    }.join("  ")
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def run(argv)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    parse_options! argv
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                    epub_path = argv.shift
         
     | 
| 
      
 58 
     | 
    
         
            +
                    raise ArgumentError, 'Specify EPUB file' unless epub_path
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 61 
     | 
    
         
            +
                      # @todo Make this optional
         
     | 
| 
      
 62 
     | 
    
         
            +
                      require 'epub/maker/ocf/physical_container/zipruby'
         
     | 
| 
      
 63 
     | 
    
         
            +
                      EPUB::OCF::PhysicalContainer.adapter = :Zipruby
         
     | 
| 
      
 64 
     | 
    
         
            +
                    rescue LoadError
         
     | 
| 
      
 65 
     | 
    
         
            +
                    end
         
     | 
| 
      
 66 
     | 
    
         
            +
                    epub = EPUB::Parser.parse(epub_path)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    $stderr.puts "Detecting code from \"#{epub.title}\""
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    codelist = {}
         
     | 
| 
      
 70 
     | 
    
         
            +
                    library = Library.new
         
     | 
| 
      
 71 
     | 
    
         
            +
                    library.metadata["Release Identifier"] = epub.release_identifier
         
     | 
| 
      
 72 
     | 
    
         
            +
                    library.metadata["title"] = epub.title
         
     | 
| 
      
 73 
     | 
    
         
            +
                    catch do |quit|
         
     | 
| 
      
 74 
     | 
    
         
            +
                      EPUB::Searcher.search_element(epub, css: 'code').each do |result|
         
     | 
| 
      
 75 
     | 
    
         
            +
                        item = result[:itemref].item
         
     | 
| 
      
 76 
     | 
    
         
            +
                        if @interactive
         
     | 
| 
      
 77 
     | 
    
         
            +
                          catch do |skip|
         
     | 
| 
      
 78 
     | 
    
         
            +
                            show_item item
         
     | 
| 
      
 79 
     | 
    
         
            +
                            show_code result[:element]
         
     | 
| 
      
 80 
     | 
    
         
            +
                            show_options
         
     | 
| 
      
 81 
     | 
    
         
            +
                            show_commands
         
     | 
| 
      
 82 
     | 
    
         
            +
                            i = ask
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                            while true
         
     | 
| 
      
 85 
     | 
    
         
            +
                              case i
         
     | 
| 
      
 86 
     | 
    
         
            +
                              when "s"
         
     | 
| 
      
 87 
     | 
    
         
            +
                                throw skip
         
     | 
| 
      
 88 
     | 
    
         
            +
                              when "q"
         
     | 
| 
      
 89 
     | 
    
         
            +
                                throw quit
         
     | 
| 
      
 90 
     | 
    
         
            +
                              when "c"
         
     | 
| 
      
 91 
     | 
    
         
            +
                                show_item item
         
     | 
| 
      
 92 
     | 
    
         
            +
                                show_code(result[:element])
         
     | 
| 
      
 93 
     | 
    
         
            +
                                show_options
         
     | 
| 
      
 94 
     | 
    
         
            +
                                show_commands
         
     | 
| 
      
 95 
     | 
    
         
            +
                                i = ask
         
     | 
| 
      
 96 
     | 
    
         
            +
                              when "o"
         
     | 
| 
      
 97 
     | 
    
         
            +
                                show_options
         
     | 
| 
      
 98 
     | 
    
         
            +
                                show_commands
         
     | 
| 
      
 99 
     | 
    
         
            +
                                i = ask
         
     | 
| 
      
 100 
     | 
    
         
            +
                              else
         
     | 
| 
      
 101 
     | 
    
         
            +
                                lexer = @available_lexers[i]
         
     | 
| 
      
 102 
     | 
    
         
            +
                                unless lexer
         
     | 
| 
      
 103 
     | 
    
         
            +
                                  i = ask
         
     | 
| 
      
 104 
     | 
    
         
            +
                                  next
         
     | 
| 
      
 105 
     | 
    
         
            +
                                end
         
     | 
| 
      
 106 
     | 
    
         
            +
                                library.codelist[result[:location]] = {"language" => lexer.tag}
         
     | 
| 
      
 107 
     | 
    
         
            +
                                break
         
     | 
| 
      
 108 
     | 
    
         
            +
                              end
         
     | 
| 
      
 109 
     | 
    
         
            +
                            end
         
     | 
| 
      
 110 
     | 
    
         
            +
                          end
         
     | 
| 
      
 111 
     | 
    
         
            +
                        else
         
     | 
| 
      
 112 
     | 
    
         
            +
                          library.codelist[result[:location]] = ({
         
     | 
| 
      
 113 
     | 
    
         
            +
                            "language" => nil,
         
     | 
| 
      
 114 
     | 
    
         
            +
                            "item" => result[:itemref].item.entry_name,
         
     | 
| 
      
 115 
     | 
    
         
            +
                            "code" => result[:element].content
         
     | 
| 
      
 116 
     | 
    
         
            +
                          })
         
     | 
| 
      
 117 
     | 
    
         
            +
                        end
         
     | 
| 
      
 118 
     | 
    
         
            +
                      end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                      path = library.save(@library_path)
         
     | 
| 
      
 121 
     | 
    
         
            +
                      $stderr.puts "Library file was saved to:"
         
     | 
| 
      
 122 
     | 
    
         
            +
                      $stdout.puts path
         
     | 
| 
      
 123 
     | 
    
         
            +
                    end
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                  private
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  def parse_options!(argv)
         
     | 
| 
      
 129 
     | 
    
         
            +
                    super do |opt|
         
     | 
| 
      
 130 
     | 
    
         
            +
                      opt.separator ""
         
     | 
| 
      
 131 
     | 
    
         
            +
                      opt.on "-i", "--interactive" do
         
     | 
| 
      
 132 
     | 
    
         
            +
                        @interactive = true
         
     | 
| 
      
 133 
     | 
    
         
            +
                      end
         
     | 
| 
      
 134 
     | 
    
         
            +
                      opt.on "-o", "--output=FILE", "File to save library data", Pathname do |path|
         
     | 
| 
      
 135 
     | 
    
         
            +
                        @library_path = path
         
     | 
| 
      
 136 
     | 
    
         
            +
                      end
         
     | 
| 
      
 137 
     | 
    
         
            +
                    end
         
     | 
| 
      
 138 
     | 
    
         
            +
                  end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                  def show_item(item)
         
     | 
| 
      
 141 
     | 
    
         
            +
                    $stderr.puts
         
     | 
| 
      
 142 
     | 
    
         
            +
                    $stderr.puts item.entry_name
         
     | 
| 
      
 143 
     | 
    
         
            +
                  end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                  def show_code(code)
         
     | 
| 
      
 146 
     | 
    
         
            +
                    $stderr.puts
         
     | 
| 
      
 147 
     | 
    
         
            +
                    $stderr.puts code.content
         
     | 
| 
      
 148 
     | 
    
         
            +
                    $stderr.puts
         
     | 
| 
      
 149 
     | 
    
         
            +
                  end
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  def show_options
         
     | 
| 
      
 152 
     | 
    
         
            +
                    $stderr.puts @lexers_display
         
     | 
| 
      
 153 
     | 
    
         
            +
                  end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                  def show_commands
         
     | 
| 
      
 156 
     | 
    
         
            +
                    $stderr.puts
         
     | 
| 
      
 157 
     | 
    
         
            +
                    $stderr.puts @commands
         
     | 
| 
      
 158 
     | 
    
         
            +
                  end
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                  def ask
         
     | 
| 
      
 161 
     | 
    
         
            +
                    $stderr.print "Which language?  "
         
     | 
| 
      
 162 
     | 
    
         
            +
                    $stdin.gets.chomp
         
     | 
| 
      
 163 
     | 
    
         
            +
                  end
         
     | 
| 
      
 164 
     | 
    
         
            +
                end
         
     | 
| 
      
 165 
     | 
    
         
            +
              end
         
     | 
| 
      
 166 
     | 
    
         
            +
            end
         
     | 
    
        data/app/highlight.rb
    ADDED
    
    | 
         @@ -0,0 +1,161 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "pathname"
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "optparse"
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "optparse/pathname"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "epub/parser"
         
     | 
| 
      
 5 
     | 
    
         
            +
            require "epub/maker"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "rouge"
         
     | 
| 
      
 7 
     | 
    
         
            +
            require "rouge/lexers/fluentd"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require "pirka/library"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative "subcommand"
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            module Pirka
         
     | 
| 
      
 12 
     | 
    
         
            +
              class App
         
     | 
| 
      
 13 
     | 
    
         
            +
                class Highlight
         
     | 
| 
      
 14 
     | 
    
         
            +
                  PROGRAM_NAME = "highlight"
         
     | 
| 
      
 15 
     | 
    
         
            +
                  DESCRIPTION = "Highlights source code in EPUB file"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  ARGS = %w[EPUB_FILE]
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  include Subcommand
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  DUMMY_ORIGIN = Addressable::URI.parse("file:///")
         
     | 
| 
      
 21 
     | 
    
         
            +
                  CSS_PATH = "pirka/style.css" # @todo Avoid conflict with existing item by other than Pirka
         
     | 
| 
      
 22 
     | 
    
         
            +
                  CSS_CLASS_NAME = "pirka"
         
     | 
| 
      
 23 
     | 
    
         
            +
                  SCOPE = "code.#{CSS_CLASS_NAME}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                  THEME = "github"
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def initialize(config)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    super
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @library_path = nil
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  # @todo Handle multiple renditions
         
     | 
| 
      
 32 
     | 
    
         
            +
                  def run(argv)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    parse_options! argv
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                    epub_path = argv.shift
         
     | 
| 
      
 36 
     | 
    
         
            +
                    raise ArgumentError, 'Specify EPUB file' unless epub_path
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 39 
     | 
    
         
            +
                      # @todo Make this optional
         
     | 
| 
      
 40 
     | 
    
         
            +
                      require 'epub/maker/ocf/physical_container/zipruby'
         
     | 
| 
      
 41 
     | 
    
         
            +
                      EPUB::OCF::PhysicalContainer.adapter = :Zipruby
         
     | 
| 
      
 42 
     | 
    
         
            +
                    rescue LoadError
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                    epub = EPUB::Parser.parse(epub_path)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    library = find_library(epub.unique_identifier, epub.modified)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    raise RuntimeError, "Cannot find code list #{Library.filename(epub.release_identifier)} for #{epub.release_identifier}(#{epub_path}) in any directory of #{Library.directories.join(", ")}" unless library
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                    css_item = add_css_file(epub)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    need_save = highlight_contents(epub, css_item, library)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    need_save << css_item
         
     | 
| 
      
 51 
     | 
    
         
            +
                    need_save.uniq!
         
     | 
| 
      
 52 
     | 
    
         
            +
                    update_modified_date(epub, Time.now)
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                    save_file epub, need_save
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  # @param [EPUB::Book, EPUB::Book::Features] epub
         
     | 
| 
      
 58 
     | 
    
         
            +
                  # @return [EPUB::Publication::Package::Manifest::Item] item indicating added CSS file
         
     | 
| 
      
 59 
     | 
    
         
            +
                  def add_css_file(epub)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    rootfile_path = DUMMY_ORIGIN + epub.ocf.container.rootfile.full_path
         
     | 
| 
      
 61 
     | 
    
         
            +
                    style = Rouge::Theme.find(THEME).new(scope: SCOPE).render
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                    epub.package.manifest.make_item {|item|
         
     | 
| 
      
 64 
     | 
    
         
            +
                      item.href = (DUMMY_ORIGIN + CSS_PATH).route_from(rootfile_path)
         
     | 
| 
      
 65 
     | 
    
         
            +
                      # IMPROVEMENT: Want to call item.entry_name = css_path
         
     | 
| 
      
 66 
     | 
    
         
            +
                      item.media_type = 'text/css'
         
     | 
| 
      
 67 
     | 
    
         
            +
                      item.id = CSS_PATH.gsub('/', '-') # @todo Avoid conflict with existing items
         
     | 
| 
      
 68 
     | 
    
         
            +
                      item.content = style
         
     | 
| 
      
 69 
     | 
    
         
            +
                    }
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  # @todo Do the best when file for release identifier is not find but for unique identifier found
         
     | 
| 
      
 73 
     | 
    
         
            +
                  def find_library(unique_identifier, modified)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    @library_path ? Library.load_file(@library_path) :
         
     | 
| 
      
 75 
     | 
    
         
            +
                      Library.find_by_release_identifier("#{unique_identifier}@#{modified}")
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                  # @todo Consider descendant elements of code
         
     | 
| 
      
 79 
     | 
    
         
            +
                  def highlight_contents(epub, css_item, library)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    need_save = []
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    formatter = Rouge::Formatters::HTML.new
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                    library.each.reverse_each do |(cfi, data)|
         
     | 
| 
      
 85 
     | 
    
         
            +
                      lang = data["language"]
         
     | 
| 
      
 86 
     | 
    
         
            +
                      unless lang
         
     | 
| 
      
 87 
     | 
    
         
            +
                        warn "Language for #{cfi} is not detected"
         
     | 
| 
      
 88 
     | 
    
         
            +
                        next
         
     | 
| 
      
 89 
     | 
    
         
            +
                      end
         
     | 
| 
      
 90 
     | 
    
         
            +
                      itemref, elem, _ = EPUB::Searcher.search_by_cfi(epub, cfi)
         
     | 
| 
      
 91 
     | 
    
         
            +
                      item = itemref.item
         
     | 
| 
      
 92 
     | 
    
         
            +
                      doc = elem.document
         
     | 
| 
      
 93 
     | 
    
         
            +
                      lexer = Rouge::Lexer.find(lang) || Rouge::Lexer.guess(source: elem.content)
         
     | 
| 
      
 94 
     | 
    
         
            +
                      unless lexer
         
     | 
| 
      
 95 
     | 
    
         
            +
                        warn "Cannot find lexer for #{lang}"
         
     | 
| 
      
 96 
     | 
    
         
            +
                        next
         
     | 
| 
      
 97 
     | 
    
         
            +
                      end
         
     | 
| 
      
 98 
     | 
    
         
            +
                      elem.inner_html = formatter.format(lexer.lex(elem.content)) # @todo Consider the case `elem` has descendants
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                      classes = (elem["class"] || "").split(/\s+/)
         
     | 
| 
      
 101 
     | 
    
         
            +
                      unless classes.include? CSS_CLASS_NAME
         
     | 
| 
      
 102 
     | 
    
         
            +
                        classes << CSS_CLASS_NAME
         
     | 
| 
      
 103 
     | 
    
         
            +
                        elem["class"] = classes.join(" ")
         
     | 
| 
      
 104 
     | 
    
         
            +
                      end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
                      link = doc.at('#pirka') # @todo Avoid conflict with existing link
         
     | 
| 
      
 107 
     | 
    
         
            +
                      unless link
         
     | 
| 
      
 108 
     | 
    
         
            +
                        item_entry_name = DUMMY_ORIGIN + item.entry_name
         
     | 
| 
      
 109 
     | 
    
         
            +
                        entry_name = DUMMY_ORIGIN + css_item.entry_name
         
     | 
| 
      
 110 
     | 
    
         
            +
                        href = entry_name.route_from(item_entry_name)
         
     | 
| 
      
 111 
     | 
    
         
            +
                        link = Nokogiri::XML::Node.new('link', doc)
         
     | 
| 
      
 112 
     | 
    
         
            +
                        link['href'] = href
         
     | 
| 
      
 113 
     | 
    
         
            +
                        link['type'] = 'text/css'
         
     | 
| 
      
 114 
     | 
    
         
            +
                        link['rel'] = 'stylesheet'
         
     | 
| 
      
 115 
     | 
    
         
            +
                        link['id'] = 'pirka'
         
     | 
| 
      
 116 
     | 
    
         
            +
                        head = (doc/'head').first
         
     | 
| 
      
 117 
     | 
    
         
            +
                        head << link
         
     | 
| 
      
 118 
     | 
    
         
            +
                      end
         
     | 
| 
      
 119 
     | 
    
         
            +
                      item.content = doc.to_xml
         
     | 
| 
      
 120 
     | 
    
         
            +
                      need_save << item
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                    need_save
         
     | 
| 
      
 124 
     | 
    
         
            +
                  end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                  def update_modified_date(epub, time = Time.now)
         
     | 
| 
      
 127 
     | 
    
         
            +
                    modified = epub.modified
         
     | 
| 
      
 128 
     | 
    
         
            +
                    unless modified
         
     | 
| 
      
 129 
     | 
    
         
            +
                      modified = EPUB::Publication::Package::Metadata::Meta.new
         
     | 
| 
      
 130 
     | 
    
         
            +
                      modified.property = 'dcterms:modified'
         
     | 
| 
      
 131 
     | 
    
         
            +
                      epub.package.metadata.metas << modified
         
     | 
| 
      
 132 
     | 
    
         
            +
                    end
         
     | 
| 
      
 133 
     | 
    
         
            +
                    modified.content = time.utc.iso8601
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                    modified
         
     | 
| 
      
 136 
     | 
    
         
            +
                  end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                  def save_file(epub, need_save)
         
     | 
| 
      
 139 
     | 
    
         
            +
                    need_save.each do |item|
         
     | 
| 
      
 140 
     | 
    
         
            +
                      item.save
         
     | 
| 
      
 141 
     | 
    
         
            +
                      epub.package.manifest << item
         
     | 
| 
      
 142 
     | 
    
         
            +
                    end
         
     | 
| 
      
 143 
     | 
    
         
            +
                    epub.package.edit
         
     | 
| 
      
 144 
     | 
    
         
            +
                  end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                  private
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                  # @todo theme
         
     | 
| 
      
 149 
     | 
    
         
            +
                  # @todo CSS file path
         
     | 
| 
      
 150 
     | 
    
         
            +
                  # @todo scope
         
     | 
| 
      
 151 
     | 
    
         
            +
                  def parse_options!(argv)
         
     | 
| 
      
 152 
     | 
    
         
            +
                    super do |opt|
         
     | 
| 
      
 153 
     | 
    
         
            +
                      opt.separator ""
         
     | 
| 
      
 154 
     | 
    
         
            +
                      opt.on "-l", "--library=FILE", "library file", Pathname do |path|
         
     | 
| 
      
 155 
     | 
    
         
            +
                        @library_path = path
         
     | 
| 
      
 156 
     | 
    
         
            +
                      end
         
     | 
| 
      
 157 
     | 
    
         
            +
                    end
         
     | 
| 
      
 158 
     | 
    
         
            +
                  end
         
     | 
| 
      
 159 
     | 
    
         
            +
                end
         
     | 
| 
      
 160 
     | 
    
         
            +
              end
         
     | 
| 
      
 161 
     | 
    
         
            +
            end
         
     | 
    
        data/app/lib.rb
    ADDED
    
    | 
         @@ -0,0 +1,52 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require "pirka/library"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Pirka
         
     | 
| 
      
 4 
     | 
    
         
            +
              class App
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Lib
         
     | 
| 
      
 6 
     | 
    
         
            +
                  PROGRAM_NAME = "lib"
         
     | 
| 
      
 7 
     | 
    
         
            +
                  DESCRIPTION = "Show library infomation"
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  include Subcommand
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def run(argv)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    # show all
         
     | 
| 
      
 13 
     | 
    
         
            +
                    # show remote repos
         
     | 
| 
      
 14 
     | 
    
         
            +
                    # show data dirs
         
     | 
| 
      
 15 
     | 
    
         
            +
                    # show data home
         
     | 
| 
      
 16 
     | 
    
         
            +
                    # show books
         
     | 
| 
      
 17 
     | 
    
         
            +
                    # show book metadata
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    no_dir_file_length = Library::SUBDIR_LENGTH + Library::EXT.length
         
     | 
| 
      
 20 
     | 
    
         
            +
                    Library.directories.each do |dir|
         
     | 
| 
      
 21 
     | 
    
         
            +
                      next unless dir.directory?
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                      dir.each_child do |child|
         
     | 
| 
      
 24 
     | 
    
         
            +
                        if child.to_path.length < no_dir_file_length && child.extname != Library::EXT
         
     | 
| 
      
 25 
     | 
    
         
            +
                          show_info child
         
     | 
| 
      
 26 
     | 
    
         
            +
                          next
         
     | 
| 
      
 27 
     | 
    
         
            +
                        end
         
     | 
| 
      
 28 
     | 
    
         
            +
                        next unless child.directory?
         
     | 
| 
      
 29 
     | 
    
         
            +
                        next unless child.basename.to_path.length == Library::SUBDIR_LENGTH
         
     | 
| 
      
 30 
     | 
    
         
            +
                        child.each_child do |lib|
         
     | 
| 
      
 31 
     | 
    
         
            +
                          next unless lib.extname == Library::EXT
         
     | 
| 
      
 32 
     | 
    
         
            +
                          next unless lib.file?
         
     | 
| 
      
 33 
     | 
    
         
            +
                          show_info lib
         
     | 
| 
      
 34 
     | 
    
         
            +
                        end
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
                    end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  def show_info(path)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    $stdout.puts Library.load_file(path).metadata.to_yaml
         
     | 
| 
      
 41 
     | 
    
         
            +
                    $stdout.puts "library: #{path}"
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  private
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  def parse_options!(argv)
         
     | 
| 
      
 47 
     | 
    
         
            +
                    super do |opt|
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
            end
         
     | 
    
        data/app/subcommand.rb
    ADDED
    
    | 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Pirka
         
     | 
| 
      
 2 
     | 
    
         
            +
              class App
         
     | 
| 
      
 3 
     | 
    
         
            +
                module Subcommand
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 5 
     | 
    
         
            +
                    def included(base)
         
     | 
| 
      
 6 
     | 
    
         
            +
                      APPS[base::PROGRAM_NAME] = base
         
     | 
| 
      
 7 
     | 
    
         
            +
                    end
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  # @param [Config]
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def initialize(config)
         
     | 
| 
      
 12 
     | 
    
         
            +
                    @config = config
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  private
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  # @todo Consider the case the subcommand has no option
         
     | 
| 
      
 18 
     | 
    
         
            +
                  def parse_options!(argv)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    parser = OptionParser.new {|opt|
         
     | 
| 
      
 20 
     | 
    
         
            +
                      usage = "Usage: #{opt.program_name} [options] #{self.class::PROGRAM_NAME}"
         
     | 
| 
      
 21 
     | 
    
         
            +
                      usage << " " << self.class::ARGS.join(" ") if self::class.const_defined?(:ARGS)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                      opt.program_name = "#{opt.program_name} [global options] #{self.class::PROGRAM_NAME}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                      opt.banner = <<EOB
         
     | 
| 
      
 25 
     | 
    
         
            +
            #{self::class::DESCRIPTION}
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            #{usage}
         
     | 
| 
      
 28 
     | 
    
         
            +
            EOB
         
     | 
| 
      
 29 
     | 
    
         
            +
                      yield opt if block_given?
         
     | 
| 
      
 30 
     | 
    
         
            +
                    }
         
     | 
| 
      
 31 
     | 
    
         
            +
                    parser.order! argv
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     |