Fossil SCM
Highlight matching works on a search using <mark> rather than <b> and add appropriate CSS to make "mark" look like "b" by default.
Commit
c5a2832eebd62b50de331e576c2d4f8f3651058b
Parent
780117d2239e21d…
2 files changed
+3
-3
+31
-2
+3
-3
| --- src/search.c | ||
| +++ src/search.c | ||
| @@ -363,12 +363,12 @@ | ||
| 363 | 363 | sqlite3_context *context, |
| 364 | 364 | int argc, |
| 365 | 365 | sqlite3_value **argv |
| 366 | 366 | ){ |
| 367 | 367 | const char *zPattern = 0; |
| 368 | - const char *zBegin = "<b>"; | |
| 369 | - const char *zEnd = "</b>"; | |
| 368 | + const char *zBegin = "<mark>"; | |
| 369 | + const char *zEnd = "</mark>"; | |
| 370 | 370 | const char *zGap = " ... "; |
| 371 | 371 | unsigned int flg = SRCHFLG_HTML; |
| 372 | 372 | switch( argc ){ |
| 373 | 373 | default: |
| 374 | 374 | flg = (unsigned int)sqlite3_value_int(argv[4]); |
| @@ -745,11 +745,11 @@ | ||
| 745 | 745 | "INSERT INTO x(label,url,score,date,snip) " |
| 746 | 746 | " SELECT ftsdocs.label," |
| 747 | 747 | " ftsdocs.url," |
| 748 | 748 | " rank(matchinfo(ftsidx,'pcsx'))," |
| 749 | 749 | " datetime(ftsdocs.mtime)," |
| 750 | - " snippet(ftsidx)" | |
| 750 | + " snippet(ftsidx,'<mark>','</mark>')" | |
| 751 | 751 | " FROM ftsidx, ftsdocs" |
| 752 | 752 | " WHERE ftsidx MATCH %Q" |
| 753 | 753 | " AND ftsdocs.rowid=ftsidx.docid", |
| 754 | 754 | zPattern |
| 755 | 755 | ); |
| 756 | 756 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -363,12 +363,12 @@ | |
| 363 | sqlite3_context *context, |
| 364 | int argc, |
| 365 | sqlite3_value **argv |
| 366 | ){ |
| 367 | const char *zPattern = 0; |
| 368 | const char *zBegin = "<b>"; |
| 369 | const char *zEnd = "</b>"; |
| 370 | const char *zGap = " ... "; |
| 371 | unsigned int flg = SRCHFLG_HTML; |
| 372 | switch( argc ){ |
| 373 | default: |
| 374 | flg = (unsigned int)sqlite3_value_int(argv[4]); |
| @@ -745,11 +745,11 @@ | |
| 745 | "INSERT INTO x(label,url,score,date,snip) " |
| 746 | " SELECT ftsdocs.label," |
| 747 | " ftsdocs.url," |
| 748 | " rank(matchinfo(ftsidx,'pcsx'))," |
| 749 | " datetime(ftsdocs.mtime)," |
| 750 | " snippet(ftsidx)" |
| 751 | " FROM ftsidx, ftsdocs" |
| 752 | " WHERE ftsidx MATCH %Q" |
| 753 | " AND ftsdocs.rowid=ftsidx.docid", |
| 754 | zPattern |
| 755 | ); |
| 756 |
| --- src/search.c | |
| +++ src/search.c | |
| @@ -363,12 +363,12 @@ | |
| 363 | sqlite3_context *context, |
| 364 | int argc, |
| 365 | sqlite3_value **argv |
| 366 | ){ |
| 367 | const char *zPattern = 0; |
| 368 | const char *zBegin = "<mark>"; |
| 369 | const char *zEnd = "</mark>"; |
| 370 | const char *zGap = " ... "; |
| 371 | unsigned int flg = SRCHFLG_HTML; |
| 372 | switch( argc ){ |
| 373 | default: |
| 374 | flg = (unsigned int)sqlite3_value_int(argv[4]); |
| @@ -745,11 +745,11 @@ | |
| 745 | "INSERT INTO x(label,url,score,date,snip) " |
| 746 | " SELECT ftsdocs.label," |
| 747 | " ftsdocs.url," |
| 748 | " rank(matchinfo(ftsidx,'pcsx'))," |
| 749 | " datetime(ftsdocs.mtime)," |
| 750 | " snippet(ftsidx,'<mark>','</mark>')" |
| 751 | " FROM ftsidx, ftsdocs" |
| 752 | " WHERE ftsidx MATCH %Q" |
| 753 | " AND ftsdocs.rowid=ftsidx.docid", |
| 754 | zPattern |
| 755 | ); |
| 756 |
+31
-2
| --- src/style.c | ||
| +++ src/style.c | ||
| @@ -1125,10 +1125,15 @@ | ||
| 1125 | 1125 | }, |
| 1126 | 1126 | { "th.sort.desc:after", |
| 1127 | 1127 | "Descending sort column marker", |
| 1128 | 1128 | @ content: '\2191'; |
| 1129 | 1129 | }, |
| 1130 | + { "mark", | |
| 1131 | + "Search markup", | |
| 1132 | + @ background-color: inherit; | |
| 1133 | + @ font-weight: bold; | |
| 1134 | + }, | |
| 1130 | 1135 | { 0, |
| 1131 | 1136 | 0, |
| 1132 | 1137 | 0 |
| 1133 | 1138 | } |
| 1134 | 1139 | }; |
| @@ -1149,23 +1154,47 @@ | ||
| 1149 | 1154 | ); |
| 1150 | 1155 | } |
| 1151 | 1156 | } |
| 1152 | 1157 | } |
| 1153 | 1158 | |
| 1159 | +/* | |
| 1160 | +** Search string zHaystack for zNeedle. zNeedle must be an isolated | |
| 1161 | +** word with space or punctuation on either size. | |
| 1162 | +** | |
| 1163 | +** Return true if found. Return false if not found | |
| 1164 | +*/ | |
| 1165 | +static int containsString(const char *zHaystack, const char *zNeedle){ | |
| 1166 | + char *z; | |
| 1167 | + int n; | |
| 1168 | + | |
| 1169 | + while( zHaystack[0] ){ | |
| 1170 | + z = strstr(zHaystack, zNeedle); | |
| 1171 | + if( z==0 ) return 0; | |
| 1172 | + n = (int)strlen(zNeedle); | |
| 1173 | + if( (z==zHaystack || !fossil_isalnum(z[-1])) && !fossil_isalnum(z[n]) ){ | |
| 1174 | + return 1; | |
| 1175 | + } | |
| 1176 | + zHaystack = z + n; | |
| 1177 | + } | |
| 1178 | + return 0; | |
| 1179 | +} | |
| 1180 | + | |
| 1181 | + | |
| 1154 | 1182 | /* |
| 1155 | 1183 | ** WEBPAGE: style.css |
| 1156 | 1184 | */ |
| 1157 | 1185 | void page_style_css(void){ |
| 1158 | 1186 | Blob css; |
| 1159 | 1187 | int i; |
| 1160 | 1188 | |
| 1161 | 1189 | cgi_set_content_type("text/css"); |
| 1162 | - blob_init(&css, db_get("css",(char*)builtin_text("skins/default/css.txt")), -1); | |
| 1190 | + blob_init(&css,db_get("css",(char*)builtin_text("skins/default/css.txt")),-1); | |
| 1163 | 1191 | |
| 1164 | 1192 | /* add special missing definitions */ |
| 1165 | 1193 | for(i=1; cssDefaultList[i].elementClass; i++){ |
| 1166 | - if( strstr(blob_str(&css), cssDefaultList[i].elementClass)==0 ){ | |
| 1194 | + char *z = blob_str(&css); | |
| 1195 | + if( !containsString(z, cssDefaultList[i].elementClass) ){ | |
| 1167 | 1196 | blob_appendf(&css, "/* %s */\n%s {\n%s}\n", |
| 1168 | 1197 | cssDefaultList[i].comment, |
| 1169 | 1198 | cssDefaultList[i].elementClass, |
| 1170 | 1199 | cssDefaultList[i].value); |
| 1171 | 1200 | } |
| 1172 | 1201 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1125,10 +1125,15 @@ | |
| 1125 | }, |
| 1126 | { "th.sort.desc:after", |
| 1127 | "Descending sort column marker", |
| 1128 | @ content: '\2191'; |
| 1129 | }, |
| 1130 | { 0, |
| 1131 | 0, |
| 1132 | 0 |
| 1133 | } |
| 1134 | }; |
| @@ -1149,23 +1154,47 @@ | |
| 1149 | ); |
| 1150 | } |
| 1151 | } |
| 1152 | } |
| 1153 | |
| 1154 | /* |
| 1155 | ** WEBPAGE: style.css |
| 1156 | */ |
| 1157 | void page_style_css(void){ |
| 1158 | Blob css; |
| 1159 | int i; |
| 1160 | |
| 1161 | cgi_set_content_type("text/css"); |
| 1162 | blob_init(&css, db_get("css",(char*)builtin_text("skins/default/css.txt")), -1); |
| 1163 | |
| 1164 | /* add special missing definitions */ |
| 1165 | for(i=1; cssDefaultList[i].elementClass; i++){ |
| 1166 | if( strstr(blob_str(&css), cssDefaultList[i].elementClass)==0 ){ |
| 1167 | blob_appendf(&css, "/* %s */\n%s {\n%s}\n", |
| 1168 | cssDefaultList[i].comment, |
| 1169 | cssDefaultList[i].elementClass, |
| 1170 | cssDefaultList[i].value); |
| 1171 | } |
| 1172 |
| --- src/style.c | |
| +++ src/style.c | |
| @@ -1125,10 +1125,15 @@ | |
| 1125 | }, |
| 1126 | { "th.sort.desc:after", |
| 1127 | "Descending sort column marker", |
| 1128 | @ content: '\2191'; |
| 1129 | }, |
| 1130 | { "mark", |
| 1131 | "Search markup", |
| 1132 | @ background-color: inherit; |
| 1133 | @ font-weight: bold; |
| 1134 | }, |
| 1135 | { 0, |
| 1136 | 0, |
| 1137 | 0 |
| 1138 | } |
| 1139 | }; |
| @@ -1149,23 +1154,47 @@ | |
| 1154 | ); |
| 1155 | } |
| 1156 | } |
| 1157 | } |
| 1158 | |
| 1159 | /* |
| 1160 | ** Search string zHaystack for zNeedle. zNeedle must be an isolated |
| 1161 | ** word with space or punctuation on either size. |
| 1162 | ** |
| 1163 | ** Return true if found. Return false if not found |
| 1164 | */ |
| 1165 | static int containsString(const char *zHaystack, const char *zNeedle){ |
| 1166 | char *z; |
| 1167 | int n; |
| 1168 | |
| 1169 | while( zHaystack[0] ){ |
| 1170 | z = strstr(zHaystack, zNeedle); |
| 1171 | if( z==0 ) return 0; |
| 1172 | n = (int)strlen(zNeedle); |
| 1173 | if( (z==zHaystack || !fossil_isalnum(z[-1])) && !fossil_isalnum(z[n]) ){ |
| 1174 | return 1; |
| 1175 | } |
| 1176 | zHaystack = z + n; |
| 1177 | } |
| 1178 | return 0; |
| 1179 | } |
| 1180 | |
| 1181 | |
| 1182 | /* |
| 1183 | ** WEBPAGE: style.css |
| 1184 | */ |
| 1185 | void page_style_css(void){ |
| 1186 | Blob css; |
| 1187 | int i; |
| 1188 | |
| 1189 | cgi_set_content_type("text/css"); |
| 1190 | blob_init(&css,db_get("css",(char*)builtin_text("skins/default/css.txt")),-1); |
| 1191 | |
| 1192 | /* add special missing definitions */ |
| 1193 | for(i=1; cssDefaultList[i].elementClass; i++){ |
| 1194 | char *z = blob_str(&css); |
| 1195 | if( !containsString(z, cssDefaultList[i].elementClass) ){ |
| 1196 | blob_appendf(&css, "/* %s */\n%s {\n%s}\n", |
| 1197 | cssDefaultList[i].comment, |
| 1198 | cssDefaultList[i].elementClass, |
| 1199 | cssDefaultList[i].value); |
| 1200 | } |
| 1201 |