| Author | DaveJarvis <email> |
|---|---|
| Date | 2021-03-22 20:55:51 GMT-0700 |
| Commit | 0a40a754cec46334c37e0e964ce4d77fbf201b4c |
| Parent | cd8d7bc |
| import java.io.File; | ||
| -import java.nio.file.Paths; | ||
| -import java.util.stream.Stream; | ||
| -import static java.io.File.pathSeparator; | ||
| -import static java.lang.System.getenv; | ||
| -import static java.util.regex.Pattern.quote; | ||
| +import static com.keenwrite.util.ResourceWalker.canExecute; | ||
| /** | ||
| return null; | ||
| - } | ||
| - | ||
| - @SuppressWarnings( "SameParameterValue" ) | ||
| - private boolean canExecute( final String exe ) { | ||
| - final var paths = getenv( "PATH" ).split( quote( pathSeparator ) ); | ||
| - return Stream.of( paths ).map( Paths::get ).anyMatch( | ||
| - path -> { | ||
| - final var p = path.resolve( exe ); | ||
| - final var extensions = new String[]{"", ".com", ".exe", ".bat", ".cmd"}; | ||
| - var found = false; | ||
| - | ||
| - for( final var extension : extensions ) { | ||
| - final var f = new File( p.toString() + extension ); | ||
| - | ||
| - if( f.exists() && f.canExecute() ) { | ||
| - found = true; | ||
| - break; | ||
| - } | ||
| - } | ||
| - | ||
| - return found; | ||
| - } | ||
| - ); | ||
| } | ||
| } | ||
| import com.keenwrite.AbstractFileFactory; | ||
| -import com.keenwrite.preferences.Workspace; | ||
| import com.keenwrite.preview.HtmlPreview; | ||
| import com.keenwrite.processors.markdown.MarkdownProcessor; | ||
| ? createHtmlPreviewProcessor() | ||
| : context.isExportFormat( XHTML_TEX ) | ||
| - ? createXhtmlProcessor( context.getWorkspace() ) | ||
| + ? createXhtmlProcessor( context ) | ||
| : context.isExportFormat( APPLICATION_PDF ) | ||
| ? createPdfProcessor( context ) | ||
| * @return An instance of {@link Processor} that completes an HTML document. | ||
| */ | ||
| - private Processor<String> createXhtmlProcessor( final Workspace workspace ) { | ||
| - return createXhtmlProcessor( IDENTITY, workspace ); | ||
| + private Processor<String> createXhtmlProcessor( | ||
| + final ProcessorContext context ) { | ||
| + return createXhtmlProcessor( IDENTITY, context ); | ||
| } | ||
| private Processor<String> createXhtmlProcessor( | ||
| - final Processor<String> successor, final Workspace workspace ) { | ||
| - return new XhtmlProcessor( successor, workspace ); | ||
| + final Processor<String> successor, final ProcessorContext context ) { | ||
| + return new XhtmlProcessor( successor, context ); | ||
| } | ||
| private Processor<String> createPdfProcessor( | ||
| final ProcessorContext context ) { | ||
| final var pdfp = new PdfProcessor( context.getExportPath() ); | ||
| - return createXhtmlProcessor( pdfp, context.getWorkspace() ); | ||
| + return createXhtmlProcessor( pdfp, context ); | ||
| } | ||
| private final static Pattern BLANK = | ||
| compile( "\\p{Blank}", UNICODE_CHARACTER_CLASS ); | ||
| - private final Workspace mWorkspace; | ||
| + | ||
| + private final ProcessorContext mContext; | ||
| public XhtmlProcessor( | ||
| - final Processor<String> successor, final Workspace workspace ) { | ||
| + final Processor<String> successor, final ProcessorContext context ) { | ||
| super( successor ); | ||
| - mWorkspace = workspace; | ||
| + | ||
| + assert context != null; | ||
| + | ||
| + mContext = context; | ||
| } | ||
| else { | ||
| final var extensions = " " + getImageOrder().trim(); | ||
| - final var imagePath = getImagePath(); | ||
| + var imagePath = getImagePath(); | ||
| + var found = false; | ||
| // By including " " in the extensions, the first element returned | ||
| if( imageFile.toFile().exists() ) { | ||
| + found = true; | ||
| break; | ||
| } | ||
| } | ||
| - // If a file name and extension combo could not be found, tell the user. | ||
| - if( imageFile == null ) { | ||
| + if( !found ) { | ||
| + imagePath = getDocumentDir().toString(); | ||
| imageFile = Path.of( imagePath, src ); | ||
| - throw new FileNotFoundException( imageFile.toString() ); | ||
| + | ||
| + if( !imageFile.toFile().exists() ) { | ||
| + throw new FileNotFoundException( imageFile.toString() ); | ||
| + } | ||
| } | ||
| } | ||
| return imageFile; | ||
| } | ||
| private String getImagePath() { | ||
| - return mWorkspace.fileProperty( KEY_IMAGES_DIR ).get().toString(); | ||
| + return getWorkspace().fileProperty( KEY_IMAGES_DIR ).get().toString(); | ||
| } | ||
| private String getImageOrder() { | ||
| - return mWorkspace.stringProperty( KEY_IMAGES_ORDER ).get(); | ||
| + return getWorkspace().stringProperty( KEY_IMAGES_ORDER ).get(); | ||
| + } | ||
| + | ||
| + /** | ||
| + * Returns the absolute path to the document being edited, which can be used | ||
| + * to find files included using relative paths. | ||
| + * | ||
| + * @return The directory containing the edited file. | ||
| + */ | ||
| + private Path getDocumentDir() { | ||
| + return mContext.getBaseDir(); | ||
| + } | ||
| + | ||
| + private Workspace getWorkspace() { | ||
| + return mContext.getWorkspace(); | ||
| } | ||
| import java.nio.file.Paths; | ||
| import java.util.function.Consumer; | ||
| +import java.util.stream.Stream; | ||
| import static com.keenwrite.util.ProtocolScheme.JAR; | ||
| import static com.keenwrite.util.ProtocolScheme.valueFrom; | ||
| +import static java.io.File.pathSeparator; | ||
| +import static java.lang.System.getenv; | ||
| import static java.nio.file.FileSystems.getDefault; | ||
| import static java.nio.file.FileSystems.newFileSystem; | ||
| +import static java.nio.file.Files.isExecutable; | ||
| import static java.util.Collections.emptyMap; | ||
| +import static java.util.regex.Pattern.quote; | ||
| /** | ||
| * Responsible for finding file resources. | ||
| */ | ||
| public final class ResourceWalker { | ||
| + /** | ||
| + * For finding executable programs. | ||
| + */ | ||
| + private static final String[] EXTENSIONS = new String[] | ||
| + {"", ".com", ".exe", ".bat", ".cmd"}; | ||
| + | ||
| /** | ||
| * Globbing pattern to match font names. | ||
| } | ||
| } | ||
| + } | ||
| + | ||
| + /** | ||
| + * Given the name of an executable (without an extension) file, this will | ||
| + * attempt to determine whether the executable is found in the PATH | ||
| + * environment variable. | ||
| + * | ||
| + * @param exe The executable file name to find. | ||
| + * @return {@code true} when the given file name references an executable | ||
| + * file located in the PATH environment variable. | ||
| + */ | ||
| + public static boolean canExecute( final String exe ) { | ||
| + final var paths = getenv( "PATH" ).split( quote( pathSeparator ) ); | ||
| + return Stream.of( paths ).map( Paths::get ).anyMatch( | ||
| + path -> { | ||
| + final var p = path.resolve( exe ); | ||
| + var found = false; | ||
| + | ||
| + for( final var extension : EXTENSIONS ) { | ||
| + if( isExecutable( Path.of( p.toString() + extension ) ) ) { | ||
| + found = true; | ||
| + break; | ||
| + } | ||
| + } | ||
| + | ||
| + return found; | ||
| + } | ||
| + ); | ||
| } | ||
| } | ||
| documentPath, | ||
| Caret.builder().build(), | ||
| + null, | ||
| NONE, | ||
| sWorkspace |
| \startxmlsetups xml:tex | ||
| - %\mathematics{\xmlflushcontext{#1}} | ||
| - \xmlflushcontext{#1} | ||
| + \mathematics{\xmlflushcontext{#1}} | ||
| \stopxmlsetups | ||
| \setuphead[section,subsection][ | ||
| page=no, | ||
| - number=no, | ||
| + number=yes, | ||
| before={\blank[big]}, | ||
| after={\blank[line]} |
| Delta | 82 lines added, 47 lines removed, 35-line increase |
|---|