diff options
Diffstat (limited to 'src/help.cpp')
-rw-r--r-- | src/help.cpp | 322 |
1 files changed, 0 insertions, 322 deletions
diff --git a/src/help.cpp b/src/help.cpp deleted file mode 100644 index e40e85e..0000000 --- a/src/help.cpp +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2012-2017 Robin Haberkorn - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> - -#include <glib.h> -#include <glib/gstdio.h> -#include <glib/gprintf.h> - -#include "sciteco.h" -#include "string-utils.h" -#include "parser.h" -#include "qregisters.h" -#include "ring.h" -#include "interface.h" -#include "help.h" - -namespace SciTECO { - -HelpIndex help_index; - -namespace States { - StateGetHelp gethelp; -} - -void -HelpIndex::load(void) -{ - gchar *lib_path; - gchar *women_path; - GDir *women_dir; - const gchar *basename; - - if (G_LIKELY(min() != NULL)) - /* already loaded */ - return; - - lib_path = QRegisters::globals["$SCITECOPATH"]->get_string(); - women_path = g_build_filename(lib_path, "women", NIL); - g_free(lib_path); - - women_dir = g_dir_open(women_path, 0, NULL); - if (!women_dir) { - g_free(women_path); - return; - } - - while ((basename = g_dir_read_name(women_dir))) { - gchar *filename, *filename_tec; - FILE *file; - gchar buffer[1024]; - gchar *topic; - - if (!g_str_has_suffix(basename, ".woman")) - continue; - - /* - * Open the corresponding SciTECO macro to read - * its first line. - */ - filename = g_build_filename(women_path, basename, NIL); - filename_tec = g_strconcat(filename, ".tec", NIL); - file = g_fopen(filename_tec, "r"); - g_free(filename_tec); - if (!file) { - /* - * There might simply be no support script for - * simple plain-text woman-pages. - * In this case we create a topic using the filename - * without an extension. - */ - topic = g_strndup(basename, strlen(basename)-6); - set(topic, filename); - g_free(topic); - g_free(filename); - continue; - } - - /* - * Each womanpage script begins with a special comment - * header containing the position to topic index. - * Every topic will be on its own line and they are unlikely - * to be very long, so we can use fgets() here. - * NOTE: Since we haven't opened with the "b" flag, - * fgets() will translate linebreaks to LF even on - * MSVCRT (Windows). - */ - if (!fgets(buffer, sizeof(buffer), file) || - !g_str_has_prefix(buffer, "!*")) { - interface.msg(InterfaceCurrent::MSG_WARNING, - "Missing or invalid topic line in womanpage script \"%s\"", - filename); - g_free(filename); - continue; - } - /* skip opening comment */ - topic = buffer+2; - - do { - gchar *endptr; - tecoInt pos = strtoul(topic, &endptr, 10); - gsize len; - - /* - * This also breaks at the last line of the - * header. - */ - if (*endptr != ':') - break; - - /* - * Strip the likely LF at the end of the line. - */ - len = strlen(endptr)-1; - if (G_LIKELY(endptr[len] == '\n')) - endptr[len] = '\0'; - - set(endptr+1, filename, pos); - } while ((topic = fgets(buffer, sizeof(buffer), file))); - - fclose(file); - g_free(filename); - } - - g_dir_close(women_dir); - g_free(women_path); -} - -HelpIndex::Topic * -HelpIndex::find(const gchar *name) -{ - Topic *ret; - - /* - * The topic index contains printable characters - * only (to avoid having to perform string building - * on the topic terms to be able to define control - * characters). - * Therefore, we expand control characters in the - * look-up string to their printable forms. - */ - gchar *term = String::canonicalize_ctl(name); - - ret = (Topic *)RBTreeStringCase::find(term); - - g_free(term); - return ret; -} - -void -HelpIndex::set(const gchar *name, const gchar *filename, tecoInt pos) -{ - Topic *topic = new Topic(name, filename, pos); - Topic *existing; - - existing = (Topic *)RBTree<RBEntryString>::find(topic); - if (existing) { - gchar *basename; - - if (!strcmp(existing->filename, filename)) { - /* - * A topic with the same name already exists - * in the same file. - * For the time being, we simply overwrite the - * last topic. - * FIXME: Perhaps make it unique again!? - */ - existing->pos = pos; - delete topic; - return; - } - - /* in another file -> make name unique */ - interface.msg(InterfaceCurrent::MSG_WARNING, - "Topic collision: \"%s\" defined in \"%s\" and \"%s\"", - name, existing->filename, filename); - - String::append(topic->name, ":"); - basename = g_path_get_basename(filename); - String::append(topic->name, basename); - g_free(basename); - } - - RBTree::insert(topic); -} - -/* - * Command states - */ - -/*$ "?" help - * ?[topic]$ -- Get help for topic - * - * Look up <topic> in the help index, opening - * the corresponding womanpage as a buffer and scrolling - * to the topic's position. - * The help index is built when this command is first - * executed, so the help system does not consume resources - * when not used (e.g. in a batch-mode script). - * - * \*(ST's help documents must be installed in the - * directory \fB$SCITECOPATH/women\fP, i.e. as part of - * the standard library. - * Each document consist of at least one plain-text file with - * the extension \(lq.woman\(rq. - * Optionally, a \*(ST script with the extension - * \(lq.woman.tec\(rq can be installed alongside the - * main document to define topics covered by this document - * and set up styling. - * - * The beginning of the script must be a header of the form: - * .EX - * !*\fIposition\fP:\fItopic1\fP - * \fIposition2\fP:\fItopic2\fP - * \fI...\fP - * *! - * .EE - * In other words it must be a \*(ST comment followed - * by an asterisk sign, followed by the first topic which - * is a buffer position, followed by a colon and the topic - * string. - * The topic string is terminated by the end of the line. - * The end of the header is marked by a single \(lq*!\(rq. - * Topic terms should be specified with printable characters - * only (e.g. use Caret+A instead of CTRL+A). - * When looking up a help term, control characters are - * canonicalized to their printable form, so the term - * \(lq^A\(rq is found both by Caret+A and CTRL+A. - * Also, while topic terms are not case folded, lookup - * is case insensitive. - * - * The rest of the script is not read by \*(ST internally - * but should contain styling for the main document. - * It is usually read by the standard library's lexer - * configuration system when showing a womanpage. - * If the \(lq.woman.tec\(rq macro is missing, - * \*(ST will define a single topic for the document based - * on the \(lq.woman\(rq file's name. - * - * The combination of plain-text document and script - * is called a \(lqwomanpage\(rq because these files - * are usually generated using \fBgroff\fP(1) with the - * \fIgrosciteco\fP formatter and the \fIsciteco.tmac\fP - * GNU troff macros. - * When using womanpages generated by \fIgrosciteco\fP, - * help topics can be defined using the \fBSCITECO_TOPIC\fP - * Troff macro. - * This flexible system allows \*(ST to access internal - * and third-party help files written in plain-text or - * with an arbitrary GNU troff macro package. - * As all GNU troff documents are processed at build-time, - * GNU troff is not required at runtime. - * - * The \fB?\fP command does not have string building enabled. - */ -void -StateGetHelp::initial(void) -{ - /* - * The help-index is populated on demand, - * so we start up quicker and batch mode does - * not depend on the availability of the standard - * library. - */ - help_index.load(); -} - -State * -StateGetHelp::done(const gchar *str) -{ - HelpIndex::Topic *topic; - - BEGIN_EXEC(&States::start); - - topic = help_index.find(str); - if (!topic) - throw Error("Topic \"%s\" not found", str); - - ring.undo_edit(); - /* - * ED hooks with the default lexer framework - * will usually load the styling SciTECO script - * when editing the buffer for the first time. - */ - ring.edit(topic->filename); - - /* - * Make sure the topic is visible. - * We do need undo tokens for this (even though - * the buffer is removed on rubout if the woman - * page is viewed first) since we might browse - * multiple topics in the same buffer without - * closing it first. - */ - interface.undo_ssm(SCI_GOTOPOS, - interface.ssm(SCI_GETCURRENTPOS)); - interface.ssm(SCI_GOTOPOS, topic->pos); - - return &States::start; -} - -} /* namespace SciTECO */ |