好了,雷克斯忍者。我正在尝试设计一种模式,在ePub电子书XHTML文件中添加到尾注的超链接。问题是在每个章节中重新开始编号,所以我需要向锚名称添加一个唯一的标识符,以便散列到它的链接。
给出一个(简单得多)如下的列表:
<h2>Introduction</h2>
<p> 1 Endnote entry number one.</p>
<p> 2 Endnote entry number two.</p>
<p> 3 Endnote entry number three.</p>
<p> 4 Endnote entry number four.</p>
<h2>Chapter 1: The Beginning</h2>
<p> 1 Endnote entry number one.</p>
<p> 2 Endnote entry number two.</p>
<p> 3 Endnote entry number three.</p>
<p> 4 Endnote entry number four.</p>我需要把它变成这样:
<h2>Introduction</h2>
<a name="endnote-introduction-1"></a><p> 1 Endnote entry number one.</p>
<a name="endnote-introduction-2"></a><p> 2 Endnote entry number two.</p>
<a name="endnote-introduction-3"></a><p> 3 Endnote entry number three.</p>
<a name="endnote-introduction-4"></a><p> 4 Endnote entry number four.</p>
<h2>Chapter 1: The Beginning</h2>
<a name="endnote-chapter-1-the-beginning-1"></a><p> 1 Endnote entry number one.</p>
<a name="endnote-chapter-1-the-beginning-2"></a><p> 2 Endnote entry number two.</p>
<a name="endnote-chapter-1-the-beginning-3"></a><p> 3 Endnote entry number three.</p>
<a name="endnote-chapter-1-the-beginning-4"></a><p> 4 Endnote entry number four.</p>显然,需要在书的实际文本中进行类似的搜索,其中每个尾注都将链接到endnotes.xhtml#endnote-introduction-1等。
最大的障碍是每次匹配搜索都是在前一次搜索结束之后开始的,所以除非使用递归,否则不能为多个条目匹配相同的位(在本例中是标题)。然而,到目前为止,我对递归的尝试只产生了无限的循环。
我使用的是TextWrangler的grep引擎,但是如果您在不同的编辑器(比如vim)中有一个解决方案,也没问题。
谢谢!
发布于 2011-08-04 06:35:51
一点awk可能会做到这一点:
创建以下脚本(我已将其命名为add_endnote_tags.awk):
/^<h2>/ {
i = 0;
chapter_name = $0;
gsub(/<[^>]+>/, "", chapter_name);
chapter_name = tolower(chapter_name);
gsub(/[^a-z]+/, "-", chapter_name);
print;
}
/^<p>/ {
i = i + 1;
printf("<a name=\"endnote-%s-%d\"></a>%s\n", chapter_name, i, $0);
}
$0 !~ /^<h2>/ && $0 !~ /^<p>/ {
print;
}然后使用它解析您的文件:
awk -f add_endnote_tags.awk < source_file.xml > dest_file.xml希望这能有所帮助。如果您使用的是Windows平台,则可能需要通过安装cygwin和awk软件包或下载gawk for Windows来安装awk
发布于 2011-08-04 07:48:37
我认为这很难在文本编辑器中完成,因为它需要两个步骤的过程。首先你需要将文件分成章节,然后你需要处理每一章的内容。假设"endnote paragraphs“(这是您希望添加锚点的位置)被定义为第一个单词等于一个整数单词的段落,则此PHP脚本将执行您所需的操作。
<?php
$data = file_get_contents('testdata.txt');
$output = processBook($data);
file_put_contents('testdata_out.txt', $output);
echo $output;
// Main function to process book adding endnote anchors.
function processBook($text) {
$re_chap = '%
# Regex 1: Get Chapter.
<h2>([^<>]+)</h2> # $1: Chapter title.
( # $2: Chapter contents.
.+? # Contents are everything up to
(?=<h2>|$) # next chapter or end of file.
) # End $2: Chapter contents.
%six';
// Match and process each chapter using callback function.
$text = preg_replace_callback($re_chap, '_cb_chap', $text);
return $text;
}
// Callback function to process each chapter.
function _cb_chap($matches) {
// Build ID from H2 title contents.
// Trim leading and trailing ws from title.
$baseid = trim($matches[1]);
// Strip all non-space, non-alphanums.
$baseid = preg_replace('/[^ A-Za-z0-9]/', '', $matches[1]);
// Append prefix and convert whitespans to single - dash.
$baseid = 'endnote-'. preg_replace('/ +/', '-', $baseid);
// Convert to lowercase.
$baseid = strtolower($baseid);
$text = preg_replace(
'/(<p>\s*)(\d+)\b/',
'<a name="'. $baseid .'-$2"></a>$1$2',
$matches[2]);
return '<h2>'. $matches[1] .'</h2>'. $text;
}
?>这个脚本正确地处理了示例数据。
https://stackoverflow.com/questions/6933925
复制相似问题