update
This commit is contained in:
47
java/markup/AbstractList.java
Normal file
47
java/markup/AbstractList.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public abstract class AbstractList implements ContainsInListItem {
|
||||
|
||||
private final List<ListItem> items;
|
||||
private final String highlight;
|
||||
private final String texBegin;
|
||||
private final String texEnd;
|
||||
|
||||
protected AbstractList(
|
||||
List<ListItem> items,
|
||||
String highlight,
|
||||
String texBegin,
|
||||
String texEnd
|
||||
) {
|
||||
this.items = items;
|
||||
this.highlight = highlight;
|
||||
this.texBegin = texBegin;
|
||||
this.texEnd = texEnd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toHtml(StringBuilder sb) {
|
||||
sb.append("<").append(highlight).append(">");
|
||||
for (ListItem item : items) {
|
||||
item.toHtml(sb);
|
||||
}
|
||||
sb.append("</").append(highlight).append(">");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toMarkdown(StringBuilder sb) {}
|
||||
|
||||
@Override
|
||||
public void toTex(StringBuilder sb) {
|
||||
sb.append(texBegin);
|
||||
for (ListItem item : items) {
|
||||
item.toTex(sb);
|
||||
}
|
||||
sb.append(texEnd);
|
||||
}
|
||||
}
|
||||
66
java/markup/AbstractMarkup.java
Normal file
66
java/markup/AbstractMarkup.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public abstract class AbstractMarkup implements Markdown, Html, Tex {
|
||||
|
||||
protected final List<? extends Markup> items;
|
||||
private final String highlightMarkdown;
|
||||
private final String highlightHtml;
|
||||
private final String highlightTexOpen;
|
||||
private final String highlightTexClose;
|
||||
|
||||
protected AbstractMarkup(
|
||||
List<? extends Markup> items,
|
||||
String highlightMarkdown,
|
||||
String highlightHtml,
|
||||
String highlightTexOpen,
|
||||
String highlightTexClose
|
||||
) {
|
||||
this.items = items;
|
||||
this.highlightMarkdown = highlightMarkdown;
|
||||
this.highlightHtml = highlightHtml;
|
||||
this.highlightTexOpen = highlightTexOpen;
|
||||
this.highlightTexClose = highlightTexClose;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toMarkdown(StringBuilder sb) {
|
||||
sb.append(highlightMarkdown);
|
||||
for (Markup item : items) {
|
||||
item.toMarkdown(sb);
|
||||
}
|
||||
sb.append(highlightMarkdown);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toHtml(StringBuilder sb) {
|
||||
if (!highlightHtml.isEmpty()) {
|
||||
sb.append("<").append(highlightHtml).append(">");
|
||||
}
|
||||
for (Markup item : items) {
|
||||
item.toHtml(sb);
|
||||
}
|
||||
if (!highlightHtml.isEmpty()) {
|
||||
sb.append("</").append(highlightHtml).append(">");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toTex(StringBuilder sb) {
|
||||
sb.append(highlightTexOpen);
|
||||
for (Markup item : items) {
|
||||
if (item instanceof Text) {
|
||||
((Text) item).toTex(sb);
|
||||
} else if (item instanceof AbstractMarkup) {
|
||||
((AbstractMarkup) item).toTex(sb);
|
||||
} else if (item instanceof AbstractList) {
|
||||
((AbstractList) item).toTex(sb);
|
||||
}
|
||||
}
|
||||
sb.append(highlightTexClose);
|
||||
}
|
||||
}
|
||||
6
java/markup/ContainsInListItem.java
Normal file
6
java/markup/ContainsInListItem.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package markup;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public interface ContainsInListItem extends Markup {}
|
||||
13
java/markup/Emphasis.java
Normal file
13
java/markup/Emphasis.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public class Emphasis extends AbstractMarkup implements PartOfParagraph {
|
||||
|
||||
public Emphasis(List<PartOfParagraph> items) {
|
||||
super(items, "*", "em", "\\emph{", "}");
|
||||
}
|
||||
}
|
||||
8
java/markup/Html.java
Normal file
8
java/markup/Html.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package markup;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public interface Html {
|
||||
void toHtml(StringBuilder sb);
|
||||
}
|
||||
13
java/markup/ListItem.java
Normal file
13
java/markup/ListItem.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public class ListItem extends AbstractMarkup implements Markup {
|
||||
|
||||
public ListItem(List<ContainsInListItem> items) {
|
||||
super(items, "", "li", "\\item ", "");
|
||||
}
|
||||
}
|
||||
8
java/markup/Markdown.java
Normal file
8
java/markup/Markdown.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package markup;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public interface Markdown {
|
||||
void toMarkdown(StringBuilder sb);
|
||||
}
|
||||
6
java/markup/Markup.java
Normal file
6
java/markup/Markup.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package markup;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public interface Markup extends Markdown, Html, Tex {}
|
||||
248
java/markup/MarkupListTest.java
Normal file
248
java/markup/MarkupListTest.java
Normal file
File diff suppressed because one or more lines are too long
97
java/markup/MarkupTest.java
Normal file
97
java/markup/MarkupTest.java
Normal file
File diff suppressed because one or more lines are too long
71
java/markup/MarkupTester.java
Normal file
71
java/markup/MarkupTester.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package markup;
|
||||
|
||||
import base.Asserts;
|
||||
import base.BaseChecker;
|
||||
import base.TestCounter;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
|
||||
*/
|
||||
public final class MarkupTester {
|
||||
private final Map<String, String> mapping;
|
||||
private final String toString;
|
||||
|
||||
private MarkupTester(final Map<String, String> mapping, final String toString) {
|
||||
this.mapping = mapping;
|
||||
this.toString = toString;
|
||||
}
|
||||
|
||||
public static Consumer<TestCounter> variant(final Consumer<Checker> checker, final String name, final Map<String, String> mapping) {
|
||||
return counter -> test(checker).accept(new MarkupTester(mapping, "to" + name), counter);
|
||||
}
|
||||
|
||||
public static BiConsumer<MarkupTester, TestCounter> test(final Consumer<Checker> tester) {
|
||||
return (checker, counter) -> tester.accept(checker.new Checker(counter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString;
|
||||
}
|
||||
|
||||
public class Checker extends BaseChecker {
|
||||
public Checker(final TestCounter counter) {
|
||||
super(counter);
|
||||
}
|
||||
|
||||
private <T> MethodHandle findMethod(final T value) {
|
||||
try {
|
||||
return MethodHandles.publicLookup().findVirtual(value.getClass(), toString, MethodType.methodType(void.class, StringBuilder.class));
|
||||
} catch (final NoSuchMethodException | IllegalAccessException e) {
|
||||
throw Asserts.error("Cannot find method 'void %s(StringBuilder)' for %s", toString, value.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void test(final T value, String expectedTemplate) {
|
||||
final MethodHandle method = findMethod(value);
|
||||
for (final Map.Entry<String, String> entry : mapping.entrySet()) {
|
||||
expectedTemplate = expectedTemplate.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
final String expected = expectedTemplate;
|
||||
counter.println("Test " + counter.getTestNo());
|
||||
counter.test(() -> {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
method.invoke(value, sb);
|
||||
} catch (final Throwable e) {
|
||||
throw Asserts.error("%s(StringBuilder) for %s thrown exception: %s", toString, value.getClass(), e);
|
||||
}
|
||||
Asserts.assertEquals("Result", expected, sb.toString());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
13
java/markup/OrderedList.java
Normal file
13
java/markup/OrderedList.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public class OrderedList extends AbstractList {
|
||||
|
||||
public OrderedList(List<ListItem> items) {
|
||||
super(items, "ol", "\\begin{enumerate}", "\\end{enumerate}");
|
||||
}
|
||||
}
|
||||
16
java/markup/Paragraph.java
Normal file
16
java/markup/Paragraph.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public class Paragraph
|
||||
extends AbstractMarkup
|
||||
implements ContainsInListItem, PrimePart
|
||||
{
|
||||
|
||||
public Paragraph(List<PartOfParagraph> items) {
|
||||
super(items, "", "p", "\\par{}", "");
|
||||
}
|
||||
}
|
||||
6
java/markup/PartOfParagraph.java
Normal file
6
java/markup/PartOfParagraph.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package markup;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public interface PartOfParagraph extends Markup {}
|
||||
6
java/markup/PrimePart.java
Normal file
6
java/markup/PrimePart.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package markup;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public interface PrimePart extends Markup {}
|
||||
13
java/markup/Strikeout.java
Normal file
13
java/markup/Strikeout.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public class Strikeout extends AbstractMarkup implements PartOfParagraph {
|
||||
|
||||
public Strikeout(List<PartOfParagraph> items) {
|
||||
super(items, "~", "s", "\\textst{", "}");
|
||||
}
|
||||
}
|
||||
13
java/markup/Strong.java
Normal file
13
java/markup/Strong.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public class Strong extends AbstractMarkup implements PartOfParagraph {
|
||||
|
||||
public Strong(List<PartOfParagraph> items) {
|
||||
super(items, "__", "strong", "\\textbf{", "}");
|
||||
}
|
||||
}
|
||||
8
java/markup/Tex.java
Normal file
8
java/markup/Tex.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package markup;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public interface Tex {
|
||||
void toTex(StringBuilder sb);
|
||||
}
|
||||
27
java/markup/Text.java
Normal file
27
java/markup/Text.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package markup;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public class Text implements PartOfParagraph {
|
||||
|
||||
private final String text;
|
||||
|
||||
public Text(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toHtml(StringBuilder sb) {
|
||||
sb.append(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toMarkdown(StringBuilder sb) {
|
||||
sb.append(text);
|
||||
}
|
||||
|
||||
public void toTex(StringBuilder sb) {
|
||||
sb.append(text);
|
||||
}
|
||||
}
|
||||
13
java/markup/UnorderedList.java
Normal file
13
java/markup/UnorderedList.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Nikita Doschennikov (me@fymio.us)
|
||||
*/
|
||||
public class UnorderedList extends AbstractList {
|
||||
|
||||
public UnorderedList(List<ListItem> items) {
|
||||
super(items, "ul", "\\begin{itemize}", "\\end{itemize}");
|
||||
}
|
||||
}
|
||||
BIN
java/markup/assets/diagram.png
Normal file
BIN
java/markup/assets/diagram.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 MiB |
1
java/markup/assets/diagram.svg
Normal file
1
java/markup/assets/diagram.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 88 KiB |
157
java/markup/assets/mermaid/diagram.mmd
Normal file
157
java/markup/assets/mermaid/diagram.mmd
Normal file
@@ -0,0 +1,157 @@
|
||||
classDiagram
|
||||
%% Интерфейсы
|
||||
class Markdown {
|
||||
<<interface>>
|
||||
+toMarkdown(StringBuilder)
|
||||
}
|
||||
|
||||
class Html {
|
||||
<<interface>>
|
||||
+toHtml(StringBuilder)
|
||||
}
|
||||
|
||||
class Markup {
|
||||
<<interface>>
|
||||
+toMarkdown(StringBuilder)
|
||||
+toHtml(StringBuilder)
|
||||
}
|
||||
|
||||
class PartOfParagraph {
|
||||
<<interface>>
|
||||
+toMarkdown(StringBuilder)
|
||||
+toHtml(StringBuilder)
|
||||
}
|
||||
|
||||
class ContainsInListItem {
|
||||
<<interface>>
|
||||
+toMarkdown(StringBuilder)
|
||||
+toHtml(StringBuilder)
|
||||
}
|
||||
|
||||
class PrimePart {
|
||||
<<interface>>
|
||||
+toMarkdown(StringBuilder)
|
||||
+toHtml(StringBuilder)
|
||||
}
|
||||
|
||||
%% Наследование интерфейсов
|
||||
Markup --|> Markdown
|
||||
Markup --|> Html
|
||||
PartOfParagraph --|> Markup
|
||||
ContainsInListItem --|> Markup
|
||||
PrimePart --|> Markup
|
||||
|
||||
%% Абстрактные классы
|
||||
class AbstractMarkup {
|
||||
<<abstract>>
|
||||
#List~Markup~ items
|
||||
-String highlightMarkdown
|
||||
-String highlightHtml
|
||||
-String highlightTexOpen
|
||||
-String highlightTexClose
|
||||
+AbstractMarkup(List, String, String, String, String)
|
||||
+toMarkdown(StringBuilder)
|
||||
+toHtml(StringBuilder)
|
||||
+toTex(StringBuilder)
|
||||
}
|
||||
|
||||
class AbstractList {
|
||||
<<abstract>>
|
||||
-List~ListItem~ items
|
||||
-String highlight
|
||||
-String texBegin
|
||||
-String texEnd
|
||||
+AbstractList(List, String, String, String)
|
||||
+toHtml(StringBuilder)
|
||||
+toMarkdown(StringBuilder)
|
||||
+toTex(StringBuilder)
|
||||
}
|
||||
|
||||
%% Абстрактные классы реализуют интерфейсы
|
||||
AbstractMarkup ..|> Markdown
|
||||
AbstractMarkup ..|> Html
|
||||
AbstractList ..|> ContainsInListItem
|
||||
|
||||
%% Inline элементы
|
||||
class Text {
|
||||
-String text
|
||||
+Text(String)
|
||||
+toMarkdown(StringBuilder)
|
||||
+toHtml(StringBuilder)
|
||||
+toTex(StringBuilder)
|
||||
}
|
||||
|
||||
class Emphasis {
|
||||
+Emphasis(List~PartOfParagraph~)
|
||||
}
|
||||
|
||||
class Strong {
|
||||
+Strong(List~PartOfParagraph~)
|
||||
}
|
||||
|
||||
class Strikeout {
|
||||
+Strikeout(List~PartOfParagraph~)
|
||||
}
|
||||
|
||||
%% Inline элементы наследуются и реализуют
|
||||
Text ..|> PartOfParagraph
|
||||
Emphasis --|> AbstractMarkup
|
||||
Emphasis ..|> PartOfParagraph
|
||||
Strong --|> AbstractMarkup
|
||||
Strong ..|> PartOfParagraph
|
||||
Strikeout --|> AbstractMarkup
|
||||
Strikeout ..|> PartOfParagraph
|
||||
|
||||
%% Paragraph
|
||||
class Paragraph {
|
||||
+Paragraph(List~PartOfParagraph~)
|
||||
}
|
||||
|
||||
Paragraph --|> AbstractMarkup
|
||||
Paragraph ..|> ContainsInListItem
|
||||
Paragraph ..|> PrimePart
|
||||
|
||||
%% Списки
|
||||
class OrderedList {
|
||||
+OrderedList(List~ListItem~)
|
||||
}
|
||||
|
||||
class UnorderedList {
|
||||
+UnorderedList(List~ListItem~)
|
||||
}
|
||||
|
||||
class ListItem {
|
||||
+ListItem(List~ContainsInListItem~)
|
||||
}
|
||||
|
||||
OrderedList --|> AbstractList
|
||||
UnorderedList --|> AbstractList
|
||||
ListItem --|> AbstractMarkup
|
||||
ListItem ..|> Markup
|
||||
|
||||
%% Зависимости (что может содержать что)
|
||||
AbstractMarkup o-- Markup : contains
|
||||
AbstractList o-- ListItem : contains
|
||||
Emphasis o-- PartOfParagraph : contains
|
||||
Strong o-- PartOfParagraph : contains
|
||||
Strikeout o-- PartOfParagraph : contains
|
||||
Paragraph o-- PartOfParagraph : contains
|
||||
ListItem o-- ContainsInListItem : contains
|
||||
|
||||
%% Стили
|
||||
style Markdown fill:#e1f5ff
|
||||
style Html fill:#e1f5ff
|
||||
style Markup fill:#e1f5ff
|
||||
style PartOfParagraph fill:#fff4e1
|
||||
style ContainsInListItem fill:#fff4e1
|
||||
style PrimePart fill:#fff4e1
|
||||
style AbstractMarkup fill:#ffe1f5
|
||||
style AbstractList fill:#ffe1f5
|
||||
style Text fill:#e1ffe1
|
||||
style Emphasis fill:#e1ffe1
|
||||
style Strong fill:#e1ffe1
|
||||
style Strikeout fill:#e1ffe1
|
||||
style Paragraph fill:#ffe1e1
|
||||
style OrderedList fill:#f5e1ff
|
||||
style UnorderedList fill:#f5e1ff
|
||||
style ListItem fill:#f5e1ff
|
||||
7
java/markup/package-info.java
Normal file
7
java/markup/package-info.java
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Tests for <a href="https://www.kgeorgiy.info/courses/prog-intro/homeworks.html#markup">Markup</a> homework
|
||||
* of <a href="https://www.kgeorgiy.info/courses/prog-intro/">Introduction to Programming</a> course.
|
||||
*
|
||||
* @author Georgiy Korneev (kgeorgiy@kgeorgiy.info)
|
||||
*/
|
||||
package markup;
|
||||
Reference in New Issue
Block a user