Dave Jarvis' Repositories

M build.gradle
3030
  compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
3131
  compile 'org.apache.commons:commons-configuration2:2.1'
32
  compile files('libs/renjin-script-engine-0.8.2320-jar-with-dependencies.jar')
32
  compile files('libs/renjin-script-engine-0.8.2324-jar-with-dependencies.jar')
3333
}
3434
35
version = '1.2.5'
35
version = '1.2.6'
3636
applicationName = 'scrivenvar'
3737
mainClassName = 'com.scrivenvar.Main'
D libs/renjin-script-engine-0.8.2320-jar-with-dependencies.jar
Binary file
A libs/renjin-script-engine-0.8.2324-jar-with-dependencies.jar
Binary file
M src/main/java/com/scrivenvar/FileEditorTabPane.java
519519
    // This will allow dynamic filters to be added and removed just by
520520
    // updating the properties file.
521
    list.add( createExtensionFilter( MARKDOWN ) );
521
    list.add( createExtensionFilter( SOURCE ) );
522522
    list.add( createExtensionFilter( DEFINITION ) );
523523
    list.add( createExtensionFilter( XML ) );
M src/main/java/com/scrivenvar/FileType.java
4040
  RMARKDOWN( "rmarkdown" ),
4141
  RXML( "rxml" ),
42
  MARKDOWN( "markdown" ),
42
  SOURCE( "source" ),
4343
  DEFINITION( "definition" ),
4444
  XML( "xml" ),
M src/main/java/com/scrivenvar/definition/DefinitionPane.java
3636
import java.util.List;
3737
import javafx.collections.ObservableList;
38
import javafx.event.EventHandler;
3839
import javafx.scene.Node;
3940
import javafx.scene.control.MultipleSelectionModel;
4041
import javafx.scene.control.SelectionMode;
4142
import javafx.scene.control.TreeItem;
4243
import javafx.scene.control.TreeView;
44
import javafx.scene.input.MouseButton;
45
import javafx.scene.input.MouseEvent;
4346
4447
/**
...
6568
    setTreeView( root );
6669
    initTreeView();
70
  }
71
72
  /**
73
   * Allows observers to receive double-click events on the tree view.
74
   *
75
   * @param handler The handler that
76
   */
77
  public void addBranchSelectedListener(
78
    final EventHandler<? super MouseEvent> handler ) {
79
80
    getTreeView().addEventHandler( MouseEvent.ANY, event -> {
81
      if( event.getButton().equals( MouseButton.PRIMARY ) && event.getClickCount() == 2 ) {
82
        if( event.getEventType().equals( MouseEvent.MOUSE_CLICKED ) ) {
83
          handler.handle( event );
84
        }
85
86
        event.consume();
87
      }
88
    } );
6789
  }
6890
M src/main/java/com/scrivenvar/editors/VariableNameInjector.java
4747
import javafx.scene.control.IndexRange;
4848
import javafx.scene.control.TreeItem;
49
import javafx.scene.control.TreeView;
4950
import javafx.scene.input.InputEvent;
5051
import javafx.scene.input.KeyCode;
...
5758
import static javafx.scene.input.KeyCombination.SHIFT_DOWN;
5859
import javafx.scene.input.KeyEvent;
60
import javafx.scene.input.MouseEvent;
5961
import org.fxmisc.richtext.StyledTextArea;
6062
import org.fxmisc.wellbehaved.event.EventPattern;
...
9193
  private int initialCaretPosition;
9294
95
  /**
96
   * Empty constructor.
97
   */
9398
  private VariableNameInjector() {
9499
  }
95100
96101
  public static void listen( final FileEditorTab tab, final DefinitionPane pane ) {
97
    VariableNameInjector vni = new VariableNameInjector();
102
    final VariableNameInjector vni = new VariableNameInjector();
98103
99104
    vni.setFileEditorTab( tab );
100105
    vni.setDefinitionPane( pane );
101
106
    vni.initBranchSelectedListener();
102107
    vni.initKeyboardEventListeners();
108
  }
109
110
  /**
111
   * Traps double-click events on the definition pane.
112
   */
113
  private void initBranchSelectedListener() {
114
    getDefinitionPane().addBranchSelectedListener( (final MouseEvent event) -> {
115
      final Object source = event.getSource();
116
117
      if( source instanceof TreeView ) {
118
        final TreeView tree = (TreeView)source;
119
        final TreeItem item = (TreeItem)tree.getSelectionModel().getSelectedItem();
120
121
        if( item instanceof VariableTreeItem ) {
122
          final VariableTreeItem var = (VariableTreeItem)item;
123
          final String text = decorate( var.toPath() );
124
125
          replaceSelection( text );
126
        }
127
      }
128
    } );
103129
  }
