You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2019/07/06 06:01:12 UTC

[isis] branch v2 updated: ISIS-2143: Introduces Markdown as new value type

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/v2 by this push:
     new 047803d  ISIS-2143: Introduces Markdown as new value type
047803d is described below

commit 047803ddfc60e9f856f6540067999942f4589a75
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Jul 6 08:01:02 2019 +0200

    ISIS-2143: Introduces Markdown as new value type
    
    - also refactors the Markup value-type infrastructure for less
    boilerplate when extending with AsciiDoc and Markdown
    - also implements client-side java-script caching for
    syntax-highlighting
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-2143
---
 .../scalars/markup/MarkupComponentFactory.java     |  21 ++--
 .../scalars/markup/MarkupComponent_reloadJs.java   |  56 ++++++++++
 .../ui/components/scalars/markup/MarkupPanel.java  |  36 ++-----
 .../scalars/markup/MarkupPanelFactories.java       | 120 ++++++++++++++++-----
 .../scalars/markup/StandaloneMarkupPanel.java      |  21 ++--
 .../src/main/java/domainapp/utils/DemoStub.java    |   2 +-
 .../apps/demo/src/main/webapp/css/application.css  |   2 -
 .../apps/demo/src/main/webapp/scripts/prism1.14.js |   8 --
 .../apache/isis/extensions/asciidoc/AsciiDoc.java  |  14 ++-
 .../extensions/asciidoc/AsciiDocComponent.java     |  28 ++++-
 .../AsciiDocComponent_highlightSyntax.java         |  74 -------------
 .../asciidoc/AsciiDocComponent_reloadJs.java       |  55 ++++++++++
 .../asciidoc/AsciiDocPanelFactoriesForWicket.java  |  78 ++++----------
 .../apache/isis/extensions/asciidoc/css}/prism.css |   0
 .../isis/extensions/asciidoc/js}/prism1.14.js      |   0
 extensions/markdown/pom.xml                        |  11 ++
 .../apache/isis/extensions/markdown/Markdown.java} |  18 +++-
 .../extensions/markdown/MarkdownComponent.java}    |  36 +++++--
 .../markdown/MarkdownPanelFactoriesForWicket.java  |  76 +++++++++++++
 .../apache/isis/extensions/markdown}/css/prism.css |   0
 .../isis/extensions/markdown/js}/prism1.14.js      |   0
 ...g.apache.isis.viewer.wicket.ui.ComponentFactory |   2 +
 22 files changed, 415 insertions(+), 243 deletions(-)

diff --git a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponentFactory.java
similarity index 61%
copy from extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java
copy to core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponentFactory.java
index b52c59b..47ac44d 100644
--- a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponentFactory.java
@@ -16,22 +16,13 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.asciidoc;
+package org.apache.isis.viewer.wicket.ui.components.scalars.markup;
 
-import org.apache.isis.applib.annotation.Value;
-import org.apache.isis.applib.value.Markup;
+import org.apache.wicket.model.IModel;
 
-/**
- * Immutable value type holding pre-rendered HTML.
- *
- */
-@Value(semanticsProviderName = 
-        "org.apache.isis.metamodel.facets.value.markup.MarkupValueSemanticsProvider")
-public class AsciiDoc extends Markup {
+@FunctionalInterface
+public interface MarkupComponentFactory {
+
+    MarkupComponent newMarkupComponent(String id, IModel<?> model);
 
-    private static final long serialVersionUID = 1L;
-    
-    public AsciiDoc(String asciiDoc) {
-        super(AsciiDocConverter.adocToHtml(asciiDoc));
-    }
 }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent_reloadJs.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent_reloadJs.java
new file mode 100644
index 0000000..be6d8e6
--- /dev/null
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupComponent_reloadJs.java
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.viewer.wicket.ui.components.scalars.markup;
+
+import java.util.UUID;
+
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+
+import lombok.val;
+
+/**
+ * Helper for MarkupComponents to reload a specified java-script reference, when rendering.
+ * @implNote used by AsciiDoc and Markdown extensions 
+ */
+public class MarkupComponent_reloadJs {
+
+    public static CharSequence decorate(CharSequence htmlContent, JavaScriptResourceReference jsRef) {
+
+        val targetId = UUID.randomUUID().toString();
+        
+        val sb = new StringBuilder();
+        sb
+        .append("<div id=\"").append(targetId).append("\">\n")
+        .append(htmlContent)
+        .append("\n</div>\n")
+        .append("<script type=\"text/javascript\" src=\""+getUrl(jsRef)+"\" defer>\n")
+        .append("\n</script>\n");
+        
+        return sb.toString();
+    }
+    
+    private static String getUrl(JavaScriptResourceReference jsRef) {
+        IRequestHandler handler = new ResourceReferenceRequestHandler(jsRef, null);
+        return RequestCycle.get().urlFor(handler).toString();
+    }
+
+}
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanel.java
index f4eeef7..c1effdb 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanel.java
@@ -24,25 +24,27 @@ import org.apache.wicket.MarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.model.Model;
 
-import org.apache.isis.applib.value.LocalResourcePath;
-import org.apache.isis.metamodel.facets.objectvalue.observe.ObserveFacet;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.ScalarPanelTextFieldParseableAbstract;
 import org.apache.isis.viewer.wicket.ui.components.widgets.bootstrap.FormGroup;
 
-import lombok.val;
-
 /**
  * Panel for rendering scalars of type {@link org.apache.isis.applib.value.Markup}.
  */
 public class MarkupPanel extends ScalarPanelTextFieldParseableAbstract {
 
     private static final long serialVersionUID = 1L;
+    private final transient MarkupComponentFactory markupComponentFactory;
 
-    public MarkupPanel(final String id, final ScalarModel scalarModel) {
+    public MarkupPanel(
+            String id, 
+            ScalarModel scalarModel, 
+            MarkupComponentFactory markupComponentFactory) {
+        
         super(id, scalarModel);
+        this.markupComponentFactory = markupComponentFactory;
     }
-
+    
     @Override
     protected String getScalarPanelType() {
         return "markupPanel";
@@ -77,28 +79,8 @@ public class MarkupPanel extends ScalarPanelTextFieldParseableAbstract {
         return createMarkupComponent(ID_SCALAR_IF_COMPACT);
     }
 
-    /**
-     * Allows for sub classes to create customized MarkupComponents. 
-     * eg. add java-script
-     * @param id
-     * @return
-     */
     protected MarkupComponent createMarkupComponent(String id) {
-        val markupComponent = new MarkupComponent(id, getModel(), getEventStreamResource());
-        markupComponent.setEnabled(false);
-        return markupComponent;
-    }
-    
-    // -- HELPER
-    
-    private LocalResourcePath getEventStreamResource() {
-        final ObserveFacet observeFacet  = super.scalarModel.getFacet(ObserveFacet.class);
-        if(observeFacet==null) {
-            return null;
-        }
-        final String eventStreamId = observeFacet.getEventStreamType().getName();
-        final LocalResourcePath ssePath = new LocalResourcePath("/sse?eventStream=" + eventStreamId);
-        return ssePath;
+        return markupComponentFactory.newMarkupComponent(id, getModel());
     }
     
 
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java
index 8137cd4..92ba386 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/MarkupPanelFactories.java
@@ -19,84 +19,156 @@
 
 package org.apache.isis.viewer.wicket.ui.components.scalars.markup;
 
+import org.apache.wicket.Component;
+import org.apache.wicket.model.IModel;
+
+import org.apache.isis.applib.value.LocalResourcePath;
 import org.apache.isis.applib.value.Markup;
-import org.apache.isis.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.metamodel.facets.objectvalue.observe.ObserveFacet;
 import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.model.models.ValueModel;
 import org.apache.isis.viewer.wicket.ui.ComponentFactory;
 import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
-import org.apache.wicket.Component;
-import org.apache.wicket.model.IModel;
+
+import lombok.val;
 
 /**
  * {@link ComponentFactory} for {@link MarkupPanel}.
  */
 public class MarkupPanelFactories {
+    
+    // -- PUBLIC FACTORIES (FOR REGISTRATION)
+    
+    public static ComponentFactory parented() {
+        return new Parented();
+    }
 
-    // -- PARENTED
+    public static ComponentFactory standalone() {
+        return new Standalone();
+    }
 
-    static class Parented extends ComponentFactoryAbstract {
+    // -- PARENTED (ABSTRACT)
+    
+    public static abstract class ParentedAbstract extends ComponentFactoryAbstract {
         private static final long serialVersionUID = 1L;
 
-        public Parented() {
+        private final Class<?> valueType;
+        
+        public ParentedAbstract(Class<?> valueType) {
             super(ComponentType.SCALAR_NAME_AND_VALUE, MarkupPanel.class);
+            this.valueType = valueType;
         }
 
         @Override
         public ApplicationAdvice appliesTo(final IModel<?> model) {
-            if (!(model instanceof ScalarModel))
+            if (!(model instanceof ScalarModel)) {
                 return ApplicationAdvice.DOES_NOT_APPLY;
+            }
 
-            final ScalarModel scalarModel = (ScalarModel) model;
+            val scalarModel = (ScalarModel) model;
 
-            if(!scalarModel.isScalarTypeAnyOf(org.apache.isis.applib.value.Markup.class))
+            if(!scalarModel.isScalarTypeAnyOf(valueType)) {
                 return ApplicationAdvice.DOES_NOT_APPLY;
+            }
 
             return appliesIf( !scalarModel.hasChoices() );
         }
 
         @Override
         public final Component createComponent(final String id, final IModel<?> model) {
-            return new MarkupPanel(id, (ScalarModel) model);
+            return new MarkupPanel(id, (ScalarModel) model, getMarkupComponentFactory());        
         }
+        
+        protected abstract MarkupComponentFactory getMarkupComponentFactory();
+        
     }
+    
+    // -- STANDALONE (ABSTRACT)
 
-    // -- STANDALONE
-
-    static class Standalone extends ComponentFactoryAbstract {
+    public static abstract class StandaloneAbstract extends ComponentFactoryAbstract {
         private static final long serialVersionUID = 1L;
+        
+        private final Class<?> valueType;
 
-        public Standalone() {
+        public StandaloneAbstract(Class<?> valueType) {
             super(ComponentType.VALUE, StandaloneMarkupPanel.class);
+            this.valueType = valueType;
         }
 
         @Override
         public ApplicationAdvice appliesTo(final IModel<?> model) {
             if (!(model instanceof ValueModel))
                 return ApplicationAdvice.DOES_NOT_APPLY;
-            final ValueModel valueModel = (ValueModel) model;
-            final ObjectAdapter adapter = valueModel.getObject();
-            if(adapter==null || adapter.getPojo()==null)
+            val valueModel = (ValueModel) model;
+            val objectAdapter = valueModel.getObject();
+            if(objectAdapter==null || objectAdapter.getPojo()==null) {
                 return ApplicationAdvice.DOES_NOT_APPLY;
+            }
 
-            return appliesIf( adapter.getPojo() instanceof Markup );
+            return appliesIf( valueType.isAssignableFrom(objectAdapter.getPojo().getClass()) );
         }
 
         @Override
         public final Component createComponent(final String id, final IModel<?> model) {
-            return new StandaloneMarkupPanel(id, (ValueModel) model);
+            return new StandaloneMarkupPanel(id, (ValueModel) model, getMarkupComponentFactory());
         }
+        
+        protected abstract MarkupComponentFactory getMarkupComponentFactory();
     }
 
-    // -- CONSTRUCTION
+    // -- CONCRETE COMPONENT FACTORY - PARENTED
+    
+    static class Parented extends ParentedAbstract {
+        private static final long serialVersionUID = 1L;
+
+        public Parented() {
+            super(Markup.class);
+        }
+
+        @Override
+        protected MarkupComponentFactory getMarkupComponentFactory() {
+            return (id, model) -> {
+                val markupComponent = new MarkupComponent(
+                        id, model, getEventStreamResource((ScalarModel)model));
+                markupComponent.setEnabled(false);
+                return markupComponent;    
+            };
+        }
+        
+        // -- HELPER
+        
+        private LocalResourcePath getEventStreamResource(ScalarModel scalarModel) {
+            final ObserveFacet observeFacet  = scalarModel.getFacet(ObserveFacet.class);
+            if(observeFacet==null) {
+                return null;
+            }
+            final String eventStreamId = observeFacet.getEventStreamType().getName();
+            final LocalResourcePath ssePath = new LocalResourcePath("/sse?eventStream=" + eventStreamId);
+            return ssePath;
+        }
 
-    public static ComponentFactory parented() {
-        return new Parented();
     }
+    
+    // -- CONCRETE COMPONENT FACTORY - STANDALONE
+    
+    static class Standalone extends StandaloneAbstract {
+        private static final long serialVersionUID = 1L;
 
-    public static ComponentFactory standalone() {
-        return new Standalone();
+        public Standalone() {
+            super(Markup.class);
+        }
+
+        @Override
+        protected MarkupComponentFactory getMarkupComponentFactory() {
+            return (id, model) -> {
+                val markupComponent = new MarkupComponent(
+                        id, model, /*observing not supported*/ null);
+                return markupComponent;    
+            };
+        }
     }
+    
+    
 
 }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/StandaloneMarkupPanel.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/StandaloneMarkupPanel.java
index e60c73f..b058a7e 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/StandaloneMarkupPanel.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/markup/StandaloneMarkupPanel.java
@@ -28,21 +28,16 @@ public class StandaloneMarkupPanel extends PanelAbstract<ValueModel> {
 
     private static final long serialVersionUID = 1L;
     private static final String ID_STANDALONE_VALUE = "standaloneValue";
-
-    public StandaloneMarkupPanel(final String id, final ValueModel valueModel) {
+      
+    public StandaloneMarkupPanel(
+            String id, 
+            ValueModel valueModel, 
+            MarkupComponentFactory markupComponentFactory) {
+        
         super(id, valueModel);
-        val markupComponent = createMarkupComponent(ID_STANDALONE_VALUE);
+        val markupComponent = markupComponentFactory
+                .newMarkupComponent(ID_STANDALONE_VALUE, getModel());
         add(markupComponent);
     }
-
-    /**
-     * Allows for sub classes to create customized MarkupComponents. 
-     * eg. add java-script
-     * @param id
-     */
-    protected MarkupComponent createMarkupComponent(String id) {
-        val markupComponent = new MarkupComponent(id, getModel(), null /*observing*/);
-        return markupComponent;
-    }
     
 }
diff --git a/examples/apps/demo/src/main/java/domainapp/utils/DemoStub.java b/examples/apps/demo/src/main/java/domainapp/utils/DemoStub.java
index 2d29340..8eb3947 100644
--- a/examples/apps/demo/src/main/java/domainapp/utils/DemoStub.java
+++ b/examples/apps/demo/src/main/java/domainapp/utils/DemoStub.java
@@ -42,7 +42,7 @@ public abstract class DemoStub {
 	
 	@PropertyLayout(cssClass = "adoc")
 	public AsciiDoc getDescription() {
-		return new AsciiDoc(readAsciiDocDescription());
+		return AsciiDoc.valueOfAdoc(readAsciiDocDescription());
 	}
 
 	protected final static Map<String, String> constants = createConstants();
diff --git a/examples/apps/demo/src/main/webapp/css/application.css b/examples/apps/demo/src/main/webapp/css/application.css
index 0646355..d061cc7 100644
--- a/examples/apps/demo/src/main/webapp/css/application.css
+++ b/examples/apps/demo/src/main/webapp/css/application.css
@@ -1,5 +1,3 @@
-@import "prism.css";
-
 /* fix brand icon */
 .navbar-header a.navbar-brand {
     margin-top: -14px;
diff --git a/examples/apps/demo/src/main/webapp/scripts/prism1.14.js b/examples/apps/demo/src/main/webapp/scripts/prism1.14.js
deleted file mode 100644
index 2d22f87..0000000
--- a/examples/apps/demo/src/main/webapp/scripts/prism1.14.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/* PrismJS 1.14.0
-http://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+java */
-var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(){var e=/\blang(?:uage)?-([\w-]+)\b/i,t=0,n=_self.Prism={manual:_self.Prism&&_self.Prism.manual,disableWorkerMessageHandler:_self.Prism&&_self.Prism.disableWorkerMessageHandler,util:{encode:function(e){return e instanceof r?new r(e.type,n.util.encode(e.content),e.alias):"Array"===n.util.type(e)?e.map(n.util.encode):e.replace(/&/g,"&amp;").replace(/</ [...]
-Prism.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:/<!DOCTYPE[\s\S]+?>/i,cdata:/<!\[CDATA\[[\s\S]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+))?)*\s*\/?>/i,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|[^\s'">=]+)/i,inside:{punctuation:[/^=/,{pattern:/(^|[^\\])["']/,lookbehin [...]
-Prism.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(?:;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^{}\s][^{};]*?(?=\s*\{)/,string:{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},property:/[-_a-z\xA0-\uFFFF][-\w\xA0-\uFFFF]*(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},Prism.languages.css.atrule.inside.rest=Prism.languages [...]
-Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|conti [...]
-Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|var|void|while|with|yield)\b/,number:/\b(?:0[xX][\dA-Fa-f]+|0[bB][01]+|0[oO][0-7]+|NaN|Infinity)\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee][+-]?\d+ [...]
-Prism.languages.java=Prism.languages.extend("clike",{keyword:/\b(?:abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp-]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d [...]
\ No newline at end of file
diff --git a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java
index b52c59b..84258f1 100644
--- a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java
+++ b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java
@@ -31,7 +31,17 @@ public class AsciiDoc extends Markup {
 
     private static final long serialVersionUID = 1L;
     
-    public AsciiDoc(String asciiDoc) {
-        super(AsciiDocConverter.adocToHtml(asciiDoc));
+    public static AsciiDoc valueOfAdoc(String asciiDoc) {
+        return valueOfHtml(AsciiDocConverter.adocToHtml(asciiDoc));
     }
+    
+    public static AsciiDoc valueOfHtml(String html) {
+        return new AsciiDoc(html);
+    }
+    
+    private AsciiDoc(String html) {
+        super(html);
+    }
+     
+    
 }
diff --git a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent.java b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent.java
index 87fd21c..e177df5 100644
--- a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent.java
+++ b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent.java
@@ -20,9 +20,16 @@ package org.apache.isis.extensions.asciidoc;
 
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.head.CssHeaderItem;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.resource.CssResourceReference;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
 
+import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent;
+import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent_reloadJs;
 
 import lombok.val;
 
@@ -37,11 +44,22 @@ public class AsciiDocComponent extends MarkupComponent {
     @Override
     public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
         val htmlContent = extractHtmlOrElse(getDefaultModelObject(), "" /*fallback*/);
-        replaceComponentTagBody(
-                markupStream, 
-                openTag, 
-                AsciiDocComponent_highlightSyntax.decorate(htmlContent)
-                );
+        replaceComponentTagBody(markupStream, openTag, 
+                MarkupComponent_reloadJs.decorate(htmlContent, jsRef.get()));
     }
+    
+    @Override
+    public void renderHead(IHeaderResponse response) {
+        super.renderHead(response);
+        
+        response.render(CssHeaderItem.forReference(
+                new CssResourceReference(AsciiDocComponent.class, "css/prism.css")));
+
+        response.render(JavaScriptHeaderItem.forReference(jsRef.get()));
+
+    }
+
+    private final static _Lazy<JavaScriptResourceReference> jsRef = _Lazy.threadSafe(()->
+        new JavaScriptResourceReference(AsciiDocComponent.class, "js/prism1.14.js"));
 
 }
diff --git a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent_highlightSyntax.java b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent_highlightSyntax.java
deleted file mode 100644
index a693411..0000000
--- a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent_highlightSyntax.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.extensions.asciidoc;
-
-import static org.apache.isis.commons.internal.base._Strings.isNullOrEmpty;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.UUID;
-
-import org.apache.isis.commons.internal.resources._Resources;
-
-/**
- * package private helper for AsciiDocComponent
- */
-class AsciiDocComponent_highlightSyntax {
-
-    private static final String jScriptTemplateResource = "/prism1.14.js";
-    
-    static CharSequence decorate(CharSequence htmlContent) {
-
-        final String jScriptTemplate;
-        try {
-            jScriptTemplate = _Resources.loadAsString(
-                    AsciiDocComponent_highlightSyntax.class, 
-                    jScriptTemplateResource, 
-                    StandardCharsets.UTF_8);
-            
-        } catch (IOException e) {
-            e.printStackTrace();
-            return resourceNotFound();
-        }
-        
-        if(isNullOrEmpty(jScriptTemplate)) {
-            return resourceNotFound();
-        }
-        
-        final String targetId = UUID.randomUUID().toString();
-        
-        final StringBuilder sb = new StringBuilder();
-        sb
-        .append("<div id=\"").append(targetId).append("\">\n")
-        .append(htmlContent)
-        .append("\n</div>\n")
-        .append("<script type=\"text/javascript\" defer>\n")
-        .append(jScriptTemplate)
-        .append("\n</script>\n");
-        
-        return sb.toString();
-    }
-
-    private static String resourceNotFound() {
-        return "Prism resource not found: '"+jScriptTemplateResource+"'.";
-    }
-
-
-
-}
diff --git a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent_reloadJs.java b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent_reloadJs.java
new file mode 100644
index 0000000..8f868e6
--- /dev/null
+++ b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent_reloadJs.java
@@ -0,0 +1,55 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.extensions.asciidoc;
+
+import java.util.UUID;
+
+import org.apache.wicket.request.IRequestHandler;
+import org.apache.wicket.request.cycle.RequestCycle;
+import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
+
+import lombok.val;
+
+/**
+ * package private helper for AsciiDocComponent
+ */
+class AsciiDocComponent_reloadJs {
+
+    static CharSequence decorate(CharSequence htmlContent, JavaScriptResourceReference jsRef) {
+
+        val targetId = UUID.randomUUID().toString();
+        
+        val sb = new StringBuilder();
+        sb
+        .append("<div id=\"").append(targetId).append("\">\n")
+        .append(htmlContent)
+        .append("\n</div>\n")
+        .append("<script type=\"text/javascript\" src=\""+getUrl(jsRef)+"\" defer>\n")
+        .append("\n</script>\n");
+        
+        return sb.toString();
+    }
+    
+    private static String getUrl(JavaScriptResourceReference jsRef) {
+        IRequestHandler handler = new ResourceReferenceRequestHandler(jsRef, null);
+        return RequestCycle.get().urlFor(handler).toString();
+    }
+
+}
diff --git a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocPanelFactoriesForWicket.java b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocPanelFactoriesForWicket.java
index d731dc1..b85b095 100644
--- a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocPanelFactoriesForWicket.java
+++ b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocPanelFactoriesForWicket.java
@@ -19,23 +19,14 @@
 
 package org.apache.isis.extensions.asciidoc;
 
-import org.apache.wicket.Component;
-import org.apache.wicket.model.IModel;
-
-import org.apache.isis.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.viewer.wicket.model.models.ScalarModel;
-import org.apache.isis.viewer.wicket.model.models.ValueModel;
-import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
-import org.apache.isis.viewer.wicket.ui.ComponentType;
-import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent;
-import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupPanel;
+import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponentFactory;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupPanelFactories;
-import org.apache.isis.viewer.wicket.ui.components.scalars.markup.StandaloneMarkupPanel;
 
 import lombok.val;
 
 /**
- * @implNote Almost a copy of {@link MarkupPanelFactories}, but specific to 
+ * @implNote Almost a copy of {@code Parented} and {@code Standalone} in 
+ * {@link MarkupPanelFactories}, but specific to 
  * the {@link AsciiDoc} value-type which requires client-side java-script to be
  * executed to enable syntax highlighting
  */
@@ -43,75 +34,42 @@ public class AsciiDocPanelFactoriesForWicket {
 
     // -- PARENTED
 
-    public static class Parented extends ComponentFactoryAbstract {
+    public static class Parented extends MarkupPanelFactories.ParentedAbstract {
         private static final long serialVersionUID = 1L;
 
         public Parented() {
-            super(ComponentType.SCALAR_NAME_AND_VALUE, MarkupPanel.class);
+            super(AsciiDoc.class);
         }
 
         @Override
-        public ApplicationAdvice appliesTo(final IModel<?> model) {
-            if (!(model instanceof ScalarModel))
-                return ApplicationAdvice.DOES_NOT_APPLY;
-
-            final ScalarModel scalarModel = (ScalarModel) model;
-
-            if(!scalarModel.isScalarTypeAnyOf(AsciiDoc.class))
-                return ApplicationAdvice.DOES_NOT_APPLY;
+        protected MarkupComponentFactory getMarkupComponentFactory() {
+            return (id, model) -> {
+                val markupComponent = new AsciiDocComponent(id, model);
+                markupComponent.setEnabled(false);
+                return markupComponent;    
+            };
 
-            return appliesIf( !scalarModel.hasChoices() );
         }
 
-        @Override
-        public final Component createComponent(final String id, final IModel<?> model) {
-            return new MarkupPanel(id, (ScalarModel) model) {
-                private static final long serialVersionUID = 1L;
-                
-                @Override
-                protected MarkupComponent createMarkupComponent(String id) {
-                    val markupComponent = new AsciiDocComponent(id, getModel());
-                    markupComponent.setEnabled(false);
-                    return markupComponent;
-                }
-
-            };
-        }
     }
 
     // -- STANDALONE
 
-    public static class Standalone extends ComponentFactoryAbstract {
+    public static class Standalone extends MarkupPanelFactories.StandaloneAbstract {
         private static final long serialVersionUID = 1L;
 
         public Standalone() {
-            super(ComponentType.VALUE, StandaloneMarkupPanel.class);
+            super(AsciiDoc.class);
         }
 
         @Override
-        public ApplicationAdvice appliesTo(final IModel<?> model) {
-            if (!(model instanceof ValueModel))
-                return ApplicationAdvice.DOES_NOT_APPLY;
-            final ValueModel valueModel = (ValueModel) model;
-            final ObjectAdapter adapter = valueModel.getObject();
-            if(adapter==null || adapter.getPojo()==null)
-                return ApplicationAdvice.DOES_NOT_APPLY;
-
-            return appliesIf( adapter.getPojo() instanceof AsciiDoc );
-        }
-
-        @Override
-        public final Component createComponent(final String id, final IModel<?> model) {
-            return new StandaloneMarkupPanel(id, (ValueModel) model) {
-                private static final long serialVersionUID = 1L;
-                
-                @Override
-                protected MarkupComponent createMarkupComponent(String id) {
-                    val markupComponent = new AsciiDocComponent(id, getModel());
-                    return markupComponent;
-                }
+        protected MarkupComponentFactory getMarkupComponentFactory() {
+            return (id, model) -> {
+                val markupComponent = new AsciiDocComponent(id, model);
+                return markupComponent;    
             };
         }
+
     }
 
 
diff --git a/extensions/asciidoc/src/main/resources/prism.css b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/css/prism.css
similarity index 100%
rename from extensions/asciidoc/src/main/resources/prism.css
rename to extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/css/prism.css
diff --git a/extensions/markdown/src/main/resources/prism1.14.js b/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/js/prism1.14.js
similarity index 100%
rename from extensions/markdown/src/main/resources/prism1.14.js
rename to extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/js/prism1.14.js
diff --git a/extensions/markdown/pom.xml b/extensions/markdown/pom.xml
index e64462a..5f65e3c 100644
--- a/extensions/markdown/pom.xml
+++ b/extensions/markdown/pom.xml
@@ -32,6 +32,17 @@
 
 	<dependencies>
 
+		<dependency>
+			<groupId>org.apache.isis.core</groupId>
+			<artifactId>isis-metamodel</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.isis.core</groupId>
+			<artifactId>isis-viewer-wicket-ui</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
 		<!-- provides a markdown parser -->
 		<dependency>
 			<groupId>com.vladsch.flexmark</groupId>
diff --git a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java b/extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/Markdown.java
similarity index 74%
copy from extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java
copy to extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/Markdown.java
index b52c59b..8e07194 100644
--- a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDoc.java
+++ b/extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/Markdown.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.asciidoc;
+package org.apache.isis.extensions.markdown;
 
 import org.apache.isis.applib.annotation.Value;
 import org.apache.isis.applib.value.Markup;
@@ -27,11 +27,21 @@ import org.apache.isis.applib.value.Markup;
  */
 @Value(semanticsProviderName = 
         "org.apache.isis.metamodel.facets.value.markup.MarkupValueSemanticsProvider")
-public class AsciiDoc extends Markup {
+public class Markdown extends Markup {
 
     private static final long serialVersionUID = 1L;
     
-    public AsciiDoc(String asciiDoc) {
-        super(AsciiDocConverter.adocToHtml(asciiDoc));
+    public static Markdown valueOfMarkdown(String asciiDoc) {
+        return valueOfHtml(MarkdownConverter.mdToHtml(asciiDoc));
     }
+    
+    public static Markdown valueOfHtml(String html) {
+        return new Markdown(html);
+    }
+    
+    private Markdown(String html) {
+        super(html);
+    }
+     
+    
 }
diff --git a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent.java b/extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/MarkdownComponent.java
similarity index 51%
copy from extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent.java
copy to extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/MarkdownComponent.java
index 87fd21c..18b030e 100644
--- a/extensions/asciidoc/src/main/java/org/apache/isis/extensions/asciidoc/AsciiDocComponent.java
+++ b/extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/MarkdownComponent.java
@@ -16,32 +16,52 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.extensions.asciidoc;
+package org.apache.isis.extensions.markdown;
 
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.MarkupStream;
+import org.apache.wicket.markup.head.CssHeaderItem;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.JavaScriptHeaderItem;
 import org.apache.wicket.model.IModel;
+import org.apache.wicket.request.resource.CssResourceReference;
+import org.apache.wicket.request.resource.JavaScriptResourceReference;
 
+import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent;
+import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponent_reloadJs;
 
 import lombok.val;
 
-public class AsciiDocComponent extends MarkupComponent {
+public class MarkdownComponent extends MarkupComponent {
 
     private static final long serialVersionUID = 1L;
 
-    public AsciiDocComponent(String id, IModel<?> model) {
+    public MarkdownComponent(String id, IModel<?> model) {
         super(id, model, /*observing*/ null);
     }
     
     @Override
     public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
         val htmlContent = extractHtmlOrElse(getDefaultModelObject(), "" /*fallback*/);
-        replaceComponentTagBody(
-                markupStream, 
-                openTag, 
-                AsciiDocComponent_highlightSyntax.decorate(htmlContent)
-                );
+        replaceComponentTagBody(markupStream, openTag, 
+                MarkupComponent_reloadJs.decorate(htmlContent, jsRef.get()));
     }
+    
+    @Override
+    public void renderHead(IHeaderResponse response) {
+        super.renderHead(response);
+        
+        response.render(CssHeaderItem.forReference(
+                new CssResourceReference(MarkdownComponent.class, "css/prism.css")));
+
+        response.render(JavaScriptHeaderItem.forReference(jsRef.get()));
+
+    }
+    
+    // -- HELPER
+    
+    private final static _Lazy<JavaScriptResourceReference> jsRef = _Lazy.threadSafe(()->
+        new JavaScriptResourceReference(MarkdownComponent.class, "js/prism1.14.js"));
 
 }
diff --git a/extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/MarkdownPanelFactoriesForWicket.java b/extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/MarkdownPanelFactoriesForWicket.java
new file mode 100644
index 0000000..fcc3232
--- /dev/null
+++ b/extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/MarkdownPanelFactoriesForWicket.java
@@ -0,0 +1,76 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.extensions.markdown;
+
+import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupComponentFactory;
+import org.apache.isis.viewer.wicket.ui.components.scalars.markup.MarkupPanelFactories;
+
+import lombok.val;
+
+/**
+ * @implNote Almost a copy of {@code Parented} and {@code Standalone} in 
+ * {@link MarkupPanelFactories}, but specific to 
+ * the {@link Markdown} value-type which requires client-side java-script to be
+ * executed to enable syntax highlighting
+ */
+public class MarkdownPanelFactoriesForWicket {
+
+    // -- PARENTED
+
+    public static class Parented extends MarkupPanelFactories.ParentedAbstract {
+        private static final long serialVersionUID = 1L;
+
+        public Parented() {
+            super(Markdown.class);
+        }
+
+        @Override
+        protected MarkupComponentFactory getMarkupComponentFactory() {
+            return (id, model) -> {
+                val markupComponent = new MarkdownComponent(id, model);
+                markupComponent.setEnabled(false);
+                return markupComponent;    
+            };
+
+        }
+
+    }
+
+    // -- STANDALONE
+
+    public static class Standalone extends MarkupPanelFactories.StandaloneAbstract {
+        private static final long serialVersionUID = 1L;
+
+        public Standalone() {
+            super(Markdown.class);
+        }
+
+        @Override
+        protected MarkupComponentFactory getMarkupComponentFactory() {
+            return (id, model) -> {
+                val markupComponent = new MarkdownComponent(id, model);
+                return markupComponent;    
+            };
+        }
+
+    }
+
+
+}
diff --git a/examples/apps/demo/src/main/webapp/css/prism.css b/extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/css/prism.css
similarity index 100%
rename from examples/apps/demo/src/main/webapp/css/prism.css
rename to extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/css/prism.css
diff --git a/extensions/asciidoc/src/main/resources/prism1.14.js b/extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/js/prism1.14.js
similarity index 100%
rename from extensions/asciidoc/src/main/resources/prism1.14.js
rename to extensions/markdown/src/main/java/org/apache/isis/extensions/markdown/js/prism1.14.js
diff --git a/extensions/markdown/src/main/resources/META-INF/services/org.apache.isis.viewer.wicket.ui.ComponentFactory b/extensions/markdown/src/main/resources/META-INF/services/org.apache.isis.viewer.wicket.ui.ComponentFactory
new file mode 100644
index 0000000..5097912
--- /dev/null
+++ b/extensions/markdown/src/main/resources/META-INF/services/org.apache.isis.viewer.wicket.ui.ComponentFactory
@@ -0,0 +1,2 @@
+org.apache.isis.extensions.markdown.MarkdownPanelFactoriesForWicket$Parented
+org.apache.isis.extensions.markdown.MarkdownPanelFactoriesForWicket$Standalone
\ No newline at end of file