Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git
/*
 * Copyright 2016 White Magic Software, Ltd.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  o Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *  o Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.scrivenvar.processors;

import static com.scrivenvar.Constants.CARET_POSITION_MD;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ObservableValue;

/**
 * Base class for inserting the magic CARET POSITION into the text so that, upon
 * previewing, the preview pane can scroll to the correct position (relative to
 * the caret position in the editor).
 *
 * @author White Magic Software, Ltd.
 */
public abstract class CaretInsertionProcessor extends AbstractProcessor<String> {

  private final IntegerProperty caretPosition = new SimpleIntegerProperty();
  private final static String NEWLINE_CARET_POSITION_MD = NEWLINE + CARET_POSITION_MD;

  public CaretInsertionProcessor(
    final Processor<String> processor,
    final ObservableValue<Integer> position ) {
    super( processor );
    this.caretPosition.bind( position );
  }

  /**
   * Inserts the caret position token into the text at an offset that won't
   * interfere with parsing the text itself, regardless of text format.
   *
   * @param text The text document to change.
   * @param i The caret position token insertion point to use, or -1 to return
   * the text without any injection.
   *
   * @return The given text with a caret position token inserted at the given
   * offset.
   */
  protected String inject( final String text, final int i ) {
    if( i > 0 && i <= text.length() ) {
      // Preserve the newline character when inserting the caret position mark.
      final String replacement = text.charAt( i - 1 ) == NEWLINE
        ? NEWLINE_CARET_POSITION_MD
        : CARET_POSITION_MD;

      return new StringBuilder( text ).replace( i, i, replacement ).toString();
    }

    return text;
  }

  /**
   * Returns true if i is greater than or equal to min and less than or equal to
   * max.
   *
   * @param i The value to check.
   * @param min The lower bound.
   * @param max The upper bound.
   *
   * @return false The value of i is either lower than min or greater than max.
   */
  protected boolean isBetween( int i, int min, int max ) {
    return i >= min && i <= max;
  }

  /**
   * Returns the editor's caret position.
   *
   * @return Where the user has positioned the caret.
   */
  protected int getCaretPosition() {
    return this.caretPosition.getValue();
  }
}