package fi.celia.convert.chars;
import java.lang.StringBuffer;
import java.io.*;
public class RemoveExtraEOL
{
private StringBuffer sp = new StringBuffer ();
private int max = 1000000;
private FileReader fr;
private FileWriter fw;
private BufferedReader br;
private boolean tyhja_rivi = false;
private boolean loytyi_tupla_tyhja_riveja = false;
private String edellRivi = null;
private String text = null;
private String edell_strToimenpide = null;
private String edell_strErikoismerkkijono_rivin_alussa = null;
private int maxErikoismerkkijonoja = 0;
private String [] arrErikoismerkkijonoja;
private String [] arrPoistaEnnenJalkeen;
private int [] arrPoistaTyhjiaRiveja;
private int [] arrPoistaTyhjaRivinvaihtoja;
private boolean bErikoismerkkijono_rivin_alussa = false;
private String strErikoismerkkijono_rivin_alussa = null;
private int iPoistaTyhjiaRiveja = 0;
private int iPoistaTyhjiaRivinvaihtoja = 0;
private String strToimenpide;
private String JALKEEN = "jälkeen";
private String ENNEN = "ennen";
private int rivi = 0;
private boolean bAlkutyhjaRivitPois = true;
private boolean m_bRemoveLFBetweenKKoodi = true;
public static final String UTF_8 = "UTF-8";
public static final String UTF_16 = "UTF-16";
public static final String UTF_16BE = "UTF-16BE";
public static final String UTF_16LE = "UTF-16LE";
public static final String ISO_8859_1 = "ISO-8859-1";
public static final String US_ASCII = "US-ASCII";
private String defLanguage = UTF_8.toString().replace('_', '-');
private DecoderCharacterSet decoder;
public RemoveExtraEOL()
{
init();
}
private static void usage()
{
System.err.println("DtBook2ml4:n muotoiluohjelma V. 1.1");
System.err.println("Kaytto:" );
System.err.println("" + RemoveExtraEOL.class +" muutettava_tiedosto tulostiedosto" );
System.err.println(" - tulostus tiedostoon tai:" );
System.err.println("" + RemoveExtraEOL.class +" muutettava_tiedosto tulostiedosto [käytettävä_charset]" );
System.err.println(" - tulostus tiedostoon tai:" );
System.err.println("" + RemoveExtraEOL.class +" muutettava_tiedosto" );
System.err.println(" - tulostus näytälle" );
System.err.println(" - Käytetty oletus character setti on UTF-8" );
System.err.println(" - Sallitut character setit ovat:" );
System.err.println(" " + UTF_8 +", " + UTF_16+", " +
UTF_16BE+", " + UTF_16LE+", " +
ISO_8859_1+" ja " + US_ASCII);
}
public static void main(String [] args )
{
if (args.length < 1)
{
usage();
System.exit(1);
}
else
{
if (args.length > 4)
{
usage();
System.exit(2);
}
boolean bRemoveLFBetweenKKoodi = true;
RemoveExtraEOL removeExtraEOL = new RemoveExtraEOL();
try {
if (args.length == 1)
removeExtraEOL.removeExtraEOL(args[0], null, null, null, bRemoveLFBetweenKKoodi );
else
if (args.length == 2)
removeExtraEOL.removeExtraEOL(args[0], args[1], null, null, bRemoveLFBetweenKKoodi );
else
if (args.length == 3)
removeExtraEOL.removeExtraEOL(args[0], args[1], args[2], null, bRemoveLFBetweenKKoodi );
else
if (args.length == 4)
removeExtraEOL.removeExtraEOL(args[0], args[1], args[2], args[3], bRemoveLFBetweenKKoodi);
}catch(Exception e){
System.err.println("Virhe: " +e.getMessage() +"\n");
e.printStackTrace();
usage();
System.exit(3);
}
}
}
/**
* Tätä methodia kutsutaan hbl.java:sta tms käsin. Toimii niin kuin
* main-kutsu 4:llä parametrilla, MUTTA kun luonut väliaikaistiedoston
* (ks alla) poistaa destFileName-tiedoston, jonka jälkeen tekeen rename'n
* väliaikaistiedostolle ja antaa sille alkup. destFileName:n nimen.
*
* @param destFileName Ks yllä.
*/
public void handleEOLsAndConvertIntoSameFile(String destFileName,
String inputCharacterSet, String outputCharacterSet,
boolean bRemoveLFBetweenKKoodi)
throws Exception
{
String tmpFileName = RemoveExtraEOL.class.getName()+".tmp";
removeExtraEOL(destFileName, tmpFileName,
inputCharacterSet, outputCharacterSet,
bRemoveLFBetweenKKoodi);
Thread.sleep(2000); // varm. vuoksi, käyttikselle aikaa
File tmpFile = new File(tmpFileName);
if (!tmpFile.exists())
{
String msg = "Väliaikaistiedostoa ei ole: " +tmpFileName;
System.err.println(msg );
throw new Exception(msg);
}
File destFile = new File(destFileName);
if (!destFile.delete())
{
String msg = "Ei voida poistaa alkup.tiedostoa: " +destFileName;
System.err.println(msg );
throw new Exception(msg);
}
Thread.sleep(2000); // varm. vuoksi, käyttikselle aikaa
if (!tmpFile.renameTo(destFile))
{
String msg = "Ei voida uudelleen nimetä: " +tmpFileName +" "
+ destFileName +":ksi";
System.err.println(msg );
throw new Exception(msg);
}
}
private void init()
{
maxErikoismerkkijonoja = 7;
arrErikoismerkkijonoja = new String[max];
arrPoistaEnnenJalkeen = new String[max];
arrPoistaTyhjiaRiveja = new int[max];
arrPoistaTyhjaRivinvaihtoja = new int[max];
arrErikoismerkkijonoja[0] = "<k>|Kuvaselostus:";
arrPoistaEnnenJalkeen[0] = JALKEEN;
arrPoistaTyhjiaRiveja[0] = 1;
arrErikoismerkkijonoja[1] = "<t>---";
arrPoistaEnnenJalkeen[1] = ENNEN;
arrPoistaTyhjiaRiveja[1] = 2;
arrErikoismerkkijonoja[2] = "<k>";
arrPoistaEnnenJalkeen[2] = JALKEEN;
arrPoistaTyhjaRivinvaihtoja[2] = 1;
arrErikoismerkkijonoja[3] = "<v>";
arrErikoismerkkijonoja[4] = "<o>";
arrErikoismerkkijonoja[5] = "<o>";
arrErikoismerkkijonoja[6] = "<i>";
arrPoistaEnnenJalkeen[6] = ENNEN;
arrPoistaTyhjiaRiveja[6] = 2;
}
public void
removeExtraEOL(String fileName,
String outFileName,
String readWithCharSet,
String writeWithCharSet,
boolean bRemoveLFBetweenKKoodi)
throws Exception
{
if (fileName == null)
{
System.err.println("fileName is null!" );
return;
}
m_bRemoveLFBetweenKKoodi = bRemoveLFBetweenKKoodi;
if (writeWithCharSet == null)
writeWithCharSet = readWithCharSet;
if (readWithCharSet == null || readWithCharSet.trim().equals(""))
readWithCharSet = defLanguage;
if (writeWithCharSet == null || writeWithCharSet.trim().equals(""))
writeWithCharSet = defLanguage;
System.out.println("luku-merkistä=" + readWithCharSet);
System.out.println("kirjoitus-merkistä=" + writeWithCharSet);
DecoderCharacterSet.CHARACTERSET writeCharacterSet =
getCharacterSet(writeWithCharSet);
DecoderCharacterSet.CHARACTERSET readCharacterSet =
getCharacterSet(readWithCharSet);
decoder = new DecoderCharacterSet( readCharacterSet, writeCharacterSet);
// DecoderCharacterSet.CHARACTERSET.UTF_8.toString().replace('_','-')
try {
System.out.println("Avataan tiestoa: " + fileName);
File f = new File(fileName);
//fr = new FileReader (f);
InputStreamReader isr = new InputStreamReader(
new FileInputStream(f)
, readCharacterSet.toString().replace('_','-')
);
br = new BufferedReader (isr);
} catch ( Exception e){
e.printStackTrace();
}
try {
boolean ret = lue_puskuriin_ja_muokkaa_tiedostosta();
loytyi_tupla_tyhja_riveja = true;
while(loytyi_tupla_tyhja_riveja)
{
loytyi_tupla_tyhja_riveja = false;
while(ret)
{
ret = lue_puskuriin_ja_muokkaa_tiedostosta();
}
}
poistaTuplaKoodit();
if (outFileName == null)
System.out.println(sp.toString());
else
{
try {
System.out.println("Tulostetaan tiedostoa " + outFileName +" ... ");
File fo = new File(outFileName);
FileOutputStream fos = new FileOutputStream(fo);
OutputStreamWriter bos = new OutputStreamWriter(fos, writeWithCharSet);
//fos.write(decoder.convertCharacterSetBytes(sp.toString(), null));
bos.write(sp.toString());
bos.flush();
bos.close();
//fos.flush();
//fos.close();
System.out.println("Rivien muokkaus valmis.");
} catch ( Exception e){
System.out.println("Tulostustiedoston avaus ei onnistunut: " + e.getMessage());
e.printStackTrace();
return;
}
}
br.close();
} catch ( Exception e){
System.out.println("Virhe: " + e.getMessage());
e.printStackTrace();
}
}
private void poistaTuplaKoodit()
{
String tmp = sp.toString();
final String cnstKK = "<k><k>";
String newData = null;
// tarkista onko tupla k-koodeja ja jos on, ota pois:
//if (tmp.contains(cnstKK))
//{
newData = tmp.replaceAll(cnstKK, "<k>");
tmp = newData;
//}
final String cnstII = "<i><i>";
newData = tmp.replaceAll(cnstII, "<i>");
tmp = newData;
if (newData != null)
sp = new StringBuffer(newData);
}
private DecoderCharacterSet.CHARACTERSET
getCharacterSet(String writeWithCharSet)
throws Exception
{
if (writeWithCharSet == null)
throw new Exception("Väärä character set: "
+ writeWithCharSet);
else
if (writeWithCharSet.equalsIgnoreCase("UTF-8") )
return DecoderCharacterSet.CHARACTERSET.UTF_8;
else
if (writeWithCharSet.equalsIgnoreCase("UTF-16") )
return DecoderCharacterSet.CHARACTERSET.UTF_16;
else
if (writeWithCharSet.equalsIgnoreCase("UTF-16BE") )
return DecoderCharacterSet.CHARACTERSET.UTF_16BE;
else
if (writeWithCharSet.equalsIgnoreCase("UTF-16LE"))
return DecoderCharacterSet.CHARACTERSET.UTF_16LE;
else
if (writeWithCharSet.equalsIgnoreCase("ISO-8859-1"))
return DecoderCharacterSet.CHARACTERSET.ISO_8859_1;
else
if (writeWithCharSet.equalsIgnoreCase("US-ASCII"))
return DecoderCharacterSet.CHARACTERSET.US_ASCII;
else
throw new Exception("Väärä character set: "
+ writeWithCharSet);
}
private boolean lue_puskuriin_ja_muokkaa_tiedostosta()
throws IOException
{
boolean ei_rivinvaihtoa = false;
bErikoismerkkijono_rivin_alussa = false;
//edell_strErikoismerkkijono_rivin_alussa = strErikoismerkkijono_rivin_alussa;
edellRivi = text;
//String tmp_edellRivi = edellRivi;
text = br.readLine();
rivi++;
if (text == null)
return false;
bErikoismerkkijono_rivin_alussa = onErikoismerkkijono(text);
if (m_bRemoveLFBetweenKKoodi && bErikoismerkkijono_rivin_alussa) // on erik. mjnorivi
{
int len = text.length();
if (len > 0)
{
int ind = text.indexOf('<');
if (ind > -1)
{
int indKoodiKirjain = ind+1;
// ja jos on k-koodi rivi, niin poista mahdoll. edell. tyhjät rivit
char ch = text.charAt(indKoodiKirjain);
if ( ch == 'k' || ch == 'i')
{
poistaKTaiIKoodinEdestaTyhjiaRivinvaihtojaJosOn();
}
}
}
}
String tmp = text.trim();
if(tmp != null && "".equals(tmp) )
{
edell_strErikoismerkkijono_rivin_alussa = null;
if (edellRivi != null && "".equals(edellRivi.trim()))
{
loytyi_tupla_tyhja_riveja = true;
return true; // ei laiteta 2 tyhjää riviä peräkkäin
}
tyhja_rivi = true;
}
else
{
//tyhja_rivi = false;
//loytyi_tupla_tyhja_riveja = false;
// käsittely: edell. on erik.mjono rivi ja tämä rivi ei ole:
if (bErikoismerkkijono_rivin_alussa
&& edell_strErikoismerkkijono_rivin_alussa != null
&& edellRivi != null)
{
int ind = edell_strErikoismerkkijono_rivin_alussa.length();
if (ind > 0)
{
int len = edellRivi.length();
// tutki onko tämä edell.rivi ja tämän rivin erik.mjono samat:
if (edell_strErikoismerkkijono_rivin_alussa.equals(edellRivi))
{ // tämän rivin erik.mjono ja edell.rivi samat
if (edell_strErikoismerkkijono_rivin_alussa.equals(strErikoismerkkijono_rivin_alussa))
{
sp.deleteCharAt(sp.length()-1);
text = text.substring(strErikoismerkkijono_rivin_alussa.length());
}
}
}
}
else
if (!bErikoismerkkijono_rivin_alussa
&& edell_strErikoismerkkijono_rivin_alussa != null
&& edellRivi != null)
{
// tutki onko tämä edell.rivi ja tämän rivin erik.mjono samat
if (edell_strErikoismerkkijono_rivin_alussa.equals(edellRivi))
{
// yhdistä tämä rivi ja seuraava eli ota rivinvaihto pois
sp.deleteCharAt(sp.length()-1);
//tmp = sp.toString();
}
}
}
//String newValue = text.replaceAll("\n", "\n");
int len = text.length();
int ind = 0;
int ei_tyhjia_merkkeja = -1;
if (len > 0)
{
ind = text.indexOf('<');
if (ind > -1)
{
int indPlus1 = ind+1;
if (text.charAt(indPlus1) == 'k' ||
text.charAt(indPlus1) == 'v' ||
text.charAt(indPlus1) == 'i' ||
text.charAt(indPlus1) == 't'
)
ei_tyhjia_merkkeja = text.substring(0, ind).trim().length();
}
if (ei_tyhjia_merkkeja == 0)
{
text = text.substring(ind);
}
}
if (bAlkutyhjaRivitPois && rivi >= 2 && "".equals(text))
return true;
if (bAlkutyhjaRivitPois && rivi >= 2)
bAlkutyhjaRivitPois = false;
if (ei_rivinvaihtoa)
sp.append(text);
else
sp.append(text+"\n");
/*
if (bErikoismerkkijono_rivin_alussa
&& edell_strToimenpide != null
&& edell_strToimenpide.equals("<k>"))
{
if (text.length() > edell_strToimenpide.length()
&& text.charAt(edell_strToimenpide.length()+1) != '\n')
sp.append("\n");
}
*/
return true;
}
private String
poistaKTaiIKoodinEdestaTyhjiaRivinvaihtojaJosOn()
{
int cntPTR = sp.length();
int i = cntPTR-1;
StringBuffer spTmp = new StringBuffer (sp.toString());
char ch;
while(i > -1)
{
ch = spTmp.charAt(i);
if ( ch != '\n' && !Character.isWhitespace(ch))
{
spTmp.append('\n');
sp = spTmp;
return spTmp.toString();
}
spTmp.deleteCharAt(i);
i--;
}
spTmp.append('\n');
sp = spTmp;
return spTmp.toString();
}
private boolean
poistaTyhjiaRivinvaihtojaJosOn(String value)
{
if (iPoistaTyhjiaRivinvaihtoja < 1)
return false;
int cntPTR = iPoistaTyhjiaRivinvaihtoja;
int len = value.length(), i = 0;
if (strErikoismerkkijono_rivin_alussa != null)
i = strErikoismerkkijono_rivin_alussa.length();
boolean isWhiteSpace = false;
StringBuffer spTmp = new StringBuffer (value);
while(cntPTR > 0 && i < len)
{
isWhiteSpace = false;
if (!Character.isWhitespace(spTmp.charAt(i)))
return false;
isWhiteSpace = true;
spTmp.deleteCharAt(i);
len = spTmp.length();
cntPTR--;
}
//System.out.println("1strErikoismerkkijono_rivin_alussa=" + value);
return true;
}
private void
poistaTyhjiaRivejaJosOn(String value)
{
if (iPoistaTyhjiaRiveja < 1)
return;
int cntPTR = iPoistaTyhjiaRiveja;
int len = sp.length();
while(cntPTR > 0 && len > 0)
{
if (len > 1 && sp.charAt(sp.length()-1) == '\n'
&& sp.charAt(sp.length()-2) == '\n')
{
sp.deleteCharAt(sp.length()-1);
len = sp.length();
cntPTR--;
}
}
}
private boolean
onErikoismerkkijono(String value)
{
if (value == null)
return false;
if ("".equals(value))
return false;
String mjono;
for(int i = 0; i < maxErikoismerkkijonoja; i++)
{
mjono = arrErikoismerkkijonoja[i];
if (mjono == null)
continue;
if (erikoisMerkkijonoRivi(mjono, value))
{
bErikoismerkkijono_rivin_alussa = true;
edell_strErikoismerkkijono_rivin_alussa = strErikoismerkkijono_rivin_alussa;
strErikoismerkkijono_rivin_alussa = mjono;
edell_strToimenpide = strToimenpide;
strToimenpide = arrPoistaEnnenJalkeen[i];
iPoistaTyhjiaRiveja = arrPoistaTyhjiaRiveja[i];
iPoistaTyhjiaRivinvaihtoja = arrPoistaTyhjaRivinvaihtoja[2];
return true;
}
}
return false;
}
private boolean
erikoisMerkkijonoRivi(String mjono, String value)
{
if (mjono == null )
return false;
if (value == null )
return false;
int endIndex = mjono.length();
if (endIndex > 0 && endIndex <= value.length()
&& mjono.equalsIgnoreCase(value.substring(0, endIndex)))
return true;
return false;
}
}