Fossil SCM

Enhance built-in help text formatting so that text contained within [[...]] is a hyperlink to another help page.

drh 2020-08-08 20:13 trunk
Commit 71992d0f081df4cbad1a8432cb268cd931660c8a992c52d615fb1d7f790b8070
3 files changed +1 -1 +5 -4 +54 -2
+1 -1
--- src/clone.c
+++ src/clone.c
@@ -123,11 +123,11 @@
123123
** --ssh-command|-c SSH Use SSH as the "ssh" command
124124
** --ssl-identity FILENAME Use the SSL identity if requested by the server
125125
** -u|--unversioned Also sync unversioned content
126126
** -v|--verbose Show more statistics in output
127127
**
128
-** See also: init
128
+** See also: [[init]], [[open]]
129129
*/
130130
void clone_cmd(void){
131131
char *zPassword;
132132
const char *zDefaultUser; /* Optional name of the default user */
133133
const char *zHttpAuth; /* HTTP Authorization user:pass information */
134134
--- src/clone.c
+++ src/clone.c
@@ -123,11 +123,11 @@
123 ** --ssh-command|-c SSH Use SSH as the "ssh" command
124 ** --ssl-identity FILENAME Use the SSL identity if requested by the server
125 ** -u|--unversioned Also sync unversioned content
126 ** -v|--verbose Show more statistics in output
127 **
128 ** See also: init
129 */
130 void clone_cmd(void){
131 char *zPassword;
132 const char *zDefaultUser; /* Optional name of the default user */
133 const char *zHttpAuth; /* HTTP Authorization user:pass information */
134
--- src/clone.c
+++ src/clone.c
@@ -123,11 +123,11 @@
123 ** --ssh-command|-c SSH Use SSH as the "ssh" command
124 ** --ssl-identity FILENAME Use the SSL identity if requested by the server
125 ** -u|--unversioned Also sync unversioned content
126 ** -v|--verbose Show more statistics in output
127 **
128 ** See also: [[init]], [[open]]
129 */
130 void clone_cmd(void){
131 char *zPassword;
132 const char *zDefaultUser; /* Optional name of the default user */
133 const char *zHttpAuth; /* HTTP Authorization user:pass information */
134
+5 -4
--- src/db.c
+++ src/db.c
@@ -2396,11 +2396,11 @@
23962396
** year-month-day form, it may be truncated, the "T" may be replaced by
23972397
** a space, and it may also name a timezone offset from UTC as "-HH:MM"
23982398
** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
23992399
** means UTC.
24002400
**
2401
-** See also: clone
2401
+** See also: [[clone]]
24022402
*/
24032403
void create_repository_cmd(void){
24042404
char *zPassword;
24052405
const char *zTemplate; /* Repository from which to copy settings */
24062406
const char *zDate; /* Date of the initial check-in */
@@ -3088,11 +3088,12 @@
30883088
** specified then that version is checked out. Otherwise the most recent
30893089
** check-in on the main branch (usually "trunk") is used.
30903090
**
30913091
** REPOSITORY can be the filename for a repository that already exists on the
30923092
** local machine or it can be a URI for a remote repository. If REPOSITORY
3093
-** is a URI, the remote repo is first cloned, then the clone is opened.
3093
+** is a URI in one of the formats recognized by the [[clone]] command, then
3094
+** remote repo is first cloned, then the clone is opened.
30943095
** The clone will be stored in the current directory, or in an alternative
30953096
** directory specified by the --repodir option. The name of the clone will
30963097
** be taken from the last term of the URI. For http: and https: URIs, you
30973098
** can append an extra term on the end to get any repository name you like.
30983099
** For example:
@@ -3118,11 +3119,11 @@
31183119
** times (the timestamp of the last checkin which modified
31193120
** them).
31203121
** --workdir DIR Use DIR as the working directory instead of ".". The DIR
31213122
** directory is created if it does not previously exist.
31223123
**
3123
-** See also: close
3124
+** See also: [[close]], [[clone]]
31243125
*/
31253126
void cmd_open(void){
31263127
int emptyFlag;
31273128
int keepFlag;
31283129
int forceMissingFlag;
@@ -3996,11 +3997,11 @@
39963997
** --global set or unset the given property globally instead of
39973998
** setting or unsetting it for the open repository only.
39983999
**
39994000
** --exact only consider exact name matches.
40004001
**
4001
-** See also: configuration
4002
+** See also: [[configuration]]
40024003
*/
40034004
void setting_cmd(void){
40044005
int i;
40054006
int globalFlag = find_option("global","g",0)!=0;
40064007
int exactFlag = find_option("exact",0,0)!=0;
40074008
--- src/db.c
+++ src/db.c
@@ -2396,11 +2396,11 @@
2396 ** year-month-day form, it may be truncated, the "T" may be replaced by
2397 ** a space, and it may also name a timezone offset from UTC as "-HH:MM"
2398 ** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
2399 ** means UTC.
2400 **
2401 ** See also: clone
2402 */
2403 void create_repository_cmd(void){
2404 char *zPassword;
2405 const char *zTemplate; /* Repository from which to copy settings */
2406 const char *zDate; /* Date of the initial check-in */
@@ -3088,11 +3088,12 @@
3088 ** specified then that version is checked out. Otherwise the most recent
3089 ** check-in on the main branch (usually "trunk") is used.
3090 **
3091 ** REPOSITORY can be the filename for a repository that already exists on the
3092 ** local machine or it can be a URI for a remote repository. If REPOSITORY
3093 ** is a URI, the remote repo is first cloned, then the clone is opened.
 
3094 ** The clone will be stored in the current directory, or in an alternative
3095 ** directory specified by the --repodir option. The name of the clone will
3096 ** be taken from the last term of the URI. For http: and https: URIs, you
3097 ** can append an extra term on the end to get any repository name you like.
3098 ** For example:
@@ -3118,11 +3119,11 @@
3118 ** times (the timestamp of the last checkin which modified
3119 ** them).
3120 ** --workdir DIR Use DIR as the working directory instead of ".". The DIR
3121 ** directory is created if it does not previously exist.
3122 **
3123 ** See also: close
3124 */
3125 void cmd_open(void){
3126 int emptyFlag;
3127 int keepFlag;
3128 int forceMissingFlag;
@@ -3996,11 +3997,11 @@
3996 ** --global set or unset the given property globally instead of
3997 ** setting or unsetting it for the open repository only.
3998 **
3999 ** --exact only consider exact name matches.
4000 **
4001 ** See also: configuration
4002 */
4003 void setting_cmd(void){
4004 int i;
4005 int globalFlag = find_option("global","g",0)!=0;
4006 int exactFlag = find_option("exact",0,0)!=0;
4007
--- src/db.c
+++ src/db.c
@@ -2396,11 +2396,11 @@
2396 ** year-month-day form, it may be truncated, the "T" may be replaced by
2397 ** a space, and it may also name a timezone offset from UTC as "-HH:MM"
2398 ** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
2399 ** means UTC.
2400 **
2401 ** See also: [[clone]]
2402 */
2403 void create_repository_cmd(void){
2404 char *zPassword;
2405 const char *zTemplate; /* Repository from which to copy settings */
2406 const char *zDate; /* Date of the initial check-in */
@@ -3088,11 +3088,12 @@
3088 ** specified then that version is checked out. Otherwise the most recent
3089 ** check-in on the main branch (usually "trunk") is used.
3090 **
3091 ** REPOSITORY can be the filename for a repository that already exists on the
3092 ** local machine or it can be a URI for a remote repository. If REPOSITORY
3093 ** is a URI in one of the formats recognized by the [[clone]] command, then
3094 ** remote repo is first cloned, then the clone is opened.
3095 ** The clone will be stored in the current directory, or in an alternative
3096 ** directory specified by the --repodir option. The name of the clone will
3097 ** be taken from the last term of the URI. For http: and https: URIs, you
3098 ** can append an extra term on the end to get any repository name you like.
3099 ** For example:
@@ -3118,11 +3119,11 @@
3119 ** times (the timestamp of the last checkin which modified
3120 ** them).
3121 ** --workdir DIR Use DIR as the working directory instead of ".". The DIR
3122 ** directory is created if it does not previously exist.
3123 **
3124 ** See also: [[close]], [[clone]]
3125 */
3126 void cmd_open(void){
3127 int emptyFlag;
3128 int keepFlag;
3129 int forceMissingFlag;
@@ -3996,11 +3997,11 @@
3997 ** --global set or unset the given property globally instead of
3998 ** setting or unsetting it for the open repository only.
3999 **
4000 ** --exact only consider exact name matches.
4001 **
4002 ** See also: [[configuration]]
4003 */
4004 void setting_cmd(void){
4005 int i;
4006 int globalFlag = find_option("global","g",0)!=0;
4007 int exactFlag = find_option("exact",0,0)!=0;
4008
+54 -2
--- src/dispatch.c
+++ src/dispatch.c
@@ -263,10 +263,48 @@
263263
if( zEnd[0] ) blob_append(pOut, zEnd, -1);
264264
i = j;
265265
}
266266
}
267267
}
268
+
269
+/*
270
+** Input string zIn starts with '['. If the content is a hyperlink of the
271
+** form [[...]] then return the index of the closing ']'. Otherwise return 0.
272
+*/
273
+static int help_is_link(const char *z, int n){
274
+ int i;
275
+ char c;
276
+ if( n<5 ) return 0;
277
+ if( z[1]!='[' ) return 0;
278
+ for(i=3; i<n && (c = z[i])!=0; i++){
279
+ if( c==']' && z[i-1]==']' ) return i;
280
+ }
281
+ return 0;
282
+}
283
+
284
+/*
285
+** Append text to pOut, adding hyperlink markup for [...].
286
+*/
287
+static void appendLinked(Blob *pOut, const char *z, int n){
288
+ int i = 0;
289
+ int j;
290
+ while( i<n ){
291
+ if( z[i]=='[' && (j = help_is_link(z+i, n-i))>0 ){
292
+ if( i ) blob_append(pOut, z, i);
293
+ z += i+2;
294
+ n -= i+2;
295
+ blob_appendf(pOut, "<a href='%R/help?cmd=%.*s'>%.*s</a>",
296
+ j-3, z, j-3, z);
297
+ z += j-1;
298
+ n -= j-1;
299
+ i = 0;
300
+ }else{
301
+ i++;
302
+ }
303
+ }
304
+ blob_append(pOut, z, i);
305
+}
268306
269307
/*
270308
** Attempt to reformat plain-text help into HTML for display on a webpage.
271309
**
272310
** The HTML output is appended to Blob pHtml, which should already be
@@ -394,11 +432,12 @@
394432
}else if( wantBR ){
395433
appendMixedFont(pHtml, zHelp+nIndent, i-nIndent);
396434
blob_append(pHtml, "<br>\n", 5);
397435
wantBR = 0;
398436
}else{
399
- blob_appendf(pHtml, "%#h\n", i-nIndent, zHelp+nIndent);
437
+ appendLinked(pHtml, zHelp+nIndent, i-nIndent);
438
+ blob_append_char(pHtml, '\n');
400439
}
401440
zHelp += i+1;
402441
i = 0;
403442
if( c==0 ) break;
404443
}
@@ -409,11 +448,11 @@
409448
410449
/*
411450
** Format help text for TTY display.
412451
*/
413452
static void help_to_text(const char *zHelp, Blob *pText){
414
- int i;
453
+ int i, x;
415454
char c;
416455
for(i=0; (c = zHelp[i])!=0; i++){
417456
if( c=='%' && strncmp(zHelp+i,"%fossil",7)==0 ){
418457
if( i>0 ) blob_append(pText, zHelp, i);
419458
blob_append(pText, "fossil", 6);
@@ -426,10 +465,18 @@
426465
blob_append(pText, " ", 1);
427466
zHelp += i+2;
428467
i = -1;
429468
continue;
430469
}
470
+ if( c=='[' && (x = help_is_link(zHelp+i, 100000))!=0 ){
471
+ if( i>0 ) blob_append(pText, zHelp, i);
472
+ zHelp += i+2;
473
+ blob_append(pText, zHelp, x-3);
474
+ zHelp += x-1;
475
+ i = -1;
476
+ continue;
477
+ }
431478
}
432479
if( i>0 ){
433480
blob_append(pText, zHelp, i);
434481
}
435482
}
@@ -447,15 +494,17 @@
447494
** -e|--everything Show all commands and pages.
448495
** -t|--test Include test- commands
449496
** -w|--www Show WWW pages.
450497
** -s|--settings Show settings.
451498
** -h|--html Transform output to HTML.
499
+** -r|--raw No output formatting.
452500
*/
453501
void test_all_help_cmd(void){
454502
int i;
455503
int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER;
456504
int useHtml = find_option("html","h",0)!=0;
505
+ int rawOut = find_option("raw","r",0)!=0;
457506
458507
if( find_option("www","w",0) ){
459508
mask = CMDFLAG_WEBPAGE;
460509
}
461510
if( find_option("everything","e",0) ){
@@ -488,10 +537,13 @@
488537
blob_init(&html, 0, 0);
489538
help_to_html(aCommand[i].zHelp, &html);
490539
fossil_print("<h1>%h</h1>\n", aCommand[i].zName);
491540
fossil_print("%s\n<hr>\n", blob_str(&html));
492541
blob_reset(&html);
542
+ }else if( rawOut ){
543
+ fossil_print("# %s\n", aCommand[i].zName);
544
+ fossil_print("%s\n\n", aCommand[i].zHelp);
493545
}else{
494546
Blob txt;
495547
blob_init(&txt, 0, 0);
496548
help_to_text(aCommand[i].zHelp, &txt);
497549
fossil_print("# %s\n", aCommand[i].zName);
498550
--- src/dispatch.c
+++ src/dispatch.c
@@ -263,10 +263,48 @@
263 if( zEnd[0] ) blob_append(pOut, zEnd, -1);
264 i = j;
265 }
266 }
267 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
269 /*
270 ** Attempt to reformat plain-text help into HTML for display on a webpage.
271 **
272 ** The HTML output is appended to Blob pHtml, which should already be
@@ -394,11 +432,12 @@
394 }else if( wantBR ){
395 appendMixedFont(pHtml, zHelp+nIndent, i-nIndent);
396 blob_append(pHtml, "<br>\n", 5);
397 wantBR = 0;
398 }else{
399 blob_appendf(pHtml, "%#h\n", i-nIndent, zHelp+nIndent);
 
400 }
401 zHelp += i+1;
402 i = 0;
403 if( c==0 ) break;
404 }
@@ -409,11 +448,11 @@
409
410 /*
411 ** Format help text for TTY display.
412 */
413 static void help_to_text(const char *zHelp, Blob *pText){
414 int i;
415 char c;
416 for(i=0; (c = zHelp[i])!=0; i++){
417 if( c=='%' && strncmp(zHelp+i,"%fossil",7)==0 ){
418 if( i>0 ) blob_append(pText, zHelp, i);
419 blob_append(pText, "fossil", 6);
@@ -426,10 +465,18 @@
426 blob_append(pText, " ", 1);
427 zHelp += i+2;
428 i = -1;
429 continue;
430 }
 
 
 
 
 
 
 
 
431 }
432 if( i>0 ){
433 blob_append(pText, zHelp, i);
434 }
435 }
@@ -447,15 +494,17 @@
447 ** -e|--everything Show all commands and pages.
448 ** -t|--test Include test- commands
449 ** -w|--www Show WWW pages.
450 ** -s|--settings Show settings.
451 ** -h|--html Transform output to HTML.
 
452 */
453 void test_all_help_cmd(void){
454 int i;
455 int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER;
456 int useHtml = find_option("html","h",0)!=0;
 
457
458 if( find_option("www","w",0) ){
459 mask = CMDFLAG_WEBPAGE;
460 }
461 if( find_option("everything","e",0) ){
@@ -488,10 +537,13 @@
488 blob_init(&html, 0, 0);
489 help_to_html(aCommand[i].zHelp, &html);
490 fossil_print("<h1>%h</h1>\n", aCommand[i].zName);
491 fossil_print("%s\n<hr>\n", blob_str(&html));
492 blob_reset(&html);
 
 
 
493 }else{
494 Blob txt;
495 blob_init(&txt, 0, 0);
496 help_to_text(aCommand[i].zHelp, &txt);
497 fossil_print("# %s\n", aCommand[i].zName);
498
--- src/dispatch.c
+++ src/dispatch.c
@@ -263,10 +263,48 @@
263 if( zEnd[0] ) blob_append(pOut, zEnd, -1);
264 i = j;
265 }
266 }
267 }
268
269 /*
270 ** Input string zIn starts with '['. If the content is a hyperlink of the
271 ** form [[...]] then return the index of the closing ']'. Otherwise return 0.
272 */
273 static int help_is_link(const char *z, int n){
274 int i;
275 char c;
276 if( n<5 ) return 0;
277 if( z[1]!='[' ) return 0;
278 for(i=3; i<n && (c = z[i])!=0; i++){
279 if( c==']' && z[i-1]==']' ) return i;
280 }
281 return 0;
282 }
283
284 /*
285 ** Append text to pOut, adding hyperlink markup for [...].
286 */
287 static void appendLinked(Blob *pOut, const char *z, int n){
288 int i = 0;
289 int j;
290 while( i<n ){
291 if( z[i]=='[' && (j = help_is_link(z+i, n-i))>0 ){
292 if( i ) blob_append(pOut, z, i);
293 z += i+2;
294 n -= i+2;
295 blob_appendf(pOut, "<a href='%R/help?cmd=%.*s'>%.*s</a>",
296 j-3, z, j-3, z);
297 z += j-1;
298 n -= j-1;
299 i = 0;
300 }else{
301 i++;
302 }
303 }
304 blob_append(pOut, z, i);
305 }
306
307 /*
308 ** Attempt to reformat plain-text help into HTML for display on a webpage.
309 **
310 ** The HTML output is appended to Blob pHtml, which should already be
@@ -394,11 +432,12 @@
432 }else if( wantBR ){
433 appendMixedFont(pHtml, zHelp+nIndent, i-nIndent);
434 blob_append(pHtml, "<br>\n", 5);
435 wantBR = 0;
436 }else{
437 appendLinked(pHtml, zHelp+nIndent, i-nIndent);
438 blob_append_char(pHtml, '\n');
439 }
440 zHelp += i+1;
441 i = 0;
442 if( c==0 ) break;
443 }
@@ -409,11 +448,11 @@
448
449 /*
450 ** Format help text for TTY display.
451 */
452 static void help_to_text(const char *zHelp, Blob *pText){
453 int i, x;
454 char c;
455 for(i=0; (c = zHelp[i])!=0; i++){
456 if( c=='%' && strncmp(zHelp+i,"%fossil",7)==0 ){
457 if( i>0 ) blob_append(pText, zHelp, i);
458 blob_append(pText, "fossil", 6);
@@ -426,10 +465,18 @@
465 blob_append(pText, " ", 1);
466 zHelp += i+2;
467 i = -1;
468 continue;
469 }
470 if( c=='[' && (x = help_is_link(zHelp+i, 100000))!=0 ){
471 if( i>0 ) blob_append(pText, zHelp, i);
472 zHelp += i+2;
473 blob_append(pText, zHelp, x-3);
474 zHelp += x-1;
475 i = -1;
476 continue;
477 }
478 }
479 if( i>0 ){
480 blob_append(pText, zHelp, i);
481 }
482 }
@@ -447,15 +494,17 @@
494 ** -e|--everything Show all commands and pages.
495 ** -t|--test Include test- commands
496 ** -w|--www Show WWW pages.
497 ** -s|--settings Show settings.
498 ** -h|--html Transform output to HTML.
499 ** -r|--raw No output formatting.
500 */
501 void test_all_help_cmd(void){
502 int i;
503 int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER;
504 int useHtml = find_option("html","h",0)!=0;
505 int rawOut = find_option("raw","r",0)!=0;
506
507 if( find_option("www","w",0) ){
508 mask = CMDFLAG_WEBPAGE;
509 }
510 if( find_option("everything","e",0) ){
@@ -488,10 +537,13 @@
537 blob_init(&html, 0, 0);
538 help_to_html(aCommand[i].zHelp, &html);
539 fossil_print("<h1>%h</h1>\n", aCommand[i].zName);
540 fossil_print("%s\n<hr>\n", blob_str(&html));
541 blob_reset(&html);
542 }else if( rawOut ){
543 fossil_print("# %s\n", aCommand[i].zName);
544 fossil_print("%s\n\n", aCommand[i].zHelp);
545 }else{
546 Blob txt;
547 blob_init(&txt, 0, 0);
548 help_to_text(aCommand[i].zHelp, &txt);
549 fossil_print("# %s\n", aCommand[i].zName);
550

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button