Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git

Merge pull request #148 from DaveJarvis/1_use_processor_context_exclusively Use processor context exclusively

AuthorDave Jarvis <email>
Date2022-01-04 23:40:15 GMT-0800
Commit0f479020921dc4fa9db8084b6d0f15a08a919224
Parent52a7bb6
Delta85 lines added, 51 lines removed, 34-line increase
src/test/java/com/keenwrite/processors/markdown/ImageLinkExtensionTest.java
import com.keenwrite.AwaitFxExtension;
import com.keenwrite.editors.common.Caret;
-import com.keenwrite.preferences.Workspace;
import com.keenwrite.processors.Processor;
import com.keenwrite.processors.ProcessorContext;
@SuppressWarnings( "SameParameterValue" )
public class ImageLinkExtensionTest {
- private static final Workspace sWorkspace = new Workspace(
- getResourceFile( "workspace.xml" ) );
-
private static final Map<String, String> IMAGES = new HashMap<>();
.with( ProcessorContext.Mutator::setInputPath, inputPath )
.with( ProcessorContext.Mutator::setExportFormat, XHTML_TEX )
- .with( ProcessorContext.Mutator::setWorkspace, sWorkspace )
.with( ProcessorContext.Mutator::setCaret, () -> Caret.builder().build() )
.build();
private static String getResource( final String path ) {
return toUri( path ).toString();
- }
-
- private static File getResourceFile( final String path ) {
- return new File( getResource( path ) );
}
}
src/main/java/com/keenwrite/ui/listeners/CaretStatus.java
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
+package com.keenwrite.ui.listeners;
+
+import com.keenwrite.editors.common.Caret;
+import com.keenwrite.events.CaretMovedEvent;
+import com.keenwrite.events.WordCountEvent;
+import javafx.scene.control.Label;
+import javafx.scene.layout.VBox;
+import org.greenrobot.eventbus.Subscribe;
+
+import static com.keenwrite.events.Bus.register;
+import static javafx.application.Platform.runLater;
+import static javafx.geometry.Pos.BASELINE_CENTER;
+
+/**
+ * Responsible for updating the UI whenever the caret changes position.
+ * Only one instance of {@link CaretStatus} is allowed, which prevents
+ * duplicate adds to the observable property.
+ */
+public class CaretStatus extends VBox {
+
+ /**
+ * Use an instance of {@link Label} for its built-in CSS style class.
+ */
+ private final Label mStatusText = new Label();
+
+ /**
+ * Contains caret position information within an editor.
+ */
+ private volatile Caret mCaret = Caret.builder().build();
+
+ /**
+ * Approximate number of words in the document.
+ */
+ private volatile int mCount;
+
+ public CaretStatus() {
+ setAlignment( BASELINE_CENTER );
+ getChildren().add( mStatusText );
+ register( this );
+ }
+
+ @Subscribe
+ public void handle( final WordCountEvent event ) {
+ mCount = event.getCount();
+ updateStatus( mCaret, mCount );
+ }
+
+ @Subscribe
+ public void handle( final CaretMovedEvent event ) {
+ mCaret = event.getCaret();
+ updateStatus( mCaret, mCount );
+ }
+
+ private void updateStatus( final Caret caret, final int count ) {
+ assert caret != null;
+ runLater( () -> mStatusText.setText( caret + " | " + count ) );
+ }
+}
src/main/java/com/keenwrite/processors/VariableProcessor.java
super( successor );
- mSigilOperator = createKeyOperator( context );
mContext = context;
+ mSigilOperator = createKeyOperator( context );
}
protected UnaryOperator<String> createKeyOperator(
final ProcessorContext context ) {
- return context.createSigilOperator();
+ return context.createKeyOperator();
}
src/main/java/com/keenwrite/processors/XhtmlProcessor.java
import com.keenwrite.dom.DocumentParser;
-import com.keenwrite.preferences.Workspace;
import com.keenwrite.ui.heuristics.WordCounter;
import com.whitemagicsoftware.keenquotes.Contractions;
import com.whitemagicsoftware.keenquotes.Converter;
-import javafx.beans.property.ListProperty;
import org.w3c.dom.Document;
import java.io.FileNotFoundException;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Pattern;
import static com.keenwrite.Bootstrap.APP_TITLE_LOWERCASE;
import static com.keenwrite.dom.DocumentParser.createMeta;
import static com.keenwrite.dom.DocumentParser.visit;
import static com.keenwrite.events.StatusEvent.clue;
import static com.keenwrite.io.HttpFacade.httpGet;
-import static com.keenwrite.preferences.AppKeys.*;
import static com.keenwrite.util.ProtocolScheme.getProtocol;
import static com.whitemagicsoftware.keenquotes.Converter.CHARS;
import static com.whitemagicsoftware.keenquotes.ParserFactory.ParserType.PARSER_XML;
import static java.lang.String.format;
import static java.lang.String.valueOf;
import static java.nio.file.Files.copy;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-import static java.util.regex.Pattern.UNICODE_CHARACTER_CLASS;
-import static java.util.regex.Pattern.compile;
/**
* Responsible for making an XHTML document complete by wrapping it with html
* and body elements. This doesn't have to be super-efficient because it's
* not run in real-time.
*/
public final class XhtmlProcessor extends ExecutorProcessor<String> {
- private final static Pattern BLANK =
- compile( "\\p{Blank}", UNICODE_CHARACTER_CLASS );
-
private final static Converter sTypographer = new Converter(
lex -> clue( lex.toString() ), contractions(), CHARS, PARSER_XML );
final var document = DocumentParser.toString( doc );
+ final var curl = mContext.getCurlQuotes();
- return curl() ? sTypographer.apply( document ) : document;
+ return curl ? sTypographer.apply( document ) : document;
} catch( final Exception ex ) {
clue( ex );
*/
private Map<String, String> createMetaDataMap( final Document doc ) {
- final Map<String, String> result = new LinkedHashMap<>();
- final var metadata = getMetaData();
+ final var result = new LinkedHashMap<String, String>();
+ final var metadata = getMetadata();
final var map = mContext.getInterpolatedDefinitions();
- metadata.forEach( entry -> result.put(
- entry.getKey(), map.interpolate( entry.getValue() ) )
+ metadata.forEach(
+ ( key, value ) -> result.put( key, map.interpolate( value ) )
);
result.put( "count", wordCount( doc ) );
* @return The document metadata.
*/
- private ListProperty<Entry<String, String>> getMetaData() {
- return getWorkspace().listsProperty( KEY_DOC_META );
+ private Map<String, String> getMetadata() {
+ return mContext.getMetadata();
}
}
else {
- final var extensions = " " + getImageOrder().trim();
+ final var extensions = getImageOrder();
var imagePath = getImagePath();
var found = false;
- // By including " " in the extensions, the first element returned
- // will be the empty string. Thus the first extension to try is the
- // file's default extension. Subsequent iterations will try to find
- // a file that has a name matching one of the preferred extensions.
- for( final var extension : BLANK.split( extensions ) ) {
+ for( final var extension : extensions ) {
final var filename = format(
"%s%s%s", src, extension.isBlank() ? "" : ".", extension );
private String getImagePath() {
- return getWorkspace().getFile( KEY_IMAGES_DIR ).toString();
+ return mContext.getImageDir().toString();
}
- private String getImageOrder() {
- return getWorkspace().getString( KEY_IMAGES_ORDER );
+ /**
+ * By including an "empty" extension, the first element returned
+ * will be the empty string. Thus, the first extension to try is the
+ * file's default extension. Subsequent iterations will try to find
+ * a file that has a name matching one of the preferred extensions.
+ *
+ * @return A list of extensions, including an empty string at the start.
+ */
+ private Iterable<String> getImageOrder() {
+ return mContext.getImageOrder();
}
}
- private Workspace getWorkspace() {
- return mContext.getWorkspace();
+ private Locale getLocale() {
+ return mContext.getLocale();
}
-
- private Locale locale() {return getWorkspace().getLocale();}
private String wordCount( final Document doc ) {
final var sb = new StringBuilder( 65536 * 10 );
visit(
doc,
"//*[normalize-space( text() ) != '']",
node -> sb.append( node.getTextContent() )
);
-
- return valueOf( WordCounter.create( locale() ).count( sb.toString() ) );
- }
- /**
- * Answers whether straight quotation marks should be curled.
- *
- * @return {@code false} to prevent curling straight quotes.
- */
- private boolean curl() {
- return getWorkspace().getBoolean( KEY_TYPESET_TYPOGRAPHY_QUOTES );
+ return valueOf( WordCounter.create( getLocale() ).count( sb.toString() ) );
}