Skip to content

Commit

Permalink
Added Youtube extension to markdown
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorianKirmaier committed Dec 5, 2023
1 parent 4a2e745 commit 207f10f
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 5 deletions.
1 change: 1 addition & 0 deletions jpro-mdfx/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
dependencies {
implementation project(':jpro-youtube')
implementation "com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:$FLEXMARK_VERSION"
implementation "com.vladsch.flexmark:flexmark-ext-gfm-tasklist:$FLEXMARK_VERSION"
implementation "com.vladsch.flexmark:flexmark-ext-tables:$FLEXMARK_VERSION"
Expand Down
2 changes: 1 addition & 1 deletion jpro-mdfx/example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dependencies {

javafx {
version = "$JAVAFX_VERSION"
modules = ['javafx.controls', 'javafx.fxml']
modules = ['javafx.controls', 'javafx.fxml', 'javafx.web']
}

mainClassName = 'one.jpro.platform.mdfx.example.MarkdownViewSample'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
import one.jpro.platform.mdfx.MarkdownView;
import one.jpro.platform.mdfx.extensions.YoutubeExtension;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -57,7 +58,10 @@ public Parent createRoot(Stage stage) {
}
});

final var markdownView = new MarkdownView() {
var markdownExtensions = MarkdownView.defaultExtensions();
markdownExtensions.add(YoutubeExtension.create());

final var markdownView = new MarkdownView("", markdownExtensions) {
@Override
protected List<String> getDefaultStylesheets() {
Optional<String> defaultStylesheet = Optional.ofNullable(getClass().getResource(SAMPLE_CSS))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,12 @@ public class HelloWorld {
>> This is a nested block quote.
>
> - Author

## Images and extensions

CoPilots favorite music:
![alt](youtube:dQw4w9WgXcQ)

Some Image:
![alt](https://www.jpro.one/app/default/resourcesencoded/cp:/1/1/one/jpro/img/landing/DUKE-forward.png)
3 changes: 3 additions & 0 deletions jpro-mdfx/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
requires flexmark.util.sequence;
requires flexmark.util.data;
requires flexmark.util.collection;
requires one.jpro.platform.youtube;

opens one.jpro.platform.mdfx;
exports one.jpro.platform.mdfx;
exports one.jpro.platform.mdfx.extensions;
opens one.jpro.platform.mdfx.extensions;
}
40 changes: 37 additions & 3 deletions jpro-mdfx/src/main/java/one/jpro/platform/mdfx/MarkdownView.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javafx.scene.Node;
import javafx.scene.image.Image;
import javafx.scene.layout.VBox;
import one.jpro.platform.mdfx.extensions.ImageExtension;
import one.jpro.platform.mdfx.impl.AdaptiveImage;
import one.jpro.platform.mdfx.impl.MDFXNodeHelper;

Expand All @@ -15,9 +16,21 @@

public class MarkdownView extends VBox {

private List<ImageExtension> extensions = new ArrayList<>();

private final SimpleStringProperty mdString = new SimpleStringProperty("");

public MarkdownView(String mdString) {
this(mdString, defaultExtensions());
}

public MarkdownView(String mdString, List<ImageExtension> extensions) {
// Check whether only one extension has the scheme null
if(extensions.stream().filter(e -> e.getScheme() == null).count() > 1) {
throw new IllegalArgumentException("Only one extension can have a scheme of null");
}

this.extensions = extensions;
this.mdString.set(mdString);
this.mdString.addListener((p,o,n) -> updateContent());
Optional.ofNullable(MarkdownView.class.getResource("/one/jpro/platform/mdfx/mdfx.css"))
Expand Down Expand Up @@ -65,6 +78,28 @@ public void setLink(Node node, String link, String description) {
}

public Node generateImage(String url) {
// Let's find an extension with a matching scheme
// But be aware, that the url is sometimes relative without a scheme

var res = extensions.stream()
.filter(e -> e.getScheme() != null && url.startsWith(e.getScheme()))
.findFirst();

if(res.isEmpty()) {
res = extensions.stream()
.filter(e -> e.getScheme() == null)
.findFirst();
}

return res.get().getFunction().apply(url, this);
}


public static List<ImageExtension> defaultExtensions() {
return new ArrayList<>(List.of(DEFAULT_IMAGE_EXTENSION));
}

static ImageExtension DEFAULT_IMAGE_EXTENSION = new ImageExtension(null, (url, view) -> {
if(url.isEmpty()) {
return new Group();
} else {
Expand All @@ -73,10 +108,9 @@ public Node generateImage(String url) {

// The TextFlow does not limit the width of its node based on the available width
// As a workaround, we bind to the width of the MarkDownView.
r.maxWidthProperty().bind(widthProperty());
r.maxWidthProperty().bind(view.widthProperty());

return r;
}

}
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package one.jpro.platform.mdfx.extensions;

import javafx.scene.Node;
import one.jpro.platform.mdfx.MarkdownView;

import java.util.function.BiFunction;

/**
* An extension for the MarkdownView.
* The scheme is used to identify the extension in the markdown string.
*
* An scheme of null is used to identify the default image extension.
*/
public class ImageExtension {
String scheme;
BiFunction<String, MarkdownView, Node> function;

public ImageExtension(String scheme, BiFunction<String, MarkdownView, Node> function) {
this.scheme = scheme;
this.function = function;
}

public String getScheme() {
return scheme;
}

public BiFunction<String, MarkdownView, Node> getFunction() {
return function;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package one.jpro.platform.mdfx.extensions;

import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import one.jpro.platform.youtube.YoutubeNode;

public class YoutubeExtension {

public static ImageExtension create() {
return new ImageExtension(
"youtube", (url, view) -> {
var uri = java.net.URI.create(url);
var schemeSpecificPart = uri.getSchemeSpecificPart();
var node = new VBox(new Label(""), new YoutubeNode(schemeSpecificPart));
node.prefWidthProperty().bind(view.widthProperty());
node.maxWidthProperty().bind(view.widthProperty());
return node;
});
}
}

0 comments on commit 207f10f

Please sign in to comment.