とりあえず試しにつくってみた。
夏目漱石「こころ」

青空文庫にあった「こころ」のテキストファイルを分割してHTML化するJavaプログラム。


// 青空文庫をケータイで読めるようにする
//   指定した文字数(といっても行で区切る)でファイルに切る
//     1ファイルに最低1行は入るようにする
//   toc, prev, next のリンク
//     ケータイらしいaccesskey指定prev[4]toc[0]next[6]
//   titleタグに「題名 - 1ページ」
//   0001.html, 0002.html, 0003.html, ... を作ってから
//   toc.html を作成する
//   目次と別にトップページがほしいときは index.html を自分で作る
//   index.html -> toc.html -> それぞれのページhtml
 
import java.io.*;
import java.util.*;
import java.text.*;
 
public class MobileHtmlMaker {
 
  public static void main(String[] args) throws Exception{
    
    // 設定
    String inputFile = "C:\\work\\mobilehtml\\kokoro.txt";
    String inputFileEncoding = "Windows-31J";
    String outputDir = "C:\\work\\mobilehtml";
    String outputFileEncoding = "Windows-31J";
    String tocFile = "index.html";
    String htmlEncoding = "Shift_JIS";
    int limit = 2000;
    String title = "夏目漱石「こころ」";
    String footerHtml = "<a href=\"/m/\">NI-Lab.</a>";
    
    // 元データのテキストファイルを読み込む
    String s = TextFile.readTextFile(inputFile, inputFileEncoding);
    String[] lines = s.replaceAll("\r", "\n").replaceAll("\n\n", "\n").split("\n");
    
    // 指定した文字数以内になるように分割。分割する単位は行
    ArrayList<List<String>> pages = new ArrayList<List<String>>();
    {
      int currentPageNumber = 1;
      ArrayList<String> currentLines = new ArrayList<String>();
      int currentTextSize = 0;
      for(int i=0; i<lines.length; i++){
        currentTextSize += lines[i].length();
        if(currentTextSize > limit){
          if(currentLines.size() < 1){
            currentLines.add(lines[i]);
            pages.add(currentLines);
            currentLines = new ArrayList<String>();
            currentTextSize = 0;
          }else{
            pages.add(currentLines);
            currentLines = new ArrayList<String>();
            currentTextSize = 0;
            currentLines.add(lines[i]);
          }
          currentPageNumber++;
        }else{
          currentLines.add(lines[i]);
        }
      }
      if(currentLines.size() < 1){
        pages.add(currentLines);
        currentLines = new ArrayList<String>();
        currentTextSize = 0;
        currentPageNumber++;
      }
    }
    
    // 目次ファイルを出力
    outputTocFile(outputDir, tocFile, outputFileEncoding, title, pages.size(), footerHtml, htmlEncoding);
    
    // ページ毎のファイルを出力
    for(int i=0; i<pages.size(); i++){
      boolean prev = true;
      boolean next = true;
      if(i == 0){
        prev = false;
      }else if(i == pages.size()-1){
        next = false;
      }
      outputPageFile(outputDir, outputFileEncoding, pages.get(i), title, i+1, prev, next, tocFile, htmlEncoding);
    }
  }
  
  private static String getFileName(int pageNumber){
    DecimalFormat formatter = new DecimalFormat("0000");
    return formatter.format(pageNumber) + ".html";
  }
  
  private static void outputPageFile(String outputDir, String outputFileEncoding, List<String> lines, String title, int pageNumber, boolean prev, boolean next, String tocFile, String charset) throws Exception{
    String titleText = title + " - " + pageNumber + "ページ";
    StringBuffer buf = new StringBuffer();
    buf.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + charset + "\"><title>" + titleText + "</title><body><p>" + titleText + "</p><hr><p>");
    for(int i=0; i<lines.size(); i++){
      buf.append(lines.get(i) + "<br>\r\n");
    }
    buf.append("</p><hr><p>");
    if(prev){
      buf.append("<a accesskey=\"4\" href=\"" + getFileName(pageNumber-1) + "\">[4]前のページ</a><br>");
    }
    buf.append(" <a accesskey=\"0\" href=\"" + tocFile + "\">[0]目次</a><br>");
    if(next){
      buf.append("<a accesskey=\"6\" href=\"" + getFileName(pageNumber+1) + "\">[6]次のページ</a><br>");
    }
    buf.append("</p></body></html>\r\n");
    TextFile.writeTextFile(outputDir + File.separator + getFileName(pageNumber), buf.toString(), outputFileEncoding);
  }
 
  private static void outputTocFile(String outputDir, String tocFileName, String outputFileEncoding, String title, int pages, String footerHtml, String charset) throws Exception{
    StringBuffer buf = new StringBuffer();
    buf.append("<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + charset + "\"><title>" + title + "</title></head><body><h1>" + title + "</h1><hr><p>");
    for(int i=1; i<pages+1; i++){
      buf.append("<a href=\"" + getFileName(i) + "\">" + i + "</a> \r\n");
    }
    buf.append("</p><hr><p>" + footerHtml + "</p></body></html>\r\n");
    TextFile.writeTextFile(outputDir + File.separator + tocFileName, buf.toString(), outputFileEncoding);
  }
}

テキストファイルを読み書きするクラス。


import java.io.*;
import java.nio.*;
import java.nio.channels.*;
 
// テキストファイルの読み書き
public class TextFile {
 
  public static void main(String[] args) throws Exception {
    String s = readTextFile("a.txt", "UTF-8");
    System.out.println(s);
    writeTextFile("b.txt", s, "UTF-8");
  }
 
  public static String readTextFile(String path, String encoding) throws Exception {
    RandomAccessFile raf = new RandomAccessFile(path, "r");
    FileChannel fc = raf.getChannel();
    ByteBuffer bb = ByteBuffer.allocate((int) fc.size());
    fc.read(bb);
    raf.close();
    return new String(bb.array(), encoding);
  }
 
  public static void writeTextFile(String path, String content, String encoding) throws Exception {
    BufferedWriter writer =
      new BufferedWriter(
        new OutputStreamWriter(
          new FileOutputStream(path), encoding));
    writer.write(content);
    writer.flush();
    writer.close();
  }
 
}

tags: Java zurazure

Posted by NI-Lab. (@nilab)