Dave Jarvis' Repositories

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

Initial code: - only single markdown editor window - markdown syntax highlighting for h1-h6, em and strong

Author Karl Tauber <email>
Date 2015-07-21 19:34:23 GMT+0200
Commit 0db533d101f33d08b95f37330e00596ba299664a
Parent eb7f2f2
src/main/java/org/markdownwriterfx/MarkdownWriterFXApp.java
+/*
+ * Copyright (c) 2015 Karl Tauber <karl at jformdesigner dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.markdownwriterfx;
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.scene.layout.BorderPane;
+import javafx.stage.Stage;
+import org.markdownwriterfx.editor.MarkdownEditorPane;
+
+/**
+ * Markdown Writer FX application.
+ *
+ * @author Karl Tauber
+ */
+public class MarkdownWriterFXApp
+ extends Application
+{
+ public static void main(String[] args) {
+ launch(args);
+ }
+
+ @Override
+ public void start(Stage primaryStage) throws Exception {
+ MarkdownEditorPane markdownEditorPane = new MarkdownEditorPane();
+ markdownEditorPane.setMarkdown("# h1\n\n## h2\n\nsome **bold** text\n\n* ul 1\n* ul 2\n* ul 3");
+
+ BorderPane content = new BorderPane(markdownEditorPane);
+ content.setPrefSize(600, 800);
+
+ primaryStage.setTitle("Markdown Writer FX");
+ primaryStage.setScene(new Scene(content));
+ primaryStage.show();
+ }
+}
src/main/java/org/markdownwriterfx/editor/MarkdownEditor.css
+/*
+ * Copyright (c) 2015 Karl Tauber <karl at jformdesigner dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.markdown-editor .h1 { -fx-font-size: 2em; }
+.markdown-editor .h2 { -fx-font-size: 1.75em; }
+.markdown-editor .h3 { -fx-font-size: 1.5em; }
+.markdown-editor .h4 { -fx-font-size: 1.25em; }
+.markdown-editor .h5 { -fx-font-size: 1.1em; }
+.markdown-editor .h6 { -fx-font-size: 1em; }
+
+.markdown-editor .h1,
+.markdown-editor .h2,
+.markdown-editor .h3,
+.markdown-editor .h4,
+.markdown-editor .h5,
+.markdown-editor .h6 {
+ -fx-font-weight: bold;
+ -fx-fill: crimson;
+}
+
+.markdown-editor .em {
+ -fx-font-style: italic;
+ -fx-fill: #4060c0;
+}
+
+.markdown-editor .strong {
+ -fx-font-weight: bold;
+ -fx-fill: #4060c0;
+}
src/main/java/org/markdownwriterfx/editor/MarkdownEditorPane.java
+/*
+ * Copyright (c) 2015 Karl Tauber <karl at jformdesigner dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.markdownwriterfx.editor;
+
+import javafx.scene.layout.BorderPane;
+import org.fxmisc.richtext.StyleClassedTextArea;
+import org.pegdown.Extensions;
+import org.pegdown.PegDownProcessor;
+import org.pegdown.ast.RootNode;
+
+/**
+ * Markdown editor pane.
+ *
+ * Uses pegdown (https://github.com/sirthias/pegdown) for parsing markdown.
+ *
+ * @author Karl Tauber
+ */
+public class MarkdownEditorPane
+ extends BorderPane
+{
+ private final StyleClassedTextArea textArea;
+ private PegDownProcessor pegDownProcessor;
+
+ public MarkdownEditorPane() {
+ textArea = new StyleClassedTextArea();
+ textArea.setWrapText(true);
+ textArea.getStyleClass().add("markdown-editor");
+ textArea.getStylesheets().add("org/markdownwriterfx/editor/MarkdownEditor.css");
+
+ textArea.textProperty().addListener((observable, oldText, newText) -> {
+ applyHighlighting(parseMarkdown(newText));
+ });
+
+ setCenter(textArea);
+ }
+
+ public String getMarkdown() {
+ return textArea.getText();
+ }
+
+ public void setMarkdown(String markdown) {
+ textArea.replaceText(markdown);
+ }
+
+ private RootNode parseMarkdown(String text) {
+ if(pegDownProcessor == null)
+ pegDownProcessor = new PegDownProcessor(Extensions.ALL);
+ return pegDownProcessor.parseMarkdown(text.toCharArray());
+ }
+
+ private void applyHighlighting(RootNode astRoot) {
+ MarkdownSyntaxHighlighter.highlight(textArea, astRoot);
+ }
+}
src/main/java/org/markdownwriterfx/editor/MarkdownSyntaxHighlighter.java
+/*
+ * Copyright (c) 2015 Karl Tauber <karl at jformdesigner dot com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.markdownwriterfx.editor;
+
+import java.util.Collections;
+import javafx.application.Platform;
+import org.fxmisc.richtext.StyleClassedTextArea;
+import org.pegdown.ast.*;
+
+/**
+ * Markdown syntax highlighter.
+ *
+ * Uses pegdown AST.
+ *
+ * @author Karl Tauber
+ */
+class MarkdownSyntaxHighlighter
+ implements Visitor
+{
+ private final StyleClassedTextArea textArea;
+ private final int textLength;
+
+ static void highlight(StyleClassedTextArea textArea, RootNode astRoot) {
+ new MarkdownSyntaxHighlighter(textArea).toStyles(astRoot);
+ }
+
+ private MarkdownSyntaxHighlighter(StyleClassedTextArea textArea) {
+ this.textArea = textArea;
+ this.textLength = textArea.getLength();
+ }
+
+ private void toStyles(RootNode astRoot) {
+ assert Platform.isFxApplicationThread();
+
+ textArea.clearStyle(0, textLength);
+ astRoot.accept(this);
+ }
+
+ @Override
+ public void visit(AbbreviationNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(AnchorLinkNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(AutoLinkNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(BlockQuoteNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(BulletListNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(CodeNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(DefinitionListNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(DefinitionNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(DefinitionTermNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(ExpImageNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(ExpLinkNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(HeaderNode node) {
+ setStyleClass(node, "h" + node.getLevel());
+ }
+
+ @Override
+ public void visit(HtmlBlockNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(InlineHtmlNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(ListItemNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(MailLinkNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(OrderedListNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(ParaNode node) {
+ // TODO Auto-generated method stub
+ visitChildren(node);
+ }
+
+ @Override
+ public void visit(QuotedNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(ReferenceNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(RefImageNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(RefLinkNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(RootNode node) {
+ // TODO Auto-generated method stub
+ visitChildren(node);
+ }
+
+ @Override
+ public void visit(SimpleNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(SpecialTextNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(StrikeNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(StrongEmphSuperNode node) {
+ setStyleClass(node, node.isStrong() ? "strong" : "em");
+ }
+
+ @Override
+ public void visit(TableBodyNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(TableCaptionNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(TableCellNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(TableColumnNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(TableHeaderNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(TableNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(TableRowNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(VerbatimNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(WikiLinkNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(TextNode node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void visit(SuperNode node) {
+ // TODO Auto-generated method stub
+ visitChildren(node);
+ }
+
+ @Override
+ public void visit(Node node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private void visitChildren(SuperNode node) {
+ for (Node child : node.getChildren())
+ child.accept(this);
+ }
+
+ private void setStyleClass(Node node, String styleClass) {
+ try {
+ // because PegDownProcessor.prepareSource() adds two trailing newlines
+ // to the text before parsing, we need to limit the end index
+ textArea.setStyle(node.getStartIndex(),
+ Math.min(node.getEndIndex(), textLength),
+ Collections.singleton(styleClass));
+ } catch(IllegalArgumentException ex) {
+ ex.printStackTrace();
+ }
+ }
+}
Delta 504 lines added, 0 lines removed, 504-line increase