Custom Text Index Offset
Custom Text Index Offset
The annotated-text library supports custom text indexing offsets to align with different scholarly and editorial workflows. By default, text uses zero-based indexing (starting at 0), but you can configure it to start at 1 or any other value.
The Problem
Zero-based indexing is standard in programming, but many academic and editorial contexts reference text positions starting from 1. For example:
- FileMaker uses 1-based indexing (documentation)
- Scholarly editions often reference character or word positions starting from 1
- Editorial workflows may use 1-based positions for manuscript annotations
- W3C Web Annotation uses 0-based indexing, which can cause confusion when integrating with other systems that use 1-based indexing
- Other markup standards often use 0-based counting
This mismatch requires constant mental translation and can lead to errors when creating or validating annotations.
Solution: Start Offset Configuration
Configure a custom offset for text character indexing using the startOffset option on the annotation adapter:
createAnnotatedText(id)
.setAnnotationAdapter({ startOffset: 1 })
.setText(text)
.setAnnotations(annotations);How It Works
When you set a startOffset:
- Display layer: Text positions are shown with the offset applied (e.g., first character is position 1)
- Internal layer: Zero-based indexing is maintained internally for processing
- Annotations: Use the offset-adjusted positions when defining start/end values
Basic Usage
1-based indexing (most common for scholarly work):
const text = "Hello world";
const annotations = [
{
start: 1, // First character 'H'
end: 5, // Last character 'o'
},
{
start: 7, // First character 'w'
end: 11, // Last character 'd'
}
];
createAnnotatedText(id)
.setAnnotationAdapter({ startOffset: 1 })
.setText(text)
.setAnnotations(annotations);Default behavior (0-based indexing):
// Without startOffset, or with startOffset: 0
const annotations = [
{
start: 0, // First character 'H'
end: 4, // Last character 'o'
}
];
createAnnotatedText(id)
.setText(text)
.setAnnotations(annotations);Use Cases
FileMaker Integration
Align with FileMaker's Position function:
// Match FileMaker's 1-based Position() function
createAnnotatedText("filemaker-text")
.setAnnotationAdapter({ startOffset: 1 });Custom Offsets
Support arbitrary starting positions:
// Start at position 100 (e.g., continuing from a previous section)
createAnnotatedText("section-2")
.setAnnotationAdapter({ startOffset: 100 });Important Considerations
- Consistency: Use the same offset throughout your application or clearly document when offsets change
- Data Import/Export: When importing annotations from external sources, ensure their indexing matches your configured offset
- API Responses: If your backend uses 0-based indexing, convert positions when setting annotations
- Documentation: Clearly communicate the indexing convention to users and collaborators
Default Behavior
When startOffset is not specified or set to 0:
- Text indexing starts at 0
- Standard zero-based indexing is used throughout
- This is the default behavior and matches most programming conventions
Example
In this example, we demonstrate three different text offsets: 0, 1, and 10. For each offset, the same annotation array is applied, to demonstrate how the starting index affects the annotation positions.