/* * Copyright (C) 2011 Laurent Caillette * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.novelang.batch; import java.io.File; import java.io.FileOutputStream; import java.nio.charset.Charset; import java.util.List; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.novelang.common.Problem; import org.novelang.common.Renderable; import org.novelang.common.SyntacticTree; import org.novelang.configuration.ConfigurationTools; import org.novelang.configuration.LevelExploderConfiguration; import org.novelang.configuration.ProducerConfiguration; import org.novelang.configuration.parse.ArgumentException; import org.novelang.configuration.parse.LevelExploderParameters; import org.novelang.logger.Logger; import org.novelang.logger.LoggerFactory; import org.novelang.parser.NodeKind; import org.novelang.produce.DocumentProducer; import org.novelang.rendering.GenericRenderer; import org.novelang.rendering.NovellaWriter; import org.novelang.rendering.RenderingTools; import org.novelang.rendering.RenditionMimeType; /** * Writes top levels into separate files. * * @author Laurent Caillette */ public class LevelExploder extends AbstractDocumentGenerator<LevelExploderParameters> { private static final Logger LOGGER = LoggerFactory.getLogger( LevelExploder.class ) ; @Override public void main( final LevelExploderParameters parameters ) throws Exception { final LevelExploderConfiguration configuration = ConfigurationTools.createExplodeLevelsConfiguration( parameters ) ; final File outputDirectory = configuration.getOutputDirectory(); resetTargetDirectory( outputDirectory ) ; final DocumentProducer documentProducer = new DocumentProducer( configuration.getProducerConfiguration() ) ; final List< Problem > allProblems = Lists.newArrayList() ; Iterables.addAll( allProblems, processDocumentRequest( configuration, outputDirectory, documentProducer ) ) ; if( ! allProblems.isEmpty() ) { reportProblems( outputDirectory, allProblems ) ; System.err.println( "There were problems. See " + outputDirectory + "/" + PROBLEMS_FILENAME ) ; } } private Iterable< Problem > processDocumentRequest( final LevelExploderConfiguration configuration, final File outputDirectory, final DocumentProducer documentProducer ) { try { final Renderable document = documentProducer.createRenderable( configuration.getDocumentRequest() ); for( final SyntacticTree child : document.getDocumentTree().getChildren() ) { if( child.isOneOf( NodeKind._LEVEL ) ) { processLevel( configuration.getProducerConfiguration(), child, outputDirectory ) ; } } } catch( Exception e ) { return ImmutableList.of( Problem.createProblem( e ) ) ; } return ImmutableList.of() ; } private void processLevel( final ProducerConfiguration producerConfiguration, final SyntacticTree level, final File outputDirectory ) throws Exception { final Charset charset = producerConfiguration.getRenderingConfiguration().getDefaultCharset() ; final String title = createLevelTitle( level, charset ) ; final File destinationFile = new File( outputDirectory, title + "." + RenditionMimeType.NOVELLA.getFileExtension() ) ; LOGGER.debug( "Outputting to file '", destinationFile.getAbsolutePath(), "'" ) ; final FileOutputStream fileOutputStream = new FileOutputStream( destinationFile ) ; try { new GenericRenderer( new NovellaWriter( producerConfiguration.getRenderingConfiguration(), null, charset ) ).render( new RenderingTools.RenderableTree( level, charset ), fileOutputStream, null, producerConfiguration.getContentConfiguration().getContentRoot() ) ; } finally { fileOutputStream.close() ; } } private int titleGenerator = 0 ; private String createLevelTitle( final SyntacticTree level, final Charset charset ) throws Exception { for( final SyntacticTree child : level.getChildren() ) { if( child.isOneOf( NodeKind.LEVEL_TITLE ) ) { final String title = RenderingTools.textualize( child, charset ) ; LOGGER.debug( "Found title: '", title, "'" ) ; return title.replace( ' ', '_' ) ; // TODO replace more filename-wrecking chars. } } final String generatedTitle = String.format( "_%d3", titleGenerator++ ); LOGGER.debug( "Generated title: '", generatedTitle, "'" ) ; return generatedTitle ; } public static LevelExploderParameters createParameters( final String[] arguments, final File baseDirectory ) throws ArgumentException { return new LevelExploderParameters( baseDirectory, arguments ); } public static String getSpecificCommandLineParametersDescriptor() { return " [OPTIONS] document-to-split.novella"; } }