104130
...
161187
162188
          // Decorate the variable upon exiting vMode.
163
          decorateVariable();
189
          decorate();
164190
        }
165191
        break;
...
274300
    if( leaf != null ) {
275301
      replaceText( boundaries[ 0 ], boundaries[ 1 ], leaf.toPath() );
276
      decorateVariable();
302
      decorate();
277303
      expand( leaf );
278304
    }
279305
  }
280306
281307
  /**
282308
   * Called when autocomplete finishes on a valid leaf or when the user presses
283309
   * Enter to finish manual autocomplete.
284310
   */
285
  private void decorateVariable() {
311
  private void decorate() {
286312
    // A little bit of duplication...
287313
    final String paragraph = getCaretParagraph();
288314
    final int[] boundaries = getWordBoundaries( paragraph );
289315
    final String old = paragraph.substring( boundaries[ 0 ], boundaries[ 1 ] );
290316
291
    final String newVariable = getVariableDecorator().decorate( old );
317
    final String newVariable = decorate( old );
292318
293319
    final int posEnded = getCurrentCaretPosition();
294320
    final int posBegan = posEnded - old.length();
295321
296322
    getEditor().replaceText( posBegan, posEnded, newVariable );
323
  }
324
325
  /**
326
   * Called when user double-clicks on a tree view item.
327
   *
328
   * @param variable The variable to decorate.
329
   */
330
  private String decorate( final String variable ) {
331
    return getVariableDecorator().decorate( variable );
332
  }
333
334
  /**
335
   * Inserts the given string at the current caret position, or replaces
336
   * selected text (if any).
337
   *
338
   * @param s The string to inject.
339
   */
340
  private void replaceSelection( final String s ) {
341
    getEditor().replaceSelection( s );
297342
  }
298343
M src/main/java/com/scrivenvar/processors/HTMLPreviewProcessor.java
4141
public class HTMLPreviewProcessor extends AbstractProcessor<String> {
4242
43
  private HTMLPreviewPane htmlPreviewPane;
43
  // There is only one preview panel.
44
  private static HTMLPreviewPane htmlPreviewPane;
4445
4546
  /**
M src/main/java/com/scrivenvar/processors/InlineRProcessor.java
5353
public final class InlineRProcessor extends DefaultVariableProcessor {
5454
55
  private final Notifier notifier = Services.load( Notifier.class );
56
  private final Options options = Services.load( Options.class );
55
  private static final Notifier NOTIFIER = Services.load( Notifier.class );
56
  private static final Options OPTIONS = Services.load( Options.class );
5757
58
  private ScriptEngine engine;
58
  // Only one editor is open at a time.
59
  private static final ScriptEngine ENGINE =
60
    (new ScriptEngineManager()).getEngineByName( "Renjin" );
5961
6062
  /**
...
174176
175177
  private synchronized ScriptEngine getScriptEngine() {
176
    if( this.engine == null ) {
177
      this.engine = (new ScriptEngineManager()).getEngineByName( "Renjin" );
178
    }
179
180
    return this.engine;
178
    return ENGINE;
181179
  }
182180
183181
  private Notifier getNotifier() {
184
    return this.notifier;
182
    return NOTIFIER;
185183
  }
186184
187185
  private Options getOptions() {
188
    return this.options;
186
    return OPTIONS;
189187
  }
190188
M src/main/java/com/scrivenvar/processors/MarkdownProcessor.java
3636
import com.vladsch.flexmark.superscript.SuperscriptExtension;
3737
import java.util.ArrayList;
38
import java.util.List;
39
38
import java.util.Collection;
4039
4140
/**
4241
 * Responsible for parsing a Markdown document and rendering it as HTML.
4342
 *
4443
 * @author White Magic Software, Ltd.
4544
 */
4645
public class MarkdownProcessor extends AbstractProcessor<String> {
4746
48
  private List<Extension> extensions;
47
  private final static HtmlRenderer RENDERER;
48
  private final static Parser PARSER;
49
50
  static {
51
    final Collection<Extension> extensions = new ArrayList<>();
52
    extensions.add( TablesExtension.create() );
53
    extensions.add( SuperscriptExtension.create() );
54
    extensions.add( StrikethroughSubscriptExtension.create() );
55
56
    RENDERER = HtmlRenderer.builder().extensions( extensions ).build();
57
    PARSER = Parser.builder().extensions( extensions ).build();
58
  }
4959
5060
  /**
...
91101
   */
92102
  private Node parse( final String markdown ) {
93
    return createParser().parse( markdown );
103
    return getParser().parse( markdown );
94104
  }
95105
...
102112
   */
103113
  private String toHtml( final String markdown ) {
104
    return createRenderer().render( parse( markdown ) );
105
  }
106
107
  /**
108
   * Returns the list of extensions to use when parsing and rendering Markdown
109
   * into HTML.
110
   *
111
   * @return A non-null list of Markdown extensions.
112
   */
113
  private synchronized List<Extension> getExtensions() {
114
    if( this.extensions == null ) {
115
      this.extensions = createExtensions();
116
    }
117
118
    return this.extensions;
119
  }
120
121
  /**
122
   * Creates a list that includes a TablesExtension. Subclasses may override
123
   * this method to insert more extensions, or remove the table extension.
124
   *
125
   * @return A list with an extension for parsing and rendering tables.
126
   */
127
  protected List<Extension> createExtensions() {
128
    final List<Extension> result = new ArrayList<>();
129
    result.add( TablesExtension.create() );
130
    result.add( SuperscriptExtension.create() );
131
    result.add( StrikethroughSubscriptExtension.create() );
132
    return result;
114
    return getRenderer().render( parse( markdown ) );
133115
  }
134116
135117
  /**
136118
   * Creates the Markdown document processor.
137119
   *
138120
   * @return A Parser that can build an abstract syntax tree.
139121
   */
140
  private Parser createParser() {
141
    return Parser.builder().extensions( getExtensions() ).build();
122
  private Parser getParser() {
123
    return PARSER;
142124
  }
143125
144
  /**
145
   * Creates the HTML document renderer.
146
   *
147
   * @return A renderer that can convert a Markdown AST to HTML.
148
   */
149
  private HtmlRenderer createRenderer() {
150
    return HtmlRenderer.builder().extensions( getExtensions() ).build();
126
  private HtmlRenderer getRenderer() {
127
    return RENDERER;
151128
  }
152129
}
M src/main/java/com/scrivenvar/processors/ProcessorFactory.java
7979
        break;
8080
81
      case MARKDOWN:
81
      case SOURCE:
8282
        processor = createMarkdownProcessor( tab );
8383
        break;
M src/main/java/com/scrivenvar/processors/RVariableProcessor.java
3838
 * @author White Magic Software, Ltd.
3939
 */
40
class RVariableProcessor extends DefaultVariableProcessor {
40
public class RVariableProcessor extends DefaultVariableProcessor {
4141
4242
  public RVariableProcessor(
M src/main/java/com/scrivenvar/processors/XMLCaretInsertionProcessor.java
4242
public class XMLCaretInsertionProcessor extends CaretInsertionProcessor {
4343
44
  private VTDGen parser;
44
  private final static VTDGen PARSER = new VTDGen();
4545
4646
  /**
...
139139
140140
  private synchronized VTDGen getParser() {
141
    if( this.parser == null ) {
142
      this.parser = createParser();
143
    }
144
145
    return this.parser;
146
  }
147
148
  /**
149
   * Creates a high-performance XML document parser.
150
   *
151
   * @return A new XML parser.
152
   */
153
  protected VTDGen createParser() {
154
    return new VTDGen();
141
    return PARSER;
155142
  }
156143
}
M src/main/resources/com/scrivenvar/messages.properties
131131
Dialog.file.choose.save.title=Save File
132132
133
Dialog.file.choose.filter.title.markdown=Markdown Files
133
Dialog.file.choose.filter.title.source=Source Files
134134
Dialog.file.choose.filter.title.definition=Definition Files
135135
Dialog.file.choose.filter.title.xml=XML Files
M src/main/resources/com/scrivenvar/settings.properties
6868
file.ext.rmarkdown=*.Rmd
6969
file.ext.rxml=*.Rxml
70
file.ext.markdown=*.md,*.markdown,*.mkdown,*.mdown,*.mkdn,*.mkd,*.mdwn,*.mdtxt,*.mdtext,*.text,*.txt,${file.ext.rmarkdown}
70
file.ext.source=*.md,*.markdown,*.mkdown,*.mdown,*.mkdn,*.mkd,*.mdwn,*.mdtxt,*.mdtext,*.text,*.txt,${file.ext.rmarkdown},${file.ext.rxml}
7171
file.ext.definition=${definition.file.ext.yaml}
7272
file.ext.xml=*.xml,${file.ext.rxml}