blob: fb844018d168a56b2dd746d7368f65c85e6886c3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2012 David Green and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* David Green - initial API and implementation
* Jeremie Bresson - Bug 381912
*******************************************************************************/
package org.eclipse.mylyn.wikitext.parser.markup;
import org.eclipse.mylyn.wikitext.parser.DocumentBuilder;
/**
* A markup block that may span multiple lines. Implements {@link Cloneable} for the template design pattern.
*
* @author David Green
* @since 3.0
*/
public abstract class Block extends Processor implements Cloneable {
private boolean closed;
public Block() {
}
/**
* Process the given line of markup starting at the provided offset.
*
* @param line
* the markup line to process
* @param offset
* the offset at which to start processing
* @return a non-negative integer to indicate that processing of the block completed before the end of the line, or
* -1 if the entire line was processed.
*/
public int processLine(String line, int offset) {
getState().setLineCharacterOffset(offset);
return processLineContent(line, offset);
}
/**
* Process the given line of markup starting at the provided offset.
*
* @param line
* the markup line to process
* @param offset
* the offset at which to start processing
* @return a non-negative integer to indicate that processing of the block completed before the end of the line, or
* -1 if the entire line was processed.
*/
protected abstract int processLineContent(String line, int offset);
/**
* Indicate if the block can start with the given markup line at the provided offset. Calling this method may cause
* the block to have state which is propagated when {@link #clone() cloning} and consumed in
* {@link #processLine(String, int, int)}. Calling this method must cause any previous state to be reset. Note that
* it is valid for block implementations to refuse to start at non-zero offsets. Implementations must be able to
* handle this method without having the {@link Processor processor state} initialized.
*
* @param line
* the line of markup to test
* @param lineOffset
* the offset at which the block should start processing
* @return true if the provided markup consists of a valid starting point for the block
*/
public abstract boolean canStart(String line, int lineOffset);
/**
* Indicate if block nesting should begin. Called after {@link #processLineContent(String, int)}.
*
* @return true if nesting should start, otherwise false.
* @see #findCloseOffset(String, int)
* @see #canResume(String, int)
*/
public boolean beginNesting() {
return false;
}
/**
* Indicate if the block can close on the given line at the given offset. blocks that implement a nesting protocol
* must implement this method.
*
* @param line
* the line of content
* @param lineOffset
* the 0-based offset into the line
* @return the 0-based offset where the close will occur, or -1 if the block should not close on this line.
* @see #beginNesting()
* @see #canResume(String, int)
*/
public int findCloseOffset(String line, int lineOffset) {
return -1;
}
/**
* Indicates if the block can resume with the given markup line at the provided offset. Resuming a block, means that
* the nested children blocks are closed. Blocks that implement a nesting protocol should implement this method.
*
* @param line
* the line of content
* @param lineOffset
* the 0-based offset into the line
* @return <code>true</code> if the block can resume <code>false</code> if nested block needs to handle the content
* further.
* @see #beginNesting()
* @see #findCloseOffset(String, int)
*/
public boolean canResume(String line, int lineOffset) {
return false;
}
/**
* Indicate if the current block is closed
*/
public boolean isClosed() {
return closed;
}
/**
* Cause the block to be closed. If the block is going from the open to the closed state, then the block must cause
* the closed state to be propagated to the {@link DocumentBuilder builder} if necessary.
*
* @param closed
*/
public void setClosed(boolean closed) {
this.closed = closed;
}
/**
* Clone the block including its state. Cloning is generally used after the {@link #canStart(String, int)} method is
* called in order to implement the Template design pattern.
*/
@Override
public Block clone() {
return (Block) super.clone();
}
}