summaryrefslogtreecommitdiff
path: root/base/src/main/java/bjc/utils/ioutils/blocks/MLPromptBlockReader.java
blob: 981c5aa5badae4c07f0f6182946e19ff92d3bdda (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package bjc.utils.ioutils.blocks;

import java.io.*;
import java.util.Scanner;

/**
 * A block reader that uses bash-style multi-line prompts to read blocks.
 * 
 * The format of the blocks returned by this is indented blocks <code> x y z a b
 * 
 * c -- block split here d <code>
 * 
 * @author bjcul
 *
 */
public class MLPromptBlockReader implements BlockReader {
	private String firstPrompt;
	private String secondPrompt;

	private Scanner input;
	private Writer output;

	private Block currBlock;
	
	/* Info about the current block. */
	private int blockNo = 0;
	private int lineNo  = 1;
	
	private String nextInitLine;
	/**
	 * Create a new multi-line prompt block reader.
	 * 
	 * @param firstPrompt  The initial prompt. Is treated as a format string, with
	 *                     %1 being the block number and %2 being the line number
	 * @param secondPrompt The secondary prompt. Is also treated as a format string
	 *                     with %1 and %2 as firstPrompt, and %3 as the continuation line
	 *                     number
	 * 
	 * @param input        The input source
	 * @param output       The output destination
	 */
	public MLPromptBlockReader(String firstPrompt, String secondPrompt, Reader input, Writer output) {
		this.firstPrompt = firstPrompt;
		this.secondPrompt = secondPrompt;
		this.input = new Scanner(input);
		this.output = output;
	}

	@Override
	public boolean hasNextBlock() {
		return input.hasNextLine();
	}

	@Override
	public Block getBlock() {
		return currBlock;
	}

	@Override
	public boolean nextBlock() {
		StringBuilder blockContents = new StringBuilder();
		
		String currLn;
		if (nextInitLine == null) {
			try {
				output.write(String.format(firstPrompt, blockNo, lineNo));
			} catch (IOException ioex) {
				throw new RuntimeException(ioex);
			}
			currLn = input.nextLine();
		} else {
			currLn = nextInitLine;
		}
		
		blockContents.append(currLn);
		
		int startLn = lineNo;
		int endLn = lineNo++;
		
		boolean inBlock = true;
		while(input.hasNextLine() && inBlock) {
			currLn = input.nextLine();
			
			int initCh = currLn.codePointAt(0);
			inBlock = Character.isSpaceChar(initCh);
		}
		
		currBlock = new Block(blockNo++, blockContents.toString(), startLn, endLn);
		return true;
	}

	@Override
	public int getBlockCount() {
		return blockNo;
	}

	@Override
	public void close() throws IOException {
		input.close();
	}

}