HFU Digital Docs
CourseKitStarPlan

Room & Instructor Extractors

Pull structured room and instructor metadata out of free-form iCal LOCATION and DESCRIPTION fields

StarPlan VEVENTs encode rooms in LOCATION and instructors in DESCRIPTION as free-form text. These extractors apply configurable regex patterns to produce structured records you can store. Defaults match HFU conventions; pass a config to support other institutions.

extractRoom

import { extractRoom, type ExtractedRoom } from '@hfu.digital/coursekit-starplan';

const room = extractRoom('A1.0.1');
// → { name: 'A1.0.1', building: 'A1', floor: '0', isOnline: false }

const online = extractRoom('Online (Zoom)');
// → { name: 'Online (Zoom)', building: null, floor: null, isOnline: true }

const unknown = extractRoom('Aula');
// → { name: 'Aula', building: null, floor: null, isOnline: false }

const missing = extractRoom('');
// → null

RoomExtractorConfig

OptionTypeDefaultDescription
patternRegExp/^([A-Za-z]+\d*)\.(\d+)\.\d+/Captures building (group 1) and floor (group 2). Default matches HFU's A1.0.1 pattern.
onlineKeywordsstring[]['online', 'zoom', 'teams', 'virtuell', 'virtual', 'webex']Lowercased substrings that flag a location as online/virtual

ExtractedRoom

interface ExtractedRoom {
    name: string;             // Original LOCATION (trimmed)
    building: string | null;  // Uppercased capture group 1, or null
    floor: string | null;     // Capture group 2, or null
    isOnline: boolean;        // True if any onlineKeyword matched
}

extractInstructor

import { extractInstructor } from '@hfu.digital/coursekit-starplan';

const name = extractInstructor('Dozent: Prof. Dr. Mustermann\nRaum: A1.0.1');
// → 'Prof. Dr. Mustermann'

const none = extractInstructor('Praktikum');
// → null

InstructorExtractorConfig

OptionTypeDefaultDescription
patternsRegExp[]German + English defaultsPatterns whose first capture group is the instructor name. Tried in order; first match wins.
minNameLengthnumber3Reject captures shorter than this
maxNameLengthnumber100Reject captures longer than this

Default patterns (in order):

/Dozent(?:in)?:\s*(.+?)(?:\n|$)/i
/Instructor:\s*(.+?)(?:\n|$)/i
/Lehrer(?:in)?:\s*(.+?)(?:\n|$)/i
/Prof\.?\s*(?:Dr\.?\s*)?(.+?)(?:\n|$)/i

Captures containing @ are rejected (avoids matching email addresses).

Notes

  • Both extractors fall back to null rather than throwing — handle the null case explicitly when persisting.
  • For multi-instructor support, run extractInstructor with custom patterns or split the description yourself before passing it in.
  • Building names are uppercased; floor strings are returned as-is (so 'A1.05.10'building: 'A1', floor: '05').

On this page