Upload files to "java/md2html"
This commit is contained in:
390
java/md2html/PrimePartCreator.java
Normal file
390
java/md2html/PrimePartCreator.java
Normal file
@@ -0,0 +1,390 @@
|
||||
package md2html;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import markup.*;
|
||||
|
||||
public class PrimePartCreator {
|
||||
|
||||
private final String block;
|
||||
private int currentChar;
|
||||
|
||||
public enum MarkdownToken {
|
||||
WORD,
|
||||
EMPHASIS_STAR,
|
||||
STRONG_STAR,
|
||||
EMPHASIS_UNDERLINE,
|
||||
STRONG_UNDERLINE,
|
||||
STRIKEOUT,
|
||||
CODE,
|
||||
SCREENING,
|
||||
VAR,
|
||||
SAMP,
|
||||
INS,
|
||||
DEL,
|
||||
PRE,
|
||||
NOTHING,
|
||||
}
|
||||
|
||||
public PrimePartCreator(String block) {
|
||||
this.block = block;
|
||||
currentChar = 0;
|
||||
}
|
||||
|
||||
public PrimePart createPart() {
|
||||
PrimePart result;
|
||||
if (isHeader()) {
|
||||
int levelOfHeader = 0;
|
||||
while (
|
||||
levelOfHeader < block.length() &&
|
||||
block.charAt(levelOfHeader) == '#'
|
||||
) {
|
||||
levelOfHeader++;
|
||||
}
|
||||
currentChar = levelOfHeader + 1;
|
||||
result = new Header(buildPart(MarkdownToken.WORD), levelOfHeader);
|
||||
} else {
|
||||
currentChar = 0;
|
||||
result = new Paragraph(buildPart(MarkdownToken.WORD));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<PartOfParagraph> buildPart(MarkdownToken currentToken) {
|
||||
List<PartOfParagraph> items = new ArrayList<>();
|
||||
MarkdownToken token = nextMarkdownToken();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (token != MarkdownToken.NOTHING) {
|
||||
if (
|
||||
(token == currentToken && currentToken != MarkdownToken.WORD) ||
|
||||
(token != MarkdownToken.SCREENING && isSuffix(currentToken))
|
||||
) {
|
||||
addToList(items, sb);
|
||||
if (
|
||||
!(token == currentToken &&
|
||||
currentToken != MarkdownToken.WORD)
|
||||
) {
|
||||
currentChar++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (token) {
|
||||
case STRIKEOUT -> {
|
||||
addToList(items, sb);
|
||||
Strikeout strikeout = new Strikeout(buildPart(token));
|
||||
items.add(strikeout);
|
||||
}
|
||||
case STRONG_STAR, STRONG_UNDERLINE -> {
|
||||
addToList(items, sb);
|
||||
Strong strong = new Strong(buildPart(token));
|
||||
items.add(strong);
|
||||
}
|
||||
case EMPHASIS_STAR, EMPHASIS_UNDERLINE -> {
|
||||
addToList(items, sb);
|
||||
Emphasis emphasis = new Emphasis(buildPart(token));
|
||||
items.add(emphasis);
|
||||
}
|
||||
case SCREENING -> {
|
||||
addToList(items, sb);
|
||||
char ch = block.charAt(currentChar);
|
||||
if (ch == '<') {
|
||||
sb.append("<");
|
||||
} else if (ch == '>') {
|
||||
sb.append(">");
|
||||
} else if (ch == '&') {
|
||||
sb.append("&");
|
||||
} else {
|
||||
sb.append(ch);
|
||||
}
|
||||
currentChar++;
|
||||
}
|
||||
case CODE -> {
|
||||
addToList(items, sb);
|
||||
Code code = new Code(buildPart(token));
|
||||
items.add(code);
|
||||
}
|
||||
case VAR -> {
|
||||
addToList(items, sb);
|
||||
Var var = new Var(buildPart(token));
|
||||
items.add(var);
|
||||
}
|
||||
case SAMP -> {
|
||||
addToList(items, sb);
|
||||
Samp samp = new Samp(buildPart(token));
|
||||
items.add(samp);
|
||||
}
|
||||
case INS -> {
|
||||
addToList(items, sb);
|
||||
Ins ins = new Ins(buildPart(token));
|
||||
items.add(ins);
|
||||
}
|
||||
case DEL -> {
|
||||
addToList(items, sb);
|
||||
Del del = new Del(buildPart(token));
|
||||
items.add(del);
|
||||
}
|
||||
case PRE -> {
|
||||
addToList(items, sb);
|
||||
|
||||
StringBuilder raw = new StringBuilder();
|
||||
while (currentChar < block.length()) {
|
||||
if (
|
||||
isWordInBlock("```", currentChar, currentChar + 3)
|
||||
) {
|
||||
currentChar += 3;
|
||||
break;
|
||||
}
|
||||
char ch = block.charAt(currentChar);
|
||||
if (ch == '<') {
|
||||
raw.append("<");
|
||||
} else if (ch == '>') {
|
||||
} else if (ch == '&') {
|
||||
raw.append("&");
|
||||
} else {
|
||||
raw.append(ch);
|
||||
}
|
||||
currentChar++;
|
||||
}
|
||||
items.add(new Pre(List.of(new Text(raw.toString()))));
|
||||
}
|
||||
default -> {
|
||||
if (currentChar < block.length()) {
|
||||
if (block.charAt(currentChar) == '<') {
|
||||
sb.append("<");
|
||||
} else if (block.charAt(currentChar) == '>') {
|
||||
sb.append(">");
|
||||
} else if (block.charAt(currentChar) == '&') {
|
||||
sb.append("&");
|
||||
} else {
|
||||
sb.append(block.charAt(currentChar));
|
||||
}
|
||||
currentChar++;
|
||||
}
|
||||
}
|
||||
}
|
||||
token = nextMarkdownToken();
|
||||
}
|
||||
if (token == MarkdownToken.NOTHING) {
|
||||
addToList(items, sb);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private MarkdownToken nextMarkdownToken() {
|
||||
if (currentChar == block.length()) {
|
||||
return MarkdownToken.NOTHING;
|
||||
}
|
||||
switch (block.charAt(currentChar)) {
|
||||
case '*' -> {
|
||||
if (isPrefix("**")) {
|
||||
currentChar += 2;
|
||||
return MarkdownToken.STRONG_STAR;
|
||||
} else if (isPrefix("*")) {
|
||||
currentChar += 1;
|
||||
return MarkdownToken.EMPHASIS_STAR;
|
||||
}
|
||||
}
|
||||
case '_' -> {
|
||||
if (isPrefix("__")) {
|
||||
currentChar += 2;
|
||||
return MarkdownToken.STRONG_UNDERLINE;
|
||||
} else if (isPrefix("_")) {
|
||||
currentChar += 1;
|
||||
return MarkdownToken.EMPHASIS_UNDERLINE;
|
||||
}
|
||||
}
|
||||
case '-' -> {
|
||||
if (isPrefix("--")) {
|
||||
currentChar += 2;
|
||||
return MarkdownToken.STRIKEOUT;
|
||||
}
|
||||
}
|
||||
case '`' -> {
|
||||
if (
|
||||
isWordInBlock("```", currentChar, currentChar + 3) &&
|
||||
hasClosing("```", currentChar + 3)
|
||||
) {
|
||||
currentChar += 3;
|
||||
return MarkdownToken.PRE;
|
||||
} else if (hasClosing("`", currentChar + 1)) {
|
||||
currentChar += 1;
|
||||
return MarkdownToken.CODE;
|
||||
}
|
||||
}
|
||||
case '\\' -> {
|
||||
if (isScreening(block.charAt(currentChar + 1))) {
|
||||
currentChar++;
|
||||
return MarkdownToken.SCREENING;
|
||||
}
|
||||
}
|
||||
case '%' -> {
|
||||
if (isPrefix("%") && hasClosing("%", currentChar + 1)) {
|
||||
currentChar += 1;
|
||||
return MarkdownToken.VAR;
|
||||
}
|
||||
}
|
||||
case '!' -> {
|
||||
if (isPrefix("!!") && hasClosing("!!", currentChar + 2)) {
|
||||
currentChar += 2;
|
||||
return MarkdownToken.SAMP;
|
||||
}
|
||||
}
|
||||
case '<' -> {
|
||||
if (
|
||||
isWordInBlock("<<", currentChar, currentChar + 2) &&
|
||||
hasClosing(">>", currentChar + 2)
|
||||
) {
|
||||
currentChar += 2;
|
||||
return MarkdownToken.INS;
|
||||
}
|
||||
}
|
||||
case '}' -> {
|
||||
if (
|
||||
isWordInBlock("}}", currentChar, currentChar + 2) &&
|
||||
hasClosing("{{", currentChar + 2)
|
||||
) {
|
||||
currentChar += 2;
|
||||
return MarkdownToken.DEL;
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
return MarkdownToken.WORD;
|
||||
}
|
||||
}
|
||||
return MarkdownToken.WORD;
|
||||
}
|
||||
|
||||
private boolean hasClosing(String delimiter, int from) {
|
||||
for (int j = from; j + delimiter.length() <= block.length(); j++) {
|
||||
if (isWordInBlock(delimiter, j, j + delimiter.length())) {
|
||||
if (j > 0 && block.charAt(j - 1) == '\\') {
|
||||
continue;
|
||||
}
|
||||
if (delimiter.equals("`")) {
|
||||
if (isWordInBlock("```", j, j + 3)) continue;
|
||||
if (j >= 1 && isWordInBlock("```", j - 1, j + 2)) continue;
|
||||
if (j >= 2 && isWordInBlock("```", j - 2, j + 1)) continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isScreening(char ch) {
|
||||
return (
|
||||
ch == '*' ||
|
||||
ch == '_' ||
|
||||
ch == '%' ||
|
||||
ch == '!' ||
|
||||
ch == '<' ||
|
||||
ch == '>' ||
|
||||
ch == '}' ||
|
||||
ch == '{' ||
|
||||
ch == '`'
|
||||
);
|
||||
}
|
||||
|
||||
private boolean isSuffix(MarkdownToken token) {
|
||||
if (token == MarkdownToken.WORD) {
|
||||
return false;
|
||||
}
|
||||
String suffix = getHighlight(token);
|
||||
if (isWordInBlock(suffix, currentChar, currentChar + suffix.length())) {
|
||||
currentChar += suffix.length() - 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isPrefix(String prefix) {
|
||||
int i = currentChar + prefix.length();
|
||||
return (
|
||||
isValidIndexInBlock(i + prefix.length()) &&
|
||||
!isWordInBlock(prefix, i, i + prefix.length()) &&
|
||||
isWordInBlock(prefix, i - prefix.length(), i) &&
|
||||
!Character.isWhitespace(block.charAt(i))
|
||||
);
|
||||
}
|
||||
|
||||
private boolean isWordInBlock(String word, int start, int end) {
|
||||
if (end > block.length() || start < 0) {
|
||||
return false;
|
||||
}
|
||||
return block.regionMatches(start, word, 0, word.length());
|
||||
}
|
||||
|
||||
private boolean isValidIndexInBlock(int index) {
|
||||
return index < block.length();
|
||||
}
|
||||
|
||||
private boolean isHeader() {
|
||||
int levelOfHeader = 0;
|
||||
if (block.charAt(levelOfHeader) != '#') {
|
||||
return false;
|
||||
}
|
||||
while (
|
||||
levelOfHeader < block.length() && block.charAt(levelOfHeader) == '#'
|
||||
) {
|
||||
levelOfHeader++;
|
||||
}
|
||||
return (
|
||||
levelOfHeader < block.length() &&
|
||||
Character.isWhitespace(block.charAt(levelOfHeader))
|
||||
);
|
||||
}
|
||||
|
||||
private static String getHighlight(MarkdownToken token) {
|
||||
switch (token) {
|
||||
case STRONG_STAR -> {
|
||||
return "**";
|
||||
}
|
||||
case STRONG_UNDERLINE -> {
|
||||
return "__";
|
||||
}
|
||||
case EMPHASIS_STAR -> {
|
||||
return "*";
|
||||
}
|
||||
case EMPHASIS_UNDERLINE -> {
|
||||
return "_";
|
||||
}
|
||||
case CODE -> {
|
||||
return "`";
|
||||
}
|
||||
case STRIKEOUT -> {
|
||||
return "--";
|
||||
}
|
||||
case SCREENING -> {
|
||||
return "\\";
|
||||
}
|
||||
case VAR -> {
|
||||
return "%";
|
||||
}
|
||||
case SAMP -> {
|
||||
return "!!";
|
||||
}
|
||||
case INS -> {
|
||||
return ">>";
|
||||
}
|
||||
case DEL -> {
|
||||
return "{{";
|
||||
}
|
||||
case PRE -> {
|
||||
return "```";
|
||||
}
|
||||
default -> {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addToList(
|
||||
List<PartOfParagraph> items,
|
||||
StringBuilder sb
|
||||
) {
|
||||
if (!sb.isEmpty()) {
|
||||
items.add(new Text(sb.toString()));
|
||||
sb.setLength(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
java/md2html/Samp.java
Normal file
11
java/md2html/Samp.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package md2html;
|
||||
|
||||
import java.util.List;
|
||||
import markup.*;
|
||||
|
||||
public class Samp extends AbstractMarkup implements PartOfParagraph {
|
||||
|
||||
public Samp(List<PartOfParagraph> items) {
|
||||
super(items, "!!", "samp", "", "");
|
||||
}
|
||||
}
|
||||
11
java/md2html/Var.java
Normal file
11
java/md2html/Var.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package md2html;
|
||||
|
||||
import java.util.List;
|
||||
import markup.*;
|
||||
|
||||
public class Var extends AbstractMarkup implements PartOfParagraph {
|
||||
|
||||
public Var(List<PartOfParagraph> items) {
|
||||
super(items, "%", "var", "", "");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user