Criando uma extensão flexmark em Clojure

clartaq:

Eu estou tentando escrever uma pequena extensão para flexmark . Eu quero criar um costume AttributeProvidere estou tentando trabalhar com o exemplo mostrado aqui .

Meu problema é traduzir duas classes em Clojure.

Eu separei as duas classes exemplo relevante em arquivos de origem Java separados e traduziu o programa de demonstração em um teste Clojure.

O SampleAttributeProviderJava:

package cwiki.util;

import com.vladsch.flexmark.ast.Link;
import com.vladsch.flexmark.ast.Node;
import com.vladsch.flexmark.html.AttributeProvider;
import com.vladsch.flexmark.html.AttributeProviderFactory;
import com.vladsch.flexmark.html.IndependentAttributeProviderFactory;
import com.vladsch.flexmark.html.renderer.AttributablePart;
import com.vladsch.flexmark.html.renderer.LinkResolverContext;
import com.vladsch.flexmark.util.html.Attributes;

class SampleAttributeProvider implements AttributeProvider {
    @Override
    public void setAttributes(final Node node, final AttributablePart part, final Attributes attributes) {
        if (node instanceof Link && part == AttributablePart.LINK) {
            Link link = (Link) node;

            if (link.getText().equals("...")) {
                attributes.replaceValue("target", "_top");
            }
        }
    }

    static AttributeProviderFactory Factory() {
        return new IndependentAttributeProviderFactory() {
            @Override
            public AttributeProvider create(LinkResolverContext context) {
                //noinspection ReturnOfInnerClass
                return new SampleAttributeProvider();
            }
        };
    }
}

O SampleExtensionem Java.

package cwiki.util;

import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.util.options.MutableDataHolder;

public class SampleExtension implements HtmlRenderer.HtmlRendererExtension {
    @Override
    public void rendererOptions(final MutableDataHolder options) {
        // add any configuration settings to options you want to apply to everything, here
    }

    @Override
    public void extend(final HtmlRenderer.Builder rendererBuilder, final String rendererType) {
        rendererBuilder.attributeProviderFactory(cwiki.util.SampleAttributeProvider.Factory());
    }

    public static SampleExtension create() {
        return new SampleExtension();
    }
}

Traduzindo o programa demonstraton no exemplo é simples. O arquivo de teste em Clojure:

(ns cwiki.test.util.CWikiAttributeProviderTest
  (:require [clojure.test :refer :all])
  (:import (com.vladsch.flexmark.util.options MutableDataSet)
           (com.vladsch.flexmark.parser Parser Parser$Builder)
           (com.vladsch.flexmark.html HtmlRenderer HtmlRenderer$Builder)
           (cwiki.util SampleExtension)
           (java.util ArrayList)))

(defn commonmark
  [markdown]
  (let [options (-> (MutableDataSet.)
                    (.set Parser/EXTENSIONS
                          (ArrayList. [(SampleExtension/create)]))
                    (.set HtmlRenderer/SOFT_BREAK "<br/>"))
        parser (.build ^Parser$Builder (Parser/builder options))
        document (.parse ^Parser parser ^String markdown)
        renderer (.build ^HtmlRenderer$Builder (HtmlRenderer/builder options))]
    (.render renderer document)))

(deftest cwiki-attribute-provider-test
  (testing "The ability of the CWikiAttributeProvider to place the correct attributes in wikilinks."
    (let [test-output (commonmark "[...](http://github.com/vsch/flexmark-java)")]
      (is (= test-output
             "<p><a href=\"http://github.com/vsch/flexmark-java\" target=\"_top\">...</a></p>\n")))))

Os ensaios e as passagens utilizando as duas classes Java acima.

Eu tenho sido capaz de traduzir o SampleAttributeProviderque Clojure. Ele compila e produz arquivos de classe. Eu não tenho sido capaz de realmente funcionar e testá-lo porque ...

Estou tendo problemas traduzindo a classe de extensão a partir do exemplo. Aqui está o que eu vim acima com a medida. (Os nomes das classes foram alterados para colisões a evitar.):

(ns cwiki.util.CWikiAttributeProviderExtension
  (:gen-class
    :implements [com.vladsch.flexmark.html.HtmlRenderer$HtmlRendererExtension]
    :methods [^:static [create [] cwiki.util.CWikiAttributeProviderExtension]])
  (:import (com.vladsch.flexmark.html HtmlRenderer$Builder)
           (com.vladsch.flexmark.util.options MutableDataHolder)
           (cwiki.util CWikiAttributeProvider CWikiAttributeProviderExtension)))

(defn -rendererOptions
  [this ^MutableDataHolder options]
  ; Add any configuration option that you want to apply to everything here.
  )

(defn -extend
  [this ^HtmlRenderer$Builder rendererBuilder ^String rendererType]
  (.attributeProviderFactory rendererBuilder (CWikiAttributeProvider.)))

(defn ^CWikiAttributeProviderExtension -create [this]
  (CWikiAttributeProviderExtension.))

A tentativa de compilar este com $ lein compile CWikiAttributeProviderExtension, produz uma mensagem de partida erro com:

Compiling cwiki.util.CWikiAttributeProviderExtension
java.lang.ClassNotFoundException: cwiki.util.CWikiAttributeProviderExtension, compiling:(cwiki/util/CWikiAttributeProviderExtension.clj:1:1)
Exception in thread "main" java.lang.ClassNotFoundException: cwiki.util.CWikiAttributeProviderExtension, compiling:(cwiki/util/CWikiAttributeProviderExtension.clj:1:1)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:7010)
        at clojure.lang.Compiler.analyze(Compiler.java:6773)
        at clojure.lang.Compiler.analyze(Compiler.java:6729)
        at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:6100)
        at clojure.lang.Compiler$TryExpr$Parser.parse(Compiler.java:2307)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:7003)
 ...   

O IDE (Cursive no IntelliJ) mostra uma mensagem de aviso sobre não ser capaz de resolver o createmétodo na :gen-classseção, mas eu não consigo ver nada de errado com a declaração ou implementação. Esta tradução é semelhante ao que eu usei anteriormente em outros programas para construir uma classe Java que adiciona um método a um objeto que estende uma interface Java. É semelhante ao que eu usei para criar a outra classe relevante no exemplo. Mas, claramente, algo está errado.

A tentativa de usar apenas o traduzida CWikiAttributeProvidersem traduzir a classe de extensão faz com que a cadeia de ferramentas para se confuso sobre a primeira compilação de um objeto em Clojure, então as partes de Java, então o resto do programa Clojure. Assim, parece que deve traduzir ambas as classes de uma vez ou não em todos.

Apenas para completar, aqui é a classe de provedor atributo traduzido em Clojure.

(ns cwiki.util.CWikiAttributeProvider
  (:gen-class
    :implements [com.vladsch.flexmark.html.AttributeProvider]
    :methods [^:static [Factory [] com.vladsch.flexmark.html.AttributeProviderFactory]])
  (:import (com.vladsch.flexmark.ast Node Link)
           (com.vladsch.flexmark.html AttributeProviderFactory
                                      IndependentAttributeProviderFactory)
           (com.vladsch.flexmark.html.renderer AttributablePart
                                               LinkResolverContext)
           (com.vladsch.flexmark.util.html Attributes)
           (cwiki.util CWikiAttributeProvider)))

(defn -setAttributes
  [this ^Node node ^AttributablePart part ^Attributes attributes]
  (when (and (= (type node) Link) (= part AttributablePart/LINK))
    (let [title (.getText ^Link node)]
      (println "node: " node)
      (println "title: " title)
      (when (= title "...")
        (.replaceValue attributes "target" "_top")))))

(defn ^AttributeProviderFactory -Factory [this]
  (proxy [IndependentAttributeProviderFactory] []
    (create [^LinkResolverContext context]
      ;; noinspection ReturnOfInnerClass
      (CWikiAttributeProvider.))))
Vanhala Toni:

Você precisa de uma declaração para a frente para a CWikiAttributeProvidercomo um valor de retorno em gen-class. Declarar a classe em duas etapas , na parte superior do seu arquivo: 1) com apenas os construtores, e 2) com uma declaração completa, incluindo) métodos (estáticos e estado.

(gen-class
  :name cwiki.util.CWikiAttributeProviderExtension
  :implements [com.vladsch.flexmark.html.HtmlRenderer$HtmlRendererExtension])

(gen-class
  :name cwiki.util.CWikiAttributeProviderExtension
  :implements [com.vladsch.flexmark.html.HtmlRenderer$HtmlRendererExtension]
  :methods (^:static [create [] cwiki.util.CWikiAttributeProviderExtension]))

Eu era capaz de compilar o exemplo, usando estas gen-classdeclarações, e alterações posteriores:

  • removendo a própria classe de declarações de importação,
  • referindo-se à classe pelo seu nome completo ( cwiki.util.CWikiAttributeProvider) em implementações do método e do tipo dicas, e
  • remoção thisde referência do método estático (para coincidir com a declaração gen-classe para o método).

Note também que você precisa para compilar a classe frente-of-time (AOT) quando usá-lo em um projeto.

Acho que você gosta

Origin http://43.154.161.224:23101/article/api/json?id=218745&siteId=1
Recomendado
Clasificación