private Context createContext(Lines lines) { // Primeira linha tem que ser context Line firstLine = lines.get(0); if (!firstLine.getLineType().equals(LineType.CONTEXT)) { throw new TxtException(PRIMEIRA_LINHA_DEVE_SER_CONTEXT); } ContextConverter converter = new ContextConverter(); Context context = converter.asObject(null, firstLine); // Demais linhas for (Line line : lines.getLines()) { if (line.getLineType().equals(LineType.CONSTANT)) { addConst(context, line); } else if (line.getLineType().equals(LineType.VARIABLE)) { addVar(context, line); } else if (line.getLineType().equals(LineType.DOMAIN)) { addDomain(context, line); } else if (line.getLineType().equals(LineType.METADATA)) { addMetadata(context, line); } else if (line.getLineType().equals(LineType.SCOPE)) { addScope(context, line); } else if (line.getLineType().equals(LineType.MESSAGE)) { addMessage(context, line); } else if (line.getLineType().equals(LineType.RULE)) { addRule(context, line); } else if (line.getLineType().equals(LineType.PROCESS)) { addProcess(context, line); } } // context.freeze(); // a partir de agora o Context é readonly!! return context; }
/** * Initializes a list block by separating it into list item blocks. * * @param root The Block to process. */ private void initListBlock(final Block root) { Line line = root.lines; line = line.next; while (line != null) { final LineType t = line.getLineType(); if ((t == LineType.OLIST || t == LineType.ULIST) || (!line.isEmpty && (line.prevEmpty && line.leading == 0 && !(t == LineType.OLIST || t == LineType.ULIST)))) { root.split(line.previous).type = BlockType.LIST_ITEM; } line = line.next; } root.split(root.lineTail).type = BlockType.LIST_ITEM; }
/** * Used for nested lists. Removes list markers and up to 4 leading spaces. * * @param configuration txtmark configuration */ public void removeListIndent(final Configuration configuration) { Line line = this.lines; while (line != null) { if (!line.isEmpty) { switch (line.getLineType(configuration)) { case ULIST: line.value = line.value.substring(line.leading + 2); break; case OLIST: line.value = line.value.substring(line.value.indexOf('.') + 2); break; default: line.value = line.value.substring(Math.min(line.leading, 4)); break; } line.initLeading(); } line = line.next; } }
/** * Recursively process the given Block. * * @param root The Block to process. * @param listMode Flag indicating that we're in a list item block. */ private void recurse(final Block root, boolean listMode) { Block block, list; Line line = root.lines; if (listMode) { root.removeListIndent(); if (this.useExtensions && root.lines != null && root.lines.getLineType() != LineType.CODE) { root.id = root.lines.stripIP(); } } while (line != null && line.isEmpty) line = line.next; if (line == null) return; while (line != null) { final LineType type = line.getLineType(); switch (type) { case OTHER: { final boolean wasEmpty = line.prevEmpty; while (line != null && !line.isEmpty) { final LineType t = line.getLineType(); if ((listMode || this.useExtensions) && (t == LineType.OLIST || t == LineType.ULIST)) break; if (this.useExtensions && (t == LineType.CODE)) break; if (t == LineType.HEADLINE || t == LineType.HEADLINE1 || t == LineType.HEADLINE2 || t == LineType.HR || t == LineType.BQUOTE || t == LineType.XML) break; line = line.next; } final BlockType bt; if (line != null && !line.isEmpty) { bt = (listMode && !wasEmpty) ? BlockType.NONE : BlockType.PARAGRAPH; root.split(line.previous).type = bt; root.removeLeadingEmptyLines(); } else { bt = (listMode && (line == null || !line.isEmpty) && !wasEmpty) ? BlockType.NONE : BlockType.PARAGRAPH; root.split(line == null ? root.lineTail : line).type = bt; root.removeLeadingEmptyLines(); } line = root.lines; } break; case CODE: while (line != null && (line.isEmpty || line.leading > 3)) { line = line.next; } block = root.split(line != null ? line.previous : root.lineTail); block.type = BlockType.CODE; block.removeSurroundingEmptyLines(); break; case XML: if (line.previous != null) { // FIXME ... this looks wrong root.split(line.previous); } root.split(line.xmlEndLine).type = BlockType.XML; root.removeLeadingEmptyLines(); line = root.lines; break; case BQUOTE: while (line != null) { if (!line.isEmpty && (line.prevEmpty && line.leading == 0 && line.getLineType() != LineType.BQUOTE)) break; line = line.next; } block = root.split(line != null ? line.previous : root.lineTail); block.type = BlockType.BLOCKQUOTE; block.removeSurroundingEmptyLines(); block.removeBlockQuotePrefix(); this.recurse(block, false); line = root.lines; break; case HR: if (line.previous != null) { // FIXME ... this looks wrong root.split(line.previous); } root.split(line).type = BlockType.RULER; root.removeLeadingEmptyLines(); line = root.lines; break; case HEADLINE: case HEADLINE1: case HEADLINE2: if (line.previous != null) { root.split(line.previous); } if (type != LineType.HEADLINE) { line.next.setEmpty(); } block = root.split(line); block.type = BlockType.HEADLINE; if (type != LineType.HEADLINE) block.hlDepth = type == LineType.HEADLINE1 ? 1 : 2; if (this.useExtensions) block.id = block.lines.stripIP(); block.transfromHeadline(); root.removeLeadingEmptyLines(); line = root.lines; break; case OLIST: case ULIST: while (line != null) { final LineType t = line.getLineType(); if (!line.isEmpty && (line.prevEmpty && line.leading == 0 && !(t == LineType.OLIST || t == LineType.ULIST))) break; line = line.next; } list = root.split(line != null ? line.previous : root.lineTail); list.type = type == LineType.OLIST ? BlockType.ORDERED_LIST : BlockType.UNORDERED_LIST; list.lines.prevEmpty = false; list.lineTail.nextEmpty = false; list.removeSurroundingEmptyLines(); list.lines.prevEmpty = list.lineTail.nextEmpty = false; this.initListBlock(list); block = list.blocks; while (block != null) { this.recurse(block, true); block = block.next; } list.expandListParagraphs(); break; default: line = line.next; break; } } }