about summary refs log tree commit diff stats
path: root/linkify
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-12-30 00:02:42 -0800
committerKartik Agaram <vc@akkartik.com>2018-12-30 00:02:42 -0800
commit08a0eed699b8ea07d37163aba610c8e04feee003 (patch)
treeaab05fd9b23ca4f5cfc6492ade82896f3ba5e4bb /linkify
parentac07e589b3e912c704c2011d543f18b16712ff15 (diff)
downloadmu-08a0eed699b8ea07d37163aba610c8e04feee003.tar.gz
4891
Couple more tweaks to html rendering:
a) SubX definitions no longer link redundantly to themselves. This long-standing
issue turns out to be tractable to solve for SubX files since the syntax
is so simple.
b) Fix links to SubX definitions in other directories. I forgot that I
have to always generate tags from the directory of the file being linkified.
c) Fix link colors. Before we lost all syntax highlighting for functions
and Globals. Now they maintain their colors, just add an underline.
Diffstat (limited to 'linkify')
-rw-r--r--linkify/linkify.cc28
1 files changed, 25 insertions, 3 deletions
diff --git a/linkify/linkify.cc b/linkify/linkify.cc
index 58f37840..bb6eb772 100644
--- a/linkify/linkify.cc
+++ b/linkify/linkify.cc
@@ -7,6 +7,7 @@
 
 // Still plenty of holes:
 // - unnecessarily linking definition location to itself
+//   - except SubX definitions, which start at start of line
 // - can't detect strings in spite of attempt to support them below, because
 //   Vim's generated html turns quotes into html entities
 // - distinguishing function and variable names
@@ -63,6 +64,13 @@ bool starts_with(const string& s, const string& pat) {
   return b == pat.end();
 }
 
+bool ends_with(const string& s, const string& pat) {
+  string::const_reverse_iterator a=s.rbegin(), b=pat.rbegin();
+  for (/*nada*/;  a!=s.rend() && b!=pat.rend();  ++a, ++b)
+    if (*a != *b) return false;
+  return b == pat.rend();
+}
+
 void encode_some_html_entities(string& s) {
   std::string::size_type pos = 0;
   while (true) {
@@ -123,11 +131,13 @@ void replace_tags_in_file(const string& filename, const map<string, syminfo>& in
       out << line.substr(0, skip_first_span);
       istringstream in2(line.substr(skip_first_span));
       in2 >> std::noskipws;
+      bool at_start_of_line = ends_with(filename, ".subx");
       while (has_data(in2)) {
         if (isspace(in2.peek())) {
 //?           cerr << "space\n";
           char c;  in2 >> c;
           out << c;
+          at_start_of_line = false;
         }
         // within a line, send straight through all characters inside '<..>'
         else if (in2.peek() == '<') {
@@ -138,6 +148,7 @@ void replace_tags_in_file(const string& filename, const map<string, syminfo>& in
             out << c;
             if (c == '>') break;
           }
+          // don't include initial tag when computing 'at_start_of_line'
 //?           cerr << "end tag\n";
         }
         else {
@@ -155,6 +166,7 @@ void replace_tags_in_file(const string& filename, const map<string, syminfo>& in
                 break;
               }
             }
+            at_start_of_line = false;
           }
           else if (c == '\'') {
 //?             cerr << "character\n";
@@ -168,23 +180,27 @@ void replace_tags_in_file(const string& filename, const map<string, syminfo>& in
                 break;
               }
             }
+            at_start_of_line = false;
           }
-          // send straight through any characters after '//' (comments)
+          // send straight through any characters after '#' (comments)
           else if (c == '#') {
 //?             cerr << "comment\n";
             out << c;
             while (in2 >> c) out << c;
+            at_start_of_line = false;
           }
           // send straight through any characters after '//' (comments)
           else if (c == '/' && in2.peek() == '/') {
 //?             cerr << "comment\n";
             out << c;
             while (in2 >> c) out << c;
+            at_start_of_line = false;
           }
           else {
 //?             cerr << "rest\n";
             if (c == ',' || c == ':') {
               out << c;
+              at_start_of_line = false;
               continue;
             }
             ostringstream out2;
@@ -212,8 +228,14 @@ void replace_tags_in_file(const string& filename, const map<string, syminfo>& in
                 out << symbol;
               }
               else {
-//?                 cerr << "  link\n";
-                out << "<a href='" << s.filename << ".html#L" << s.line_num << "'>" << symbol << "</a>";
+                if (at_start_of_line) {
+//?                   cerr << "  at start of line\n";
+                  out << symbol;
+                }
+                else {
+//?                   cerr << "  link\n";
+                  out << "<a href='" << s.filename << ".html#L" << s.line_num << "'>" << symbol << "</a>";
+                }
               }
             }
           }  // end rest