HighlightReader.java
/*
* Copyright © 2014-2025 The CTAN Team and individual authors
*
* This file is distributed under the 3-clause BSD license.
* See file LICENSE for details.
*/
package org.ctan.markup.markdown.syntax;
import java.io.IOException;
import java.io.PushbackReader;
import java.io.Reader;
/**
* This class establishes a reader which treats ``` as EOF.
*
* @author <a href="mailto:gene@ctan.org">Gerd Neugebauer</a>
*/
public class HighlightReader extends PushbackReader {
/**
* This is the constructor for <code>HighlightReader</code>.
*
* @param reader the reader
*/
public HighlightReader(Reader reader) {
super(reader, 64);
}
/**
* {@inheritDoc}
*
* @see java.io.PushbackReader#close()
*/
@Override
public void close() throws IOException {
// noop
}
/**
* This method checks that the lookahead of several characters are identical
* to the expected character. Then these are digested. Otherwise the
* characters are pushed back into the input.
*
* @param s the expected characters
*
* @return {@code true} iff <i>n</i> characters have been found
*
* @throws IOException in case of an I/O error
*/
public boolean expect(int... s) throws IOException {
var i = 0;
for (int c : s) {
var cc = read();
if (c != cc) {
unread(cc);
while (i-- > 0) {
unread(s[i]);
}
return false;
}
i++;
}
return true;
}
/**
* {@inheritDoc}
*
* @see java.io.Reader#read()
*/
@Override
public int read() throws IOException {
var c = super.read();
if (c != '`') {
return c;
}
c = super.read();
if (c != '`') {
unread(c);
return '`';
}
c = super.read();
if (c != '`') {
unread(c);
unread('`');
return '`';
}
return -1;
}
/**
* {@inheritDoc}
*
* @see java.io.Reader#read(char[], int, int)
*/
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* @see java.io.PushbackReader#unread(int)
*/
@Override
public void unread(int c) throws IOException {
if (c >= 0) {
super.unread(c);
}
}
}