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 blocks = readBlocks(reader); for (String block : blocks) { writer.write(convertBlock(block)); writer.newLine(); } } catch (IOException e) { // по условию обычно можно игнорировать или просто завершить } } private static List readBlocks(BufferedReader reader) throws IOException { List 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 "" + parseInline(content) + ""; } else { return "

" + parseInline(block) + "

"; } } 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 stack = new ArrayDeque<>(); Map 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(""); 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(""); 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); }; } }