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

This commit is contained in:
2026-02-04 20:41:20 +05:00
parent a1807aa84b
commit 69ccb05980
3 changed files with 171 additions and 2 deletions

146
java/md2html/Md2Html.java Normal file
View 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 '<' -> "&lt;";
case '>' -> "&gt;";
case '&' -> "&amp;";
default -> String.valueOf(c);
};
}
}