/*_x000D_
 * To change this license header, choose License Headers in Project Properties._x000D_
 * To change this template file, choose Tools | Templates_x000D_
 * and open the template in the editor._x000D_
 */_x000D_
package conversion.pdf.util;_x000D_
_x000D_
import java.io.ByteArrayInputStream;_x000D_
import java.io.ByteArrayOutputStream;_x000D_
import java.io.IOException;_x000D_
import java.io.ObjectInputStream;_x000D_
import java.io.ObjectOutputStream;_x000D_
import java.util.ArrayList;_x000D_
import objects.PPTObject;_x000D_
import org.apache.pdfbox.cos.COSStream;_x000D_
import org.apache.pdfbox.pdmodel.PDPage;_x000D_
import org.apache.pdfbox.pdmodel.PDResources;_x000D_
import org.apache.pdfbox.util.PDFTextStripper;_x000D_
import org.apache.pdfbox.util.TextPosition;_x000D_
_x000D_
/**_x000D_
 * TextExtractor overrides certain methodes from PDFTextStripper in order to put_x000D_
 * information in the arrayList of PPTObjects objecten._x000D_
 *_x000D_
 * @author Gertjan_x000D_
 */_x000D_
public class PDFTextExtractor extends PDFTextStripper {_x000D_
    _x000D_
    private TekenPlus teken = new TekenPlus();_x000D_
    private ArrayList<TekenPlus> woord = new ArrayList<>();_x000D_
    private boolean isNewWord = true;_x000D_
    private ArrayList<PPTObject> objecten = new ArrayList<>();_x000D_
    private Info2Object Inf2Obj = new Info2Object();_x000D_
    _x000D_
    public TekenPlus getTekenPlus() {_x000D_
        return this.teken;_x000D_
    }_x000D_
    /*get geeft niet alleen de objecten terug maar maakt de lijst ook weer leeg, dit is zodat je telkens je ze ophaalt_x000D_
     je een hele pagina ophaalt... */_x000D_
    _x000D_
    public ArrayList<PPTObject> getObjecten() {_x000D_
        try {_x000D_
            return objecten;_x000D_
        } finally {_x000D_
            objecten = new ArrayList<>();_x000D_
        }_x000D_
        _x000D_
    }_x000D_
    _x000D_
    @Override_x000D_
    public void processStream(PDPage aPage, PDResources resources, COSStream cosStream) throws IOException {_x000D_
        super.processStream(aPage, resources, cosStream); //To change body of generated methods, choose Tools | Templates._x000D_
        //en dan een persoonlijke naverwerking:_x000D_
        objecten.add(Inf2Obj.convert(woord));_x000D_
        woord = new ArrayList<>();_x000D_
    }_x000D_
    _x000D_
    public PDFTextExtractor() throws IOException {_x000D_
        super.setSortByPosition(true);_x000D_
        _x000D_
    }_x000D_
    _x000D_
    @Override_x000D_
    protected void processTextPosition(TextPosition text) {_x000D_
        /*deze methode haalt letters met info uit de text... hier gaan we de tekst opvangen _x000D_
         en opslaan in woorden, de woorden hebben een fontsize en een schaal... aan de hand van de _x000D_
         coordinaten xdir en ydir wordt de lijn en inspringing bepaald... */_x000D_
_x000D_
        /*Het idee is om tekstdelen terug te geven uiteindelijk want dat heb je nodig_x000D_
         Daarom is er de klasse tekstpartMaker die een enorme string van char's met hun info binnen krijgt_x000D_
         -> char's met info = nieuwe klasse!! _x000D_
         */_x000D_
        teken.setTeken(text.getCharacter());_x000D_
        teken.setFontsize(text.getFontSize());_x000D_
        teken.setHeigt(text.getHeightDir());_x000D_
        teken.setPosX(text.getXDirAdj());_x000D_
        teken.setPosY(text.getYDirAdj());_x000D_
        teken.setSpace(text.getWidthOfSpace());_x000D_
        teken.setXscale(text.getXScale());_x000D_
_x000D_
        //System.out.println(text.getFont().getFontDescriptor());_x000D_
        if (text.getFont().getBaseFont().toLowerCase().contains("bold")) {_x000D_
            teken.setBold(true);_x000D_
            //System.out.println("made bold!");_x000D_
        } else {_x000D_
            teken.setBold(false);_x000D_
        }_x000D_
        if (text.getFont().getBaseFont().toLowerCase().contains("italic")) {_x000D_
            teken.setItalic(true);_x000D_
            //System.out.println("made italic!");_x000D_
        } else {_x000D_
            teken.setItalic(false);_x000D_
        }_x000D_
        /*enum bepalen -> kijken watvoor letter het is gebeurt hier al!!!*/_x000D_
        if (text.getCharacter().matches("[A-Za-z]")) {_x000D_
            //System.out.println("letter gevonden!!!" + text.getCharacter());_x000D_
            teken.setType(TekenPlus.type.LETTER);_x000D_
        } else if (text.getCharacter().matches("[0-9]")) {_x000D_
            //System.out.println("---cijfer gevonden!!!" + text.getCharacter());_x000D_
            teken.setType(TekenPlus.type.CIJFER);_x000D_
        } else if (text.getCharacter().matches("[--?()., ]")) { //OPM laat die - vanvoor staan anders klopt regex niet!!!_x000D_
            //System.out.println("+++niet splitsend symbool" + text.getCharacter());_x000D_
            teken.setType(TekenPlus.type.NONSPLITTING);_x000D_
        } /*BELANGRIJKE OPM: een spatie is geen split teken... een spatie houdt meestal dingen gewoon samen...*/ else {_x000D_
            //System.out.println(">>>onbekend split teken gevonden" + text.getCharacter());_x000D_
            teken.setType(TekenPlus.type.SPLITTING);_x000D_
        }_x000D_
_x000D_
        //teken.schrijfPlus();_x000D_
_x000D_
        /*_x000D_
         System.out.println("Methode die info over tekst eruit haalt");_x000D_
         System.out.println("String[" + text.getXDirAdj() + ","_x000D_
         + text.getYDirAdj() + " fs=" + text.getFontSize() + " xscale="_x000D_
         + text.getXScale() + " height=" + text.getHeightDir() + " space="_x000D_
         + text.getWidthOfSpace() + " width="_x000D_
         + text.getWidthDirAdj() + "]" + text.getCharacter());_x000D_
         */_x000D_
        //een korte commercial break om ons teken nu ook hogerop te krijgen!_x000D_
        verwerkTeken(teken);_x000D_
        _x000D_
    }_x000D_
    _x000D_
    private void verwerkTeken(TekenPlus teken) {_x000D_
        /*Het idee is als volgt, indien het teken de zelfde eigenschappen heeft als het vorige dan wordt het_x000D_
         erbij gepusht in een tijdelijk tekstdeel, is het anders dan wordt het in een nieuw tekstdeel gezet*/_x000D_
        /*_x000D_
         tekstdeel moet vervolgens nog tekst worden...  OPM tekst wordt niet gesplitst op basis van spaties!!_x000D_
         */_x000D_
        //System.out.println("te verwerken teken: " + teken.getTeken());_x000D_
        if (isNewWord) {_x000D_
            //  System.out.println("gekozen voor : new word optie");_x000D_
            woord = new ArrayList<>();_x000D_
            isNewWord = false;_x000D_
        }_x000D_
        //anders gewoon verder schrijven aan je arraylist..._x000D_
        /*Hier wordt onderzocht welke soort delimiter je hebt, is het een ander teken dan gewone tekst dan splits je daarop ook...*/_x000D_
        if (teken.getType() == TekenPlus.type.SPLITTING) {_x000D_
            //System.out.println("gekozen voor: splitting optie");_x000D_
            // System.out.println("SPLITTING teken");_x000D_
            objecten.add(Inf2Obj.convert(woord));_x000D_
            woord = new ArrayList<>();_x000D_
        }_x000D_
        _x000D_
        if (!woord.isEmpty() && !tekenControle(teken)) { //doet hetzelfde als kijken of het splitting is! _x000D_
            //controle op leeg zijn anders nullpointers!!_x000D_
            //System.out.println("INFO splitting");_x000D_
            objecten.add(Inf2Obj.convert(woord));_x000D_
            woord = new ArrayList<>();_x000D_
        }_x000D_
_x000D_
        //even een kopie nemen, hij doet iets vreemd anders..._x000D_
        try {_x000D_
            ByteArrayOutputStream baos = new ByteArrayOutputStream();_x000D_
            ObjectOutputStream oos = new ObjectOutputStream(baos);_x000D_
            oos.writeObject(teken);_x000D_
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());_x000D_
            ObjectInputStream ois = new ObjectInputStream(bais);_x000D_
            TekenPlus kopie = (TekenPlus) ois.readObject();_x000D_
            _x000D_
            woord.add(kopie);_x000D_
        } catch (Exception e) {_x000D_
            System.out.println("fout bij kopiëren..." + e.getMessage());_x000D_
        }_x000D_
        _x000D_
    }_x000D_
    _x000D_
/**_x000D_
 * Checks if a symbol belongs to the same word or not...._x000D_
 *   returns false upon a splitting event (like a defferent font etc.)_x000D_
 * @param teken_x000D_
 * @return _x000D_
 */_x000D_
    private boolean tekenControle(TekenPlus teken) {_x000D_
        _x000D_
        TekenPlus vorigeLetter = woord.get(woord.size() - 1); //dit haalt de laatste letter eraf..._x000D_
        //System.out.print("De vorige letter was: ");_x000D_
        //vorigeLetter.schrijfPlus();_x000D_
        //opm = xpos is dat hori of verti? (programma assen of menselijker... :p_x000D_
        if (vorigeLetter.getPosY() != teken.getPosY()) {_x000D_
            //System.out.println("split op PosY!");_x000D_
            return false;_x000D_
            _x000D_
        }_x000D_
        if (vorigeLetter.getFontsize() != teken.getFontsize()) {_x000D_
            //System.out.println("split op FontSize");_x000D_
            return false;_x000D_
        }_x000D_
        if (vorigeLetter.isBold() != teken.isBold()) {_x000D_
            return false;_x000D_
        }_x000D_
        if (vorigeLetter.isItalic() != teken.isItalic()) {_x000D_
            return false;_x000D_
        }_x000D_
        _x000D_
        if ((teken.getPosX() - vorigeLetter.getPosX()) > 100) {_x000D_
            //100 is arbitrair gekozen, merk op dat deze test enkel gedaan wordt voor woorden met zelfde fontsize op zelfde lijn!_x000D_
            //System.out.println("verschil tekens: " + (teken.getPosX() - vorigeLetter.getPosX()));_x000D_
            return false;_x000D_
        }_x000D_
        _x000D_
        return true;_x000D_
    }_x000D_
    _x000D_
}_x000D_

/*Hier wordt onderzocht welke soort delimiter je hebt, is het een ander teken dan gewone tekst dan splits je daarop ook...*/
/*_x000D_
 * To change this license header, choose License Headers in Project Properties._x000D_
 * To change this template file, choose Tools | Templates_x000D_
 * and open the template in the editor._x000D_
 */_x000D_
package conversion.pdf.util;_x000D_
_x000D_
import java.io.ByteArrayInputStream;_x000D_
import java.io.ByteArrayOutputStream;_x000D_
import java.io.IOException;_x000D_
import java.io.ObjectInputStream;_x000D_
import java.io.ObjectOutputStream;_x000D_
import java.util.ArrayList;_x000D_
import objects.PPTObject;_x000D_
import org.apache.pdfbox.cos.COSStream;_x000D_
import org.apache.pdfbox.pdmodel.PDPage;_x000D_
import org.apache.pdfbox.pdmodel.PDResources;_x000D_
import org.apache.pdfbox.util.PDFTextStripper;_x000D_
import org.apache.pdfbox.util.TextPosition;_x000D_
_x000D_
/**_x000D_
 * TextExtractor overrides certain methodes from PDFTextStripper in order to put_x000D_
 * information in the arrayList of PPTObjects objecten._x000D_
 *_x000D_
 * @author Gertjan_x000D_
 */_x000D_
public class PDFTextExtractor extends PDFTextStripper {_x000D_
    _x000D_
    private TekenPlus teken = new TekenPlus();_x000D_
    private ArrayList<TekenPlus> woord = new ArrayList<>();_x000D_
    private boolean isNewWord = true;_x000D_
    private ArrayList<PPTObject> objecten = new ArrayList<>();_x000D_
    private Info2Object Inf2Obj = new Info2Object();_x000D_
    _x000D_
    public TekenPlus getTekenPlus() {_x000D_
        return this.teken;_x000D_
    }_x000D_
    /*get geeft niet alleen de objecten terug maar maakt de lijst ook weer leeg, dit is zodat je telkens je ze ophaalt_x000D_
     je een hele pagina ophaalt... */_x000D_
    _x000D_
    public ArrayList<PPTObject> getObjecten() {_x000D_
        try {_x000D_
            return objecten;_x000D_
        } finally {_x000D_
            objecten = new ArrayList<>();_x000D_
        }_x000D_
        _x000D_
    }_x000D_
    _x000D_
    @Override_x000D_
    public void processStream(PDPage aPage, PDResources resources, COSStream cosStream) throws IOException {_x000D_
        super.processStream(aPage, resources, cosStream); //To change body of generated methods, choose Tools | Templates._x000D_
        //en dan een persoonlijke naverwerking:_x000D_
        objecten.add(Inf2Obj.convert(woord));_x000D_
        woord = new ArrayList<>();_x000D_
    }_x000D_
    _x000D_
    public PDFTextExtractor() throws IOException {_x000D_
        super.setSortByPosition(true);_x000D_
        _x000D_
    }_x000D_
    _x000D_
    @Override_x000D_
    protected void processTextPosition(TextPosition text) {_x000D_
        /*deze methode haalt letters met info uit de text... hier gaan we de tekst opvangen _x000D_
         en opslaan in woorden, de woorden hebben een fontsize en een schaal... aan de hand van de _x000D_
         coordinaten xdir en ydir wordt de lijn en inspringing bepaald... */_x000D_
_x000D_
        /*Het idee is om tekstdelen terug te geven uiteindelijk want dat heb je nodig_x000D_
         Daarom is er de klasse tekstpartMaker die een enorme string van char's met hun info binnen krijgt_x000D_
         -> char's met info = nieuwe klasse!! _x000D_
         */_x000D_
        teken.setTeken(text.getCharacter());_x000D_
        teken.setFontsize(text.getFontSize());_x000D_
        teken.setHeigt(text.getHeightDir());_x000D_
        teken.setPosX(text.getXDirAdj());_x000D_
        teken.setPosY(text.getYDirAdj());_x000D_
        teken.setSpace(text.getWidthOfSpace());_x000D_
        teken.setXscale(text.getXScale());_x000D_
_x000D_
        //System.out.println(text.getFont().getFontDescriptor());_x000D_
        if (text.getFont().getBaseFont().toLowerCase().contains("bold")) {_x000D_
            teken.setBold(true);_x000D_
            //System.out.println("made bold!");_x000D_
        } else {_x000D_
            teken.setBold(false);_x000D_
        }_x000D_
        if (text.getFont().getBaseFont().toLowerCase().contains("italic")) {_x000D_
            teken.setItalic(true);_x000D_
            //System.out.println("made italic!");_x000D_
        } else {_x000D_
            teken.setItalic(false);_x000D_
        }_x000D_
        /*enum bepalen -> kijken watvoor letter het is gebeurt hier al!!!*/_x000D_
        if (text.getCharacter().matches("[A-Za-z]")) {_x000D_
            //System.out.println("letter gevonden!!!" + text.getCharacter());_x000D_
            teken.setType(TekenPlus.type.LETTER);_x000D_
        } else if (text.getCharacter().matches("[0-9]")) {_x000D_
            //System.out.println("---cijfer gevonden!!!" + text.getCharacter());_x000D_
            teken.setType(TekenPlus.type.CIJFER);_x000D_
        } else if (text.getCharacter().matches("[--?()., ]")) { //OPM laat die - vanvoor staan anders klopt regex niet!!!_x000D_
            //System.out.println("+++niet splitsend symbool" + text.getCharacter());_x000D_
            teken.setType(TekenPlus.type.NONSPLITTING);_x000D_
        } /*BELANGRIJKE OPM: een spatie is geen split teken... een spatie houdt meestal dingen gewoon samen...*/ else {_x000D_
            //System.out.println(">>>onbekend split teken gevonden" + text.getCharacter());_x000D_
            teken.setType(TekenPlus.type.SPLITTING);_x000D_
        }_x000D_
_x000D_
        //teken.schrijfPlus();_x000D_
_x000D_
        /*_x000D_
         System.out.println("Methode die info over tekst eruit haalt");_x000D_
         System.out.println("String[" + text.getXDirAdj() + ","_x000D_
         + text.getYDirAdj() + " fs=" + text.getFontSize() + " xscale="_x000D_
         + text.getXScale() + " height=" + text.getHeightDir() + " space="_x000D_
         + text.getWidthOfSpace() + " width="_x000D_
         + text.getWidthDirAdj() + "]" + text.getCharacter());_x000D_
         */_x000D_
        //een korte commercial break om ons teken nu ook hogerop te krijgen!_x000D_
        verwerkTeken(teken);_x000D_
        _x000D_
    }_x000D_
    _x000D_
    private void verwerkTeken(TekenPlus teken) {_x000D_
        /*Het idee is als volgt, indien het teken de zelfde eigenschappen heeft als het vorige dan wordt het_x000D_
         erbij gepusht in een tijdelijk tekstdeel, is het anders dan wordt het in een nieuw tekstdeel gezet*/_x000D_
        /*_x000D_
         tekstdeel moet vervolgens nog tekst worden...  OPM tekst wordt niet gesplitst op basis van spaties!!_x000D_
         */_x000D_
        //System.out.println("te verwerken teken: " + teken.getTeken());_x000D_
        if (isNewWord) {_x000D_
            //  System.out.println("gekozen voor : new word optie");_x000D_
            woord = new ArrayList<>();_x000D_
            isNewWord = false;_x000D_
        }_x000D_
        //anders gewoon verder schrijven aan je arraylist..._x000D_
        /*Hier wordt onderzocht<SUF>*/_x000D_
        if (teken.getType() == TekenPlus.type.SPLITTING) {_x000D_
            //System.out.println("gekozen voor: splitting optie");_x000D_
            // System.out.println("SPLITTING teken");_x000D_
            objecten.add(Inf2Obj.convert(woord));_x000D_
            woord = new ArrayList<>();_x000D_
        }_x000D_
        _x000D_
        if (!woord.isEmpty() && !tekenControle(teken)) { //doet hetzelfde als kijken of het splitting is! _x000D_
            //controle op leeg zijn anders nullpointers!!_x000D_
            //System.out.println("INFO splitting");_x000D_
            objecten.add(Inf2Obj.convert(woord));_x000D_
            woord = new ArrayList<>();_x000D_
        }_x000D_
_x000D_
        //even een kopie nemen, hij doet iets vreemd anders..._x000D_
        try {_x000D_
            ByteArrayOutputStream baos = new ByteArrayOutputStream();_x000D_
            ObjectOutputStream oos = new ObjectOutputStream(baos);_x000D_
            oos.writeObject(teken);_x000D_
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());_x000D_
            ObjectInputStream ois = new ObjectInputStream(bais);_x000D_
            TekenPlus kopie = (TekenPlus) ois.readObject();_x000D_
            _x000D_
            woord.add(kopie);_x000D_
        } catch (Exception e) {_x000D_
            System.out.println("fout bij kopiëren..." + e.getMessage());_x000D_
        }_x000D_
        _x000D_
    }_x000D_
    _x000D_
/**_x000D_
 * Checks if a symbol belongs to the same word or not...._x000D_
 *   returns false upon a splitting event (like a defferent font etc.)_x000D_
 * @param teken_x000D_
 * @return _x000D_
 */_x000D_
    private boolean tekenControle(TekenPlus teken) {_x000D_
        _x000D_
        TekenPlus vorigeLetter = woord.get(woord.size() - 1); //dit haalt de laatste letter eraf..._x000D_
        //System.out.print("De vorige letter was: ");_x000D_
        //vorigeLetter.schrijfPlus();_x000D_
        //opm = xpos is dat hori of verti? (programma assen of menselijker... :p_x000D_
        if (vorigeLetter.getPosY() != teken.getPosY()) {_x000D_
            //System.out.println("split op PosY!");_x000D_
            return false;_x000D_
            _x000D_
        }_x000D_
        if (vorigeLetter.getFontsize() != teken.getFontsize()) {_x000D_
            //System.out.println("split op FontSize");_x000D_
            return false;_x000D_
        }_x000D_
        if (vorigeLetter.isBold() != teken.isBold()) {_x000D_
            return false;_x000D_
        }_x000D_
        if (vorigeLetter.isItalic() != teken.isItalic()) {_x000D_
            return false;_x000D_
        }_x000D_
        _x000D_
        if ((teken.getPosX() - vorigeLetter.getPosX()) > 100) {_x000D_
            //100 is arbitrair gekozen, merk op dat deze test enkel gedaan wordt voor woorden met zelfde fontsize op zelfde lijn!_x000D_
            //System.out.println("verschil tekens: " + (teken.getPosX() - vorigeLetter.getPosX()));_x000D_
            return false;_x000D_
        }_x000D_
        _x000D_
        return true;_x000D_
    }_x000D_
    _x000D_
}_x000D_
