@tailrec def scan(pred: Int => Boolean): Unit = { if (offset < text.length) { val c = text.codePointAt(offset) if (pred(c)) {
offset += Character.charCount(c)
scan(pred)
}
}
}
while (offset < text.length) {
scan(c => !Character.isLetter(c)) val start = offset
scan(c => Character.isLetterOrDigit(c) || apostrophe(c)) val stop = offset if (stop - start >= 2) { val info = Text.Info(Text.Range(base + start, base + stop), text.substring(start, stop)) if (mark(info)) result += info
}
}
result.toList
}
def current_word(rendering: Rendering, range: Text.Range): Option[Text.Info[String]] = { for {
spell_range <- rendering.spell_checker_point(range)
text <- rendering.get_text(spell_range)
info <- marked_words(spell_range.start, text, info => info.range.overlaps(range)).headOption
} yield info
}
/* dictionaries */
class Dictionary private[Spell_Checker](val path: Path) { val lang: String = path.drop_ext.file_name val user_path: Path = Path.explode("$ISABELLE_HOME_USER/dictionaries") + Path.basic(lang) overridedef toString: String = lang
}
privateobject Decl { def apply(name: String, include: Boolean): String = if (include) name else"-" + name
def unapply(decl: String): Option[(String, Boolean)] = { val decl1 = decl.trim if (decl1 == "" || decl1.startsWith("#")) None else
Library.try_unprefix("-", decl1.trim) match { case None => Some((decl1, true)) case Some(decl2) => Some((decl2, false))
}
}
}
lazyval dictionaries: List[Dictionary] = for {
path <- Path.split(Isabelle_System.getenv("JORTHO_DICTIONARIES")) if path.is_file
} yieldnew Dictionary(path)
privatedef included_iterator(): Iterator[String] = for {
(word, upd) <- updates.iterator if upd.include
} yield word
privatedef excluded(word: String): Boolean =
updates.get(word) match { case Some(upd) => !upd.include case None => false
}
privatedef load(): Unit = { val main_dictionary = split_lines(File.read_gzip(dictionary.path))
val permanent_updates = if (dictionary.user_path.is_file) for { case Spell_Checker.Decl(word, include) <- split_lines(File.read(dictionary.user_path))
} yield (word, Spell_Checker.Update(include, true)) else Nil
privatedef save(): Unit = { val permanent_decls =
(for {
(word, upd) <- updates.iterator if upd.permanent
} yield Spell_Checker.Decl(word, upd.include)).toList
if (permanent_decls.nonEmpty || dictionary.user_path.is_file) { val header = """# User updates for spell-checker dictionary
#
# * each line contains at most one word
# * extra blanks are ignored
# * lines starting with"#" are stripped
# * lines starting with"-" indicate excluded words
#
#:mode=text:encoding=UTF-8:
def check(word: String): Boolean =
word match { case Word.Case(c) if c != Word.Case.lowercase =>
contains(word) || contains(Word.lowercase(word)) case _ =>
contains(word)
}
privatedef suggestions(word: String): Option[List[String]] = { val res =
Untyped.method(dict.getClass.getSuperclass, "searchSuggestions", classOf[String]).
invoke(dict, word).asInstanceOf[JList[AnyRef]].toArray.toList.map(_.toString) if (res.isEmpty) None else Some(res)
}
def complete(word: String): List[String] = if (check(word)) Nil else { val word_case = Word.Case.unapply(word) def recover_case(s: String) =
word_case match { case Some(c) => Word.Case(c, s) case None => s
} val result =
word_case match { case Some(c) if c != Word.Case.lowercase =>
suggestions(word) orElse suggestions(Word.lowercase(word)) case _ =>
suggestions(word)
}
result.getOrElse(Nil).map(recover_case)
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.