All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.dedicon.pipeline.braille.calabash.impl.BrlReplaceDoubleFormFeedsStep Maven / Gradle / Ivy

There is a newer version: 2.0.1
Show newest version
package nl.dedicon.pipeline.braille.calabash.impl;

import com.xmlcalabash.core.XProcException;
import com.xmlcalabash.core.XProcRuntime;
import com.xmlcalabash.core.XProcStep;
import com.xmlcalabash.library.DefaultStep;
import com.xmlcalabash.runtime.XAtomicStep;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.SaxonApiException;
import org.apache.commons.lang3.StringUtils;
import org.daisy.common.xproc.calabash.XProcStepProvider;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * XProc step for replacing double form feeds in BRL files
 * 
 * @author Paul Rambags
 */
public class BrlReplaceDoubleFormFeedsStep extends DefaultStep {

    private static final Logger logger = LoggerFactory.getLogger(BrlReplaceDoubleFormFeedsStep.class);

    private static final QName _brl_uri = new QName("brl-uri");

    private BrlReplaceDoubleFormFeedsStep(XProcRuntime runtime, XAtomicStep step) {
        super(runtime, step);
    }

    @Override
    public void reset() {
    }

    @Override
    public void run() throws SaxonApiException {
        super.run();

        try {
            String brlUri = getOption(_brl_uri, "");
            if (StringUtils.isNotBlank(brlUri)) {
                
                try {

                    Path path = new File(new URI(brlUri)).toPath();
                    // The path refers to a CP850 encoded file
                    // A sequence of FF (LF)* FF is replaced by FF
                    byte[] inBytes = Files.readAllBytes(path);
                    byte[] outBytes = new byte[inBytes.length];
                    
                    int inIndex = 0;
                    int outIndex = 0;
                    while (inIndex < inBytes.length) {
                        int doubleFormFeedLength = findDoubleFormFeed(inBytes, inIndex);
                        if (doubleFormFeedLength > 0) {
                            outBytes[outIndex] = 0xC; // form feed
                            inIndex += doubleFormFeedLength;
                            outIndex ++;
                        } else {
                            outBytes[outIndex] = inBytes[inIndex];
                            inIndex ++;
                            outIndex ++;
                        }
                    }
                    
                    Files.write(path, Arrays.copyOfRange(outBytes, 0, outIndex));

                } catch (URISyntaxException|IOException e) {
                    logger.error(String.format("Failed to replace double form feeds in file %s due to %s", brlUri, e.getMessage()));
                    throw e;
                }
            }
        } catch (Exception e) {
            logger.error("dedicon:brl-replace-double-form-feeds failed", e);
            throw new XProcException(step.getNode(), e);
        }
    }

    // finds a C(DA)*C sequence and returns it's length
    private int findDoubleFormFeed(byte[] bytes, int index) {
        int length = 0;
        if (index + length < bytes.length && bytes[index + length] == 0xC) {
            length ++;
            while (index + length < bytes.length + 1 && bytes[index + length] == 0xD && bytes[index + length + 1] == 0xA) {
                length += 2;
            }
            if (index + length < bytes.length && bytes[index + length] == 0xC) {
                length ++;
                return length;
            }
        }
        return -1;
    }
    
    @Component(
            name = "dedicon:brl-replace-double-form-feeds",
            service = {XProcStepProvider.class},
            property = {"type:String={http://www.dedicon.nl}brl-replace-double-form-feeds"}
    )
    public static class Provider implements XProcStepProvider {

        @Override
        public XProcStep newStep(XProcRuntime runtime, XAtomicStep step) {
            return new BrlReplaceDoubleFormFeedsStep(runtime, step);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy