mirror of
https://github.com/OMGeeky/ATCS.git
synced 2025-12-26 23:57:25 +01:00
Added code to generate new english.pot file and some tools to ease
transition of existing translations towards the new content.
This commit is contained in:
@@ -78,6 +78,9 @@ public class AboutEditor extends Editor {
|
||||
"<a href=\"https://jsoup.org/\">jsoup</a> by Jonathan Hedley<br/>" +
|
||||
"License: <a href=\"https://jsoup.org/license\">MIT License</a><br/>" +
|
||||
"<br/>" +
|
||||
"A slightly modified version of <a href=\"https://launchpad.net/po-parser\">General PO Parser</a> by Bal<61>zs T<>th<br/>" +
|
||||
"License: <a href=\"http://www.gnu.org/licenses/gpl-3.0.html\">GPL v3</a><br/>" +
|
||||
"<br/>" +
|
||||
"See the tabs below to find the full license text for each of these.<br/>" +
|
||||
"<br/>" +
|
||||
"The Windows installer was created with:<br/>" +
|
||||
|
||||
154
src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotComparator.java
Normal file
154
src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotComparator.java
Normal file
@@ -0,0 +1,154 @@
|
||||
package com.gpl.rpg.atcontentstudio.ui.tools.i18n;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import com.gpl.rpg.atcontentstudio.model.Project;
|
||||
|
||||
import net.launchpad.tobal.poparser.POEntry;
|
||||
import net.launchpad.tobal.poparser.POFile;
|
||||
import net.launchpad.tobal.poparser.POParser;
|
||||
|
||||
public class PotComparator {
|
||||
|
||||
Map<String, List<String>> stringsResourcesNew = new LinkedHashMap<String, List<String>>();
|
||||
Map<String, String> resourcesStringsNew = new LinkedHashMap<String, String>();
|
||||
|
||||
Map<String, List<String>> stringsResourcesOld = new LinkedHashMap<String, List<String>>();
|
||||
Map<String, String> resourcesStringsOld = new LinkedHashMap<String, String>();
|
||||
|
||||
|
||||
public PotComparator(Project proj) {
|
||||
POParser parser = new POParser();
|
||||
|
||||
POFile newPot = parser.parseFile(new File(proj.alteredContent.baseFolder.getAbsolutePath()+File.separator+"english.pot"));
|
||||
if (newPot == null) {
|
||||
System.err.println("Cannot locate new english.pot file at "+proj.alteredContent.baseFolder.getAbsolutePath()+File.separator);
|
||||
}
|
||||
extractFromPoFile(newPot, stringsResourcesNew, resourcesStringsNew);
|
||||
|
||||
POFile oldPot = parser.parseFile(new File(proj.baseContent.baseFolder.getAbsolutePath()+File.separator+"assets"+File.separator+"translation"+File.separator+"english.pot"));
|
||||
if (oldPot == null) {
|
||||
System.err.println("Cannot locate old english.pot file at "+proj.baseContent.baseFolder.getAbsolutePath()+File.separator+"assets"+File.separator+"translations"+File.separator);
|
||||
}
|
||||
extractFromPoFile(oldPot, stringsResourcesOld, resourcesStringsOld);
|
||||
}
|
||||
|
||||
|
||||
private void extractFromPoFile(POFile po, Map<String, List<String>> stringsResources, Map<String, String> resourcesStrings) {
|
||||
for (POEntry entry : po.getEntryArray()) {
|
||||
Vector<String> resources = entry.getStringsByType(POEntry.StringType.REFERENCE);
|
||||
Vector<String> msgids = entry.getStringsByType(POEntry.StringType.MSGID);
|
||||
if (resources == null || resources.size() == 0 || msgids == null || msgids.size() == 0) continue;
|
||||
String msgid = msgids.get(0);
|
||||
if (msgids.size() > 1) {
|
||||
for (int i = 1; i < msgids.size(); i++) {
|
||||
msgid += "\n";
|
||||
msgid += msgids.get(i);
|
||||
}
|
||||
}
|
||||
for (String resLine : resources) {
|
||||
String[] resArray = resLine.split(" ");
|
||||
for (String res : resArray) {
|
||||
resourcesStrings.put(res, msgid);
|
||||
if (stringsResources.get(msgid) == null) {
|
||||
stringsResources.put(msgid, new LinkedList<String>());
|
||||
}
|
||||
stringsResources.get(msgid).add(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void compare() {
|
||||
for (String oldRes : resourcesStringsOld.keySet()) {
|
||||
String newString = resourcesStringsNew.get(oldRes);
|
||||
String oldString = resourcesStringsOld.get(oldRes);
|
||||
if (newString != null) {
|
||||
if (!newString.equals(oldString)) {
|
||||
List<String> allOldResources = stringsResourcesOld.get(oldString);
|
||||
List<String> allNewResources = stringsResourcesNew.get(oldString);
|
||||
System.out.println("---------------------------------------------");
|
||||
System.out.println("--- TYPO CHECK ------------------------------");
|
||||
System.out.println("---------------------------------------------");
|
||||
System.out.println("String at: "+oldRes);
|
||||
if (allOldResources.size() > 1) {
|
||||
System.out.println("Also present at:");
|
||||
for (String res : allOldResources) {
|
||||
if (!res.equals(oldRes)) {
|
||||
System.out.println("- "+res);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (allNewResources != null) {
|
||||
System.out.println("Still present at: ");
|
||||
for (String res : allNewResources) {
|
||||
System.out.println("- "+res);
|
||||
}
|
||||
}
|
||||
System.out.println("Was : \""+oldString+"\"");
|
||||
System.out.println("Now : \""+newString+"\"");
|
||||
|
||||
}
|
||||
} else {
|
||||
List<String> allOldResources = stringsResourcesOld.get(oldString);
|
||||
List<String> allNewResources = stringsResourcesNew.get(oldString);
|
||||
if (allOldResources.size() >= 1) {
|
||||
System.out.println("---------------------------------------------");
|
||||
System.out.println("--- REMOVED RESOURCE ------------------------");
|
||||
System.out.println("---------------------------------------------");
|
||||
System.out.println("String at: "+oldRes);
|
||||
if (allOldResources.size() > 1) {
|
||||
System.out.println("And also at:");
|
||||
for (String res : allOldResources) {
|
||||
if (!res.equals(oldRes)) {
|
||||
System.out.println("- "+res);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Was: \""+oldString+"\"");
|
||||
if (allNewResources == null) {
|
||||
System.out.println("Absent from new.");
|
||||
} else {
|
||||
System.out.println("Still present at: ");
|
||||
for (String res : allNewResources) {
|
||||
System.out.println("- "+res);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
removedStrings: for (String oldString : stringsResourcesOld.keySet()) {
|
||||
if (stringsResourcesNew.get(oldString) == null) {
|
||||
List<String> allOldResources = stringsResourcesOld.get(oldString);
|
||||
if (allOldResources.size() >= 1) {
|
||||
if (allOldResources.size() > 0) {
|
||||
for (String res : allOldResources) {
|
||||
String newString = resourcesStringsNew.get(res);
|
||||
if (newString != null) {
|
||||
continue removedStrings;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("---------------------------------------------");
|
||||
System.out.println("--- REMOVED STRING --------------------------");
|
||||
System.out.println("---------------------------------------------");
|
||||
System.out.println("String: \""+oldString+"\"");
|
||||
if (allOldResources.size() > 0) {
|
||||
System.out.println("Was at:");
|
||||
for (String res : allOldResources) {
|
||||
System.out.println("- "+res);
|
||||
}
|
||||
}
|
||||
System.out.println("This string is absent from the new file, and its attached resources are missing too.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
114
src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotGenerator.java
Normal file
114
src/com/gpl/rpg/atcontentstudio/ui/tools/i18n/PotGenerator.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package com.gpl.rpg.atcontentstudio.ui.tools.i18n;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
||||
import com.gpl.rpg.atcontentstudio.model.Project;
|
||||
import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition;
|
||||
import com.gpl.rpg.atcontentstudio.model.gamedata.Dialogue;
|
||||
import com.gpl.rpg.atcontentstudio.model.gamedata.Item;
|
||||
import com.gpl.rpg.atcontentstudio.model.gamedata.ItemCategory;
|
||||
import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement;
|
||||
import com.gpl.rpg.atcontentstudio.model.gamedata.NPC;
|
||||
import com.gpl.rpg.atcontentstudio.model.gamedata.Quest;
|
||||
import com.gpl.rpg.atcontentstudio.model.gamedata.QuestStage;
|
||||
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
|
||||
|
||||
public class PotGenerator {
|
||||
|
||||
public static void generatePotFileForProject(Project proj) {
|
||||
Map<String, List<String>> stringsResources = new LinkedHashMap<String, List<String>>();
|
||||
Map<String, String> resourcesStrings = new LinkedHashMap<String, String>();
|
||||
|
||||
GameSource gsrc = proj.baseContent;
|
||||
|
||||
for (ActorCondition ac : gsrc.gameData.actorConditions) {
|
||||
pushString(stringsResources, resourcesStrings, ac.display_name, getPotContextComment(ac));
|
||||
}
|
||||
|
||||
for (Dialogue d : gsrc.gameData.dialogues ) {
|
||||
pushString(stringsResources, resourcesStrings, d.message, getPotContextComment(d));
|
||||
if (d.replies == null) continue;
|
||||
for (Dialogue.Reply r : d.replies) {
|
||||
if (r.text != null && !r.text.equals(Dialogue.Reply.GO_NEXT_TEXT) ) {
|
||||
pushString(stringsResources, resourcesStrings, r.text, getPotContextComment(d)+":"+d.replies.indexOf(r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemCategory ic : gsrc.gameData.itemCategories) {
|
||||
pushString(stringsResources, resourcesStrings, ic.name, getPotContextComment(ic));
|
||||
}
|
||||
|
||||
for (Item i : gsrc.gameData.items) {
|
||||
pushString(stringsResources, resourcesStrings, i.name, getPotContextComment(i));
|
||||
pushString(stringsResources, resourcesStrings, i.description, getPotContextComment(i)+":description");
|
||||
}
|
||||
|
||||
for (NPC npc : gsrc.gameData.npcs ) {
|
||||
pushString(stringsResources, resourcesStrings, npc.name, getPotContextComment(npc));
|
||||
}
|
||||
|
||||
for (Quest q : gsrc.gameData.quests) {
|
||||
pushString(stringsResources, resourcesStrings, q.name, getPotContextComment(q));
|
||||
for (QuestStage qs : q.stages) {
|
||||
pushString(stringsResources, resourcesStrings, qs.log_text, getPotContextComment(q)+":"+Integer.toString(qs.progress));
|
||||
}
|
||||
}
|
||||
|
||||
for (WorldmapSegment ws : gsrc.worldmap) {
|
||||
for (WorldmapSegment.NamedArea area : ws.labels.values()) {
|
||||
pushString(stringsResources, resourcesStrings, area.name, gsrc.worldmap.worldmapFile.getName()+":"+ws.id+":"+area.id);
|
||||
}
|
||||
}
|
||||
|
||||
File f = new File(proj.alteredContent.baseFolder, "english.pot");
|
||||
try {
|
||||
FileWriter fw = new FileWriter(f);
|
||||
for (String msg : stringsResources.keySet()) {
|
||||
for (String ctx : stringsResources.get(msg)) {
|
||||
fw.write("#: ");
|
||||
fw.write(ctx);
|
||||
fw.write("\n");
|
||||
}
|
||||
fw.write("msgid \"");
|
||||
fw.write(msg);
|
||||
fw.write("\"\nmsgstr \"\"\n\n");
|
||||
|
||||
}
|
||||
fw.flush();
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void pushString (Map<String, List<String>> stringsResources, Map<String, String> resourcesStrings, String translatableString, String resourceIdentifier) {
|
||||
if (translatableString == null) return;
|
||||
if (translatableString.contains("\n")) {
|
||||
translatableString = translatableString.replaceAll("\n", "\\\\n\"\n\"");
|
||||
translatableString = "\"\n\""+translatableString;
|
||||
}
|
||||
resourcesStrings.put(resourceIdentifier, translatableString);
|
||||
List<String> resourceIdentifiers = stringsResources.get(translatableString);
|
||||
if (resourceIdentifiers == null) {
|
||||
resourceIdentifiers = new LinkedList<String>();
|
||||
stringsResources.put(translatableString, resourceIdentifiers);
|
||||
}
|
||||
resourceIdentifiers.add(resourceIdentifier);
|
||||
}
|
||||
|
||||
private static String getPotContextComment(JSONElement e) {
|
||||
return e.jsonFile.getName()+":"+e.id;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
100
src/net/launchpad/tobal/poparser/POEntry.java
Normal file
100
src/net/launchpad/tobal/poparser/POEntry.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
*
|
||||
* @author Balázs Tóth (tobal17@gmail.com)
|
||||
*
|
||||
* Modified by Kevin POCHAT for ATCS
|
||||
*/
|
||||
package net.launchpad.tobal.poparser;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
public class POEntry
|
||||
{
|
||||
private POLine[] Lines;
|
||||
|
||||
public enum StringType
|
||||
{
|
||||
/**translator comments*/
|
||||
TRLCMNT,
|
||||
/**extracted comments*/
|
||||
EXTCMNT,
|
||||
/**reference*/
|
||||
REFERENCE,
|
||||
/**flag*/
|
||||
FLAG,
|
||||
/**previous context*/
|
||||
PREVCTXT,
|
||||
/**previous untranslated string singular*/
|
||||
PREVUNTRSTRSING,
|
||||
/**previous untranslated string plural*/
|
||||
PREVUNTRSTRPLUR,
|
||||
/**untranslated string singular*/
|
||||
MSGID,
|
||||
/**translated string*/
|
||||
MSGSTR,
|
||||
/**context*/
|
||||
MSGCTXT,
|
||||
/**header line*/
|
||||
HEADER
|
||||
|
||||
// TODO: support for plural untranslated strings,
|
||||
// and translated string cases
|
||||
}
|
||||
|
||||
POEntry()
|
||||
{
|
||||
Lines = new POLine[0];
|
||||
}
|
||||
|
||||
public void addLine(StringType type, String string)
|
||||
{
|
||||
boolean hasType = false;
|
||||
POLine line = null;
|
||||
for(int i = 0; i < Lines.length; i++)
|
||||
{
|
||||
if(Lines[i].getType() == type)
|
||||
{
|
||||
hasType = true;
|
||||
line = Lines[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(hasType)
|
||||
{
|
||||
line.addString(string);
|
||||
}
|
||||
else
|
||||
{
|
||||
line = new POLine(type, string);
|
||||
POLine[] templines = Lines.clone();
|
||||
Lines = new POLine[Lines.length+1];
|
||||
for(int i = 0; i < Lines.length-1; i++)
|
||||
{
|
||||
Lines[i] = templines[i];
|
||||
}
|
||||
Lines[Lines.length-1] = line;
|
||||
}
|
||||
}
|
||||
|
||||
public POLine[] getLines()
|
||||
{
|
||||
return Lines;
|
||||
}
|
||||
|
||||
public Vector<String> getStringsFromLine(int index)
|
||||
{
|
||||
return Lines[index].getStrings();
|
||||
}
|
||||
|
||||
public Vector<String> getStringsByType(POEntry.StringType type)
|
||||
{
|
||||
for(int i = 0; i < Lines.length; i++)
|
||||
{
|
||||
if(Lines[i].getType() == type)
|
||||
{
|
||||
return Lines[i].getStrings();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
139
src/net/launchpad/tobal/poparser/POFile.java
Normal file
139
src/net/launchpad/tobal/poparser/POFile.java
Normal file
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
*
|
||||
* @author Balázs Tóth (tobal17@gmail.com)
|
||||
*
|
||||
* Modified by Kevin POCHAT for ATCS
|
||||
*/
|
||||
package net.launchpad.tobal.poparser;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Vector;
|
||||
|
||||
public class POFile
|
||||
{
|
||||
private POEntry[] entries;
|
||||
private POEntry header;
|
||||
private File file;
|
||||
|
||||
POFile(POEntry[] entries, POEntry header, File file)
|
||||
{
|
||||
this.entries = entries;
|
||||
this.header = header;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns with the name of the po file
|
||||
* @return name of po file
|
||||
*/
|
||||
public String getFileName()
|
||||
{
|
||||
return file == null ? null : file.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns with the POEntry object array
|
||||
* @return POEntry array
|
||||
*/
|
||||
public POEntry[] getEntryArray()
|
||||
{
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the POEntry object specified by the index
|
||||
* @param index, index of the entry
|
||||
* @return one POEntry object
|
||||
*/
|
||||
public POEntry getEntry(int index)
|
||||
{
|
||||
return entries[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how many entries are there in the po file
|
||||
* @return count of entries
|
||||
*/
|
||||
public int getEntryLength()
|
||||
{
|
||||
return entries.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified flag is set in the entry,
|
||||
* given by the entry index.
|
||||
* @param flag, string representing the flag
|
||||
* @param entryIndex, index of the entry to examine
|
||||
* @return true, if the flag is set, false otherwise
|
||||
*/
|
||||
public boolean checkFlag(String flag, int entryIndex)
|
||||
{
|
||||
boolean status = false;
|
||||
Vector<String> strings = new Vector<String>();
|
||||
strings = entries[entryIndex].getStringsByType(POEntry.StringType.FLAG);
|
||||
if (strings != null)
|
||||
{
|
||||
for(int i = 0; i < strings.size(); i++)
|
||||
{
|
||||
if (strings.get(i).contains(flag))
|
||||
{
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns with all the strings of the given type, from
|
||||
* the specified entry.
|
||||
* @param entryIndex
|
||||
* @param type
|
||||
* @return String array of specified type
|
||||
*/
|
||||
public String[] getStringsFromEntryByType(int entryIndex, POEntry.StringType type)
|
||||
{
|
||||
Vector<String> vector = entries[entryIndex].getStringsByType(type);
|
||||
String[] str = new String[vector.size()];
|
||||
for(int i = 0; i < str.length; i++)
|
||||
{
|
||||
str[i] = vector.get(i);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* For debug purposes
|
||||
*/
|
||||
public void printFile()
|
||||
{
|
||||
for(int i = 0; i < entries.length; i++)
|
||||
{
|
||||
POLine[] lines = entries[i].getLines();
|
||||
for(int j = 0; j < lines.length; j++)
|
||||
{
|
||||
Vector<String> strings = lines[j].getStrings();
|
||||
for(int k = 0; k < strings.size(); k++)
|
||||
{
|
||||
System.out.println(strings.get(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For debug purposes
|
||||
*/
|
||||
public void printHeader()
|
||||
{
|
||||
POLine[] lines = header.getLines();
|
||||
for(int j = 0; j < lines.length; j++)
|
||||
{
|
||||
Vector<String> strings = lines[j].getStrings();
|
||||
for(int k = 0; k < strings.size(); k++)
|
||||
{
|
||||
System.out.println(strings.get(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
42
src/net/launchpad/tobal/poparser/POLine.java
Normal file
42
src/net/launchpad/tobal/poparser/POLine.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
*
|
||||
* @author Balázs Tóth (tobal17@gmail.com)
|
||||
*
|
||||
* Modified by Kevin POCHAT for ATCS
|
||||
*/
|
||||
package net.launchpad.tobal.poparser;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
public class POLine
|
||||
{
|
||||
private POEntry.StringType type;
|
||||
private Vector<String> strings;
|
||||
|
||||
POLine(POEntry.StringType type, String string)
|
||||
{
|
||||
this.type = type;
|
||||
this.strings = new Vector<String>();
|
||||
this.strings.add(string);
|
||||
}
|
||||
|
||||
public void addString(String string)
|
||||
{
|
||||
strings.add(string);
|
||||
}
|
||||
|
||||
public Vector<String> getStrings()
|
||||
{
|
||||
return strings;
|
||||
}
|
||||
|
||||
public POEntry.StringType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getVectorSize()
|
||||
{
|
||||
return strings.size();
|
||||
}
|
||||
}
|
||||
275
src/net/launchpad/tobal/poparser/POParser.java
Normal file
275
src/net/launchpad/tobal/poparser/POParser.java
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
*
|
||||
* @author Balázs Tóth (tobal17@gmail.com)
|
||||
*
|
||||
* Based on the work of István Nyitrai
|
||||
*
|
||||
* Modified by Kevin POCHAT for ATCS
|
||||
*/
|
||||
package net.launchpad.tobal.poparser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.BufferedReader;
|
||||
import java.util.Vector;
|
||||
|
||||
public class POParser
|
||||
{
|
||||
private POEntry[] entries;
|
||||
private POEntry header;
|
||||
// private File file;
|
||||
private POEntry.StringType parserMode;
|
||||
|
||||
/**
|
||||
* Creates a POParser object. Use getPOFile() method,
|
||||
* to access parsed data.
|
||||
* @param file, File object of the PO file
|
||||
*/
|
||||
public POParser()
|
||||
{
|
||||
parserMode = null;
|
||||
}
|
||||
|
||||
public POFile parseFile(File file)
|
||||
{
|
||||
return parse(file);
|
||||
}
|
||||
|
||||
public POFile parseStream(BufferedReader br) throws IOException {
|
||||
return parse(br);
|
||||
}
|
||||
|
||||
private String unQuote(String string)
|
||||
{
|
||||
String str = new String();
|
||||
if(string.startsWith("\""))
|
||||
{
|
||||
str = string.substring(1);
|
||||
string = str;
|
||||
}
|
||||
if(string.endsWith("\""))
|
||||
{
|
||||
str = string.substring(0, string.length()-1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
private POFile parse(File file)
|
||||
{
|
||||
POFile result = null;
|
||||
try
|
||||
{
|
||||
FileReader fr = new FileReader(file);
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
result = parse(br);
|
||||
br.close();
|
||||
fr.close();
|
||||
}
|
||||
catch (java.io.FileNotFoundException e)
|
||||
{
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
catch (java.io.IOException e) {
|
||||
System.out.println(e.toString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private POFile parse(BufferedReader br) throws IOException {
|
||||
Vector<String> rawentry = new Vector<String>(1, 1);
|
||||
Vector<Vector<String>> rawentries = new Vector<Vector<String>>();
|
||||
String line;
|
||||
int id = 0;
|
||||
while((line = br.readLine()) != null)
|
||||
{
|
||||
if(!line.equals(""))
|
||||
{
|
||||
if(!line.startsWith("#~")) // ignore
|
||||
{
|
||||
rawentry.add(line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(rawentry.size() > 0)
|
||||
{
|
||||
rawentry.add(0, String.valueOf(id));
|
||||
id++;
|
||||
rawentries.add(new Vector<String>(rawentry));
|
||||
rawentry = new Vector<String>(1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!rawentry.equals(rawentries.lastElement()) && rawentry.size() > 0)
|
||||
{
|
||||
rawentry.add(0, String.valueOf(id));
|
||||
rawentries.add(new Vector<String>(rawentry));
|
||||
}
|
||||
this.header = parseHeader(rawentries);
|
||||
this.entries = parseEntries(rawentries);
|
||||
|
||||
return new POFile(entries, header, null);
|
||||
}
|
||||
|
||||
private POEntry parseHeader(Vector<Vector<String>> vectors)
|
||||
{
|
||||
POEntry tempheader = new POEntry();
|
||||
|
||||
// is this header?
|
||||
Vector<String> rawentry = vectors.get(0);
|
||||
if(new Integer(rawentry.get(0)) == 0 && rawentry.contains("msgid \"\""))
|
||||
{
|
||||
for(int i = 1; i < rawentry.size(); i++)
|
||||
{
|
||||
String str = rawentry.get(i);
|
||||
tempheader.addLine(POEntry.StringType.HEADER, str);
|
||||
str = new String();
|
||||
}
|
||||
return tempheader;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private POEntry[] parseEntries(Vector<Vector<String>> vectors)
|
||||
{
|
||||
String line = new String();
|
||||
boolean thereIsHeader = false;
|
||||
|
||||
// is this header
|
||||
Vector<String> rawentry = vectors.get(0);
|
||||
if(new Integer(rawentry.get(0)) == 0 && rawentry.contains("msgid \"\""))
|
||||
{
|
||||
thereIsHeader = true;
|
||||
}
|
||||
|
||||
int size;
|
||||
if(thereIsHeader)
|
||||
{
|
||||
size = vectors.size()-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = vectors.size();
|
||||
}
|
||||
|
||||
POEntry[] tempentries = new POEntry[size];
|
||||
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
POEntry entry = new POEntry();
|
||||
|
||||
if(thereIsHeader)
|
||||
rawentry = vectors.get(i+1);
|
||||
else
|
||||
rawentry = vectors.get(i);
|
||||
|
||||
rawentry.remove(0);
|
||||
for(int j = 0; j < rawentry.size(); j++)
|
||||
{
|
||||
line = rawentry.get(j);
|
||||
POEntry.StringType strType = null;
|
||||
int subStrIndex = 0;
|
||||
if(line.startsWith("#"))
|
||||
{
|
||||
parserMode = null;
|
||||
if(line.startsWith("# "))
|
||||
{
|
||||
strType = POEntry.StringType.TRLCMNT;
|
||||
if (line.startsWith("# "))
|
||||
{
|
||||
subStrIndex = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
subStrIndex = 2;
|
||||
}
|
||||
}
|
||||
if(line.startsWith("#."))
|
||||
{
|
||||
strType = POEntry.StringType.EXTCMNT;
|
||||
subStrIndex = 3;
|
||||
}
|
||||
if(line.startsWith("#:"))
|
||||
{
|
||||
strType = POEntry.StringType.REFERENCE;
|
||||
subStrIndex = 3;
|
||||
}
|
||||
if(line.startsWith("#,"))
|
||||
{
|
||||
strType = POEntry.StringType.FLAG;
|
||||
subStrIndex = 3;
|
||||
}
|
||||
if(line.startsWith("#|"))
|
||||
{
|
||||
// TODO: can these comments be multi line? if no,
|
||||
// drop support for it
|
||||
if(line.startsWith("#| msgctxt "))
|
||||
{
|
||||
strType = POEntry.StringType.PREVCTXT;
|
||||
parserMode = strType;
|
||||
subStrIndex = 11;
|
||||
}
|
||||
if(line.startsWith("#| msgid "))
|
||||
{
|
||||
strType = POEntry.StringType.PREVUNTRSTRSING;
|
||||
parserMode = strType;
|
||||
subStrIndex = 9;
|
||||
}
|
||||
if(line.startsWith("#| msgid_plural "))
|
||||
{
|
||||
strType = POEntry.StringType.PREVUNTRSTRPLUR;
|
||||
parserMode = strType;
|
||||
subStrIndex = 16;
|
||||
}
|
||||
}
|
||||
String str = new String();
|
||||
str = line.substring(subStrIndex);
|
||||
entry.addLine(strType, str);
|
||||
}
|
||||
else if(line.startsWith("msg"))
|
||||
{
|
||||
parserMode = null;
|
||||
if(line.startsWith("msgctxt "))
|
||||
{
|
||||
strType = POEntry.StringType.MSGCTXT;
|
||||
parserMode = strType;
|
||||
subStrIndex = 8;
|
||||
}
|
||||
if(line.startsWith("msgid "))
|
||||
{
|
||||
strType = POEntry.StringType.MSGID;
|
||||
parserMode = strType;
|
||||
subStrIndex = 6;
|
||||
}
|
||||
if(line.startsWith("msgstr "))
|
||||
{
|
||||
strType = POEntry.StringType.MSGSTR;
|
||||
parserMode = strType;
|
||||
subStrIndex = 7;
|
||||
}
|
||||
String str = new String();
|
||||
// TODO: is unquoting nessessary?
|
||||
str = unQuote(line.substring(subStrIndex));
|
||||
entry.addLine(strType, str);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(parserMode != null)
|
||||
{
|
||||
entry.addLine(parserMode, unQuote(line));
|
||||
}
|
||||
}
|
||||
}
|
||||
tempentries[i] = entry;
|
||||
}
|
||||
|
||||
return tempentries;
|
||||
}
|
||||
}
|
||||
24
src/net/launchpad/tobal/poparser/ParserTest.java
Normal file
24
src/net/launchpad/tobal/poparser/ParserTest.java
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @author Balázs Tóth (tobal17@gmail.com)
|
||||
*
|
||||
* Modified by Kevin POCHAT for ATCS
|
||||
*/
|
||||
package net.launchpad.tobal.poparser;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ParserTest
|
||||
{
|
||||
public static void main(String args[])
|
||||
{
|
||||
File file = new File("C:\\file.po");
|
||||
POParser parser = new POParser();
|
||||
POFile po = parser.parseFile(file);
|
||||
po.printHeader();
|
||||
po.printFile();
|
||||
// is the 3th entry fuzzy?
|
||||
boolean fuzzy = po.checkFlag("fuzzy", 3);
|
||||
// give me the msgid of the 4th entry
|
||||
String[] str = po.getStringsFromEntryByType(4, POEntry.StringType.MSGID);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user