65.9K
CodeProject 正在变化。 阅读更多。
Home

关键词索引(关键词在上下文中)生成器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.96/5 (15投票s)

2006 年 9 月 15 日

CPOL

5分钟阅读

viewsIcon

76392

downloadIcon

1289

生成并显示文本条目的置换索引(关键词在上下文中的索引)。

PermutedIndex screen shot

引言

置换索引,也称为关键词在上下文中的索引,是关键词的字母列表,显示了它们周围的文本(上下文)。上面的截图显示了一个例子。显示格式使得用户可以轻松地扫描感兴趣的关键词,上下文有助于识别关键词出现多次的具体实例,而关键词本身可以作为链接,直接访问它们所引用的文本或对象。

背景

最著名的关键词索引是书本末尾的字母索引,它列出了关键词以及关键词出现的页码。使用索引的读者必须检查列出的页面,直到找到他们所寻求的特定参考。关键词在上下文中的索引通过包含周围的文本以及关键词,使得查找所需参考变得容易。为了提高可读性,它被格式化为使关键词在垂直列中对齐。这种格式可能因为在Unix操作系统打印文档中使用而为人所熟知。

这种索引方法特别适用于一组具有单行描述的实体:描述行本身充当上下文。库函数描述、收藏品照片描述、短语引用或谚语都是合适的例子。

使用代码

代码包含索引器本身 CPermutedIndex,以及一个基于对话框、由App-Wizard生成的示例应用程序,该程序接受用户输入的字符串,从这些字符串构建索引,并在列表框和字母“拇指索引”窗口中显示索引。示例应用程序还可以将索引作为HTML或C源代码写入文件,供其他项目使用。

构建索引

要构建索引,请构造一个 CPermutedIndex 对象,并使用要索引的字符串数组调用其 BuildIndex 方法。

m_pPermutedIndex = new CPermutedIndex;
m_pPermutedIndex->BuildIndex(m_pInputLinePtrs, m_nInputLineCount);

请注意,索引对象不会复制字符串,因此字符串数组必须在需要索引时一直存在。

从索引中排除单词

有些单词只会给索引增加混乱。冠词和连词,如 the, and, of。特定上下文的填充词,如 avenue, street, gram, kilometer, volt, second。要排除您的单词集,请在构建索引之前使用字符串数组调用 SetExcludedWordList

static char szExcludedWords[] =
{
    "the", "and", "of", "avenue", "street", "gram", 
    "kilometer", "volt", "second"
};
...
    m_pPermutedIndex = new CPermutedIndex;
    m_pPermutedIndex->SetExcludedWordList(szExcludedWords, 
                      sizeof(szExcludedWords)/sizeof(char *));
    m_pPermutedIndex->BuildIndex(m_pInputLinePtrs, m_nInputLineCount);

使用索引

要将索引与Windows列表框一起使用,请使用 LBS_OWNERDRAWFIXED 样式创建列表框。从 CListBox 派生一个类,并重写其 DrawItem 方法以调用 CPermutedIndex 对象中的 DrawListBoxItem。然后,在构建索引后,在 CPermutedIndex 对象中调用 FillIndexListBox

// in the header file
class CIndexListBox : public CListBox
{
public:
    // set this to point to the dialog that hosts this control
    CPermutedIndexDemoDlg *m_pParentDlg;
protected:
    afx_msg void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};

// and in the implementation file
void CIndexListBox::DrawItem(DRAWITEMSTRUCT *pDiS)
{
    m_pParentDlg->m_pPermutedIndex->DrawListBoxItem(pDiS);
}

要响应用户选择列表框中的条目,请为 ON_LBN_SELCHANGE 添加一个事件处理程序,并在 CPermutedIndex 对象中调用 GetIndexTableEntry

void CPermutedIndexDemoDlg::OnSelchangeIndexList()
{
    int nCurSel = m_wndIndexList.GetCurSel();
    int nEntry = m_wndIndexList.GetItemData(nCurSel);
    const IndexEntry *pEntry = m_pPermutedIndex->GetIndexTableEntry(nEntry);
    int nSourceLine = pEntry->nItemIndex;
}

此时,您需要知道 IndexEntry 结构看起来是什么样子

typedef struct _IndexEntry
{
    int nItemIndex;       // the index of the string in the source list
    const char *pszText;  // a pointer to the start of the string
    short nKeywordOffset; // the offset of the keyword in the source string
    short nKeywordLength; // the length of the keyword in the source string
} IndexEntry;

从中可以提取所有信息来显示索引并关联条目与其源字符串。

拇指索引标签窗口

“拇指索引标签”窗口显示字母表。单击某个字母将返回以该字母开头的第一个索引条目的编号;然后应用程序可以通过将列表框的选择设置为该条目来滚动列表框到该条目。

要实现拇指索引标签窗口,请在对话框上放置一个白色矩形静态控件,并为其指定 SS_NOTIFY 样式。从 CStatic 派生一个类,并将该类的实例附加到控件。按如下方式实现派生类

// in the header file
class CIndexTabWin : public CStatic
{
public:
    // set this to point to the dialog that hosts this control
    CPermutedIndexDemoDlg *m_pParentDlg;
protected:
    afx_msg void OnPaint();
    afx_msg void OnLButtonDown(UINT nType, CPoint point);
    DECLARE_MESSAGE_MAP()
};

// and in the implementation file
BEGIN_MESSAGE_MAP(CIndexTabWin, CStatic)
    ON_WM_PAINT()
    ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

// let the code in CPermutedIndex do the drawing
//
void CIndexTabWin::OnPaint()
{
    PAINTSTRUCT ps;

    CDC *pDC = BeginPaint(&ps);
    m_pParentDlg->m_pPermutedIndex->DrawIndexTabWindow(this, pDC);
    EndPaint(&ps);
}

// forward the mouse click in the index tab window to
// the code in the parent dialog
//
void CIndexTabWin::OnLButtonDown(UINT nType, CPoint point)
{
    m_pParentDlg->ProcessTabWindowClick(point.x);
}

要将标签窗口链接到列表框,您需要类似这样的代码

void CPermutedIndexDemoDlg::ProcessTabWindowClick(int nXPos)
{
    // get the entry number for the start of that letter's index
    // and set the list box selection to that one
    int nEntry = m_pPermutedIndex->IndexOffsetFromTabXCoord(nXPos);
    if (nEntry >= 0)        // "empty" tabs return -1
        m_wndIndexList.SetCurSel(nEntry);
}

导出索引供其他用途

绘制索引和标签窗口以及适当链接所需的信息都可从 CPermutedIndex 对象中获得。演示应用程序包含将索引导出为链接HTML或C语言数组和结构的代码。检查此应用程序应该可以帮助您了解如何使用索引。

关注点

该索引器最初是作为历史照片收藏的查看器的一部分编写的,每张照片都用一行文本描述。该应用程序还可以将索引导出为带有指向图像文件链接的HTML。使用该索引的经验表明,该索引功能可能在其他地方也很有用。

在Windows列表框中显示置换索引可以让您学习如何使用所有者绘制的列表框。此实现会绘制到关键词的文本,使用 TA_RIGHT 文本对齐方式将其对齐到绘图矩形的水平中心,然后使用 TA_LEFT 对齐方式将其对齐到中心,绘制关键词和其右侧的任何文本。关键词以不同的颜色绘制,并且可以选择使用不同的字体;演示应用程序使用稍微粗体的字体来使关键词突出。

在HTML中显示索引使用类似的方法。索引被创建为一个带有不可见边框的两列表。左列显示到关键词的文本,并右对齐;右列显示关键词及其后面的文本,并左对齐。关键词被赋予一个指向相应目标的链接。结果显示为单行文本,关键词垂直对齐。

HTML拇指索引标签被创建为一系列链接(对于活动的字母)或字符串(对于不活动的字母)。活动条目链接到索引中的相应条目,因此这些目标在写入索引时被创建,使用 GetEntrySectionNumber 方法来获取与每个索引条目关联的任何标签。

历史

  • 2006年9月15日:创建。
  • 2006年9月20日:修复以兼容VC7编译。
  • 2006年10月2日:添加了对 SetExcludedWordList 的文本描述。
© . All rights reserved.