added lost Strikeout file
Some checks failed
Fast Reverse Tests / test (push) Successful in 1m32s
Markup Tests / test (push) Successful in 17s
Reverse Tests / test (push) Successful in 25s
Sum Tests / test (push) Successful in 27s
Word Stat Tests / test (push) Successful in 25s
Word Stat++ Tests / test (push) Failing after 37s
Some checks failed
Fast Reverse Tests / test (push) Successful in 1m32s
Markup Tests / test (push) Successful in 17s
Reverse Tests / test (push) Successful in 25s
Sum Tests / test (push) Successful in 27s
Word Stat Tests / test (push) Successful in 25s
Word Stat++ Tests / test (push) Failing after 37s
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,4 @@
|
||||
*.xml
|
||||
java/out/
|
||||
java/out/*
|
||||
*.iml
|
||||
*.idea*
|
||||
*out*
|
||||
|
||||
24
java/markup/Strikeout.java
Normal file
24
java/markup/Strikeout.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package markup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Strikeout extends AbstractMarkup {
|
||||
public Strikeout(List<MarkupElement> elements) {
|
||||
super(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toMarkdown(StringBuilder sb) {
|
||||
toMarkdown(sb, "~");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toHtml(StringBuilder sb) {
|
||||
toHtml(sb, "s");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toTex(StringBuilder sb) {
|
||||
toTex(sb, "\\textst");
|
||||
}
|
||||
}
|
||||
146
java/md2html/Md2Html.java
Normal file
146
java/md2html/Md2Html.java
Normal file
@@ -0,0 +1,146 @@
|
||||
package md2html;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public class Md2Html {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args == null || args.length < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
try (
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(new FileInputStream(args[0]), StandardCharsets.UTF_8));
|
||||
BufferedWriter writer = new BufferedWriter(
|
||||
new OutputStreamWriter(new FileOutputStream(args[1]), StandardCharsets.UTF_8))
|
||||
) {
|
||||
List<String> blocks = readBlocks(reader);
|
||||
for (String block : blocks) {
|
||||
writer.write(convertBlock(block));
|
||||
writer.newLine();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// по условию обычно можно игнорировать или просто завершить
|
||||
}
|
||||
}
|
||||
|
||||
private static List<String> readBlocks(BufferedReader reader) throws IOException {
|
||||
List<String> blocks = new ArrayList<>();
|
||||
StringBuilder current = new StringBuilder();
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.isEmpty()) {
|
||||
if (!current.isEmpty()) {
|
||||
blocks.add(current.toString());
|
||||
current.setLength(0);
|
||||
}
|
||||
} else {
|
||||
if (!current.isEmpty()) {
|
||||
current.append('\n');
|
||||
}
|
||||
current.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
if (!current.isEmpty()) {
|
||||
blocks.add(current.toString());
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
||||
private static String convertBlock(String block) {
|
||||
int level = countHeaderLevel(block);
|
||||
|
||||
if (level > 0) {
|
||||
String content = block.substring(level + 1);
|
||||
return "<h" + level + ">" + parseInline(content) + "</h" + level + ">";
|
||||
} else {
|
||||
return "<p>" + parseInline(block) + "</p>";
|
||||
}
|
||||
}
|
||||
|
||||
private static int countHeaderLevel(String block) {
|
||||
int i = 0;
|
||||
while (i < block.length() && block.charAt(i) == '#') {
|
||||
i++;
|
||||
}
|
||||
if (i > 0 && i <= 6 && i < block.length() && block.charAt(i) == ' ') {
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static String parseInline(String text) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
Deque<String> stack = new ArrayDeque<>();
|
||||
|
||||
Map<String, String> tags = Map.of(
|
||||
"*", "em",
|
||||
"_", "em",
|
||||
"**", "strong",
|
||||
"__", "strong",
|
||||
"--", "s",
|
||||
"`", "code"
|
||||
);
|
||||
|
||||
for (int i = 0; i < text.length(); ) {
|
||||
|
||||
// escape
|
||||
if (text.charAt(i) == '\\' && i + 1 < text.length()) {
|
||||
result.append(escapeHtml(text.charAt(i + 1)));
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check double markers first
|
||||
if (i + 1 < text.length()) {
|
||||
String two = text.substring(i, i + 2);
|
||||
if (tags.containsKey(two)) {
|
||||
if (!stack.isEmpty() && stack.peek().equals(two)) {
|
||||
result.append("</").append(tags.get(two)).append(">");
|
||||
stack.pop();
|
||||
} else {
|
||||
result.append("<").append(tags.get(two)).append(">");
|
||||
stack.push(two);
|
||||
}
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// single markers
|
||||
String one = String.valueOf(text.charAt(i));
|
||||
if (tags.containsKey(one)) {
|
||||
if (!stack.isEmpty() && stack.peek().equals(one)) {
|
||||
result.append("</").append(tags.get(one)).append(">");
|
||||
stack.pop();
|
||||
} else {
|
||||
result.append("<").append(tags.get(one)).append(">");
|
||||
stack.push(one);
|
||||
}
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// normal char
|
||||
result.append(escapeHtml(text.charAt(i)));
|
||||
i++;
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static String escapeHtml(char c) {
|
||||
return switch (c) {
|
||||
case '<' -> "<";
|
||||
case '>' -> ">";
|
||||
case '&' -> "&";
|
||||
default -> String.valueOf(c);
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user