Fossil

Check-in [71992d0f08]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enhance built-in help text formatting so that text contained within [[...]] is a hyperlink to another help page.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 71992d0f081df4cbad1a8432cb268cd931660c8a992c52d615fb1d7f790b8070
User & Date: drh 2020-08-08 20:13:56.671
Context
2020-08-08
23:51
Many updates to built-in help pages. No changes to code. check-in: c965636958 user: drh tags: trunk
20:13
Enhance built-in help text formatting so that text contained within [[...]] is a hyperlink to another help page. check-in: 71992d0f08 user: drh tags: trunk
18:19
Fix typo in built-in documentation for "fossil open". check-in: 9ec3274f35 user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/clone.c.
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
**    --private                  Also clone private branches
**    --save-http-password       Remember the HTTP password without asking
**    --ssh-command|-c SSH       Use SSH as the "ssh" command
**    --ssl-identity FILENAME    Use the SSL identity if requested by the server
**    -u|--unversioned           Also sync unversioned content
**    -v|--verbose               Show more statistics in output
**
** See also: init
*/
void clone_cmd(void){
  char *zPassword;
  const char *zDefaultUser;   /* Optional name of the default user */
  const char *zHttpAuth;      /* HTTP Authorization user:pass information */
  int nErr = 0;
  int urlFlags = URL_PROMPT_PW | URL_REMEMBER;







|







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
**    --private                  Also clone private branches
**    --save-http-password       Remember the HTTP password without asking
**    --ssh-command|-c SSH       Use SSH as the "ssh" command
**    --ssl-identity FILENAME    Use the SSL identity if requested by the server
**    -u|--unversioned           Also sync unversioned content
**    -v|--verbose               Show more statistics in output
**
** See also: [[init]], [[open]]
*/
void clone_cmd(void){
  char *zPassword;
  const char *zDefaultUser;   /* Optional name of the default user */
  const char *zHttpAuth;      /* HTTP Authorization user:pass information */
  int nErr = 0;
  int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
Changes to src/db.c.
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
**
** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
** year-month-day form, it may be truncated, the "T" may be replaced by
** a space, and it may also name a timezone offset from UTC as "-HH:MM"
** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
** means UTC.
**
** See also: clone
*/
void create_repository_cmd(void){
  char *zPassword;
  const char *zTemplate;      /* Repository from which to copy settings */
  const char *zDate;          /* Date of the initial check-in */
  const char *zDefaultUser;   /* Optional name of the default user */
  int bUseSha1 = 0;           /* True to set the hash-policy to sha1 */







|







2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
**
** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
** year-month-day form, it may be truncated, the "T" may be replaced by
** a space, and it may also name a timezone offset from UTC as "-HH:MM"
** (westward) or "+HH:MM" (eastward). Either no timezone suffix or "Z"
** means UTC.
**
** See also: [[clone]]
*/
void create_repository_cmd(void){
  char *zPassword;
  const char *zTemplate;      /* Repository from which to copy settings */
  const char *zDate;          /* Date of the initial check-in */
  const char *zDefaultUser;   /* Optional name of the default user */
  int bUseSha1 = 0;           /* True to set the hash-policy to sha1 */
3086
3087
3088
3089
3090
3091
3092

3093
3094
3095
3096
3097
3098
3099
3100
** for the repository is created with its root at the current working
** directory, or in DIR if the "--workdir DIR" is used.  If VERSION is
** specified then that version is checked out.  Otherwise the most recent
** check-in on the main branch (usually "trunk") is used.
**
** REPOSITORY can be the filename for a repository that already exists on the
** local machine or it can be a URI for a remote repository.  If REPOSITORY

** is a URI, the remote repo is first cloned, then the clone is opened.
** The clone will be stored in the current directory, or in an alternative
** directory specified by the --repodir option.  The name of the clone will
** be taken from the last term of the URI.  For http: and https: URIs, you
** can append an extra term on the end to get any repository name you like.
** For example:
**
**     fossil open https://fossil-scm.org/home/new-name







>
|







3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
** for the repository is created with its root at the current working
** directory, or in DIR if the "--workdir DIR" is used.  If VERSION is
** specified then that version is checked out.  Otherwise the most recent
** check-in on the main branch (usually "trunk") is used.
**
** REPOSITORY can be the filename for a repository that already exists on the
** local machine or it can be a URI for a remote repository.  If REPOSITORY
** is a URI in one of the formats recognized by the [[clone]] command, then
** remote repo is first cloned, then the clone is opened.
** The clone will be stored in the current directory, or in an alternative
** directory specified by the --repodir option.  The name of the clone will
** be taken from the last term of the URI.  For http: and https: URIs, you
** can append an extra term on the end to get any repository name you like.
** For example:
**
**     fossil open https://fossil-scm.org/home/new-name
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
**                     the clone in DIR rather than in "."
**   --setmtime        Set timestamps of all files to match their SCM-side
**                     times (the timestamp of the last checkin which modified
**                     them).
**   --workdir DIR     Use DIR as the working directory instead of ".". The DIR
**                     directory is created if it does not previously exist.
**
** See also: close
*/
void cmd_open(void){
  int emptyFlag;
  int keepFlag;
  int forceMissingFlag;
  int allowNested;
  int allowSymlinks;







|







3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
**                     the clone in DIR rather than in "."
**   --setmtime        Set timestamps of all files to match their SCM-side
**                     times (the timestamp of the last checkin which modified
**                     them).
**   --workdir DIR     Use DIR as the working directory instead of ".". The DIR
**                     directory is created if it does not previously exist.
**
** See also: [[close]], [[clone]]
*/
void cmd_open(void){
  int emptyFlag;
  int keepFlag;
  int forceMissingFlag;
  int allowNested;
  int allowSymlinks;
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
**
** Options:
**   --global   set or unset the given property globally instead of
**              setting or unsetting it for the open repository only.
**
**   --exact    only consider exact name matches.
**
** See also: configuration
*/
void setting_cmd(void){
  int i;
  int globalFlag = find_option("global","g",0)!=0;
  int exactFlag = find_option("exact",0,0)!=0;
  int unsetFlag = g.argv[1][0]=='u';
  int nSetting;







|







3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
**
** Options:
**   --global   set or unset the given property globally instead of
**              setting or unsetting it for the open repository only.
**
**   --exact    only consider exact name matches.
**
** See also: [[configuration]]
*/
void setting_cmd(void){
  int i;
  int globalFlag = find_option("global","g",0)!=0;
  int exactFlag = find_option("exact",0,0)!=0;
  int unsetFlag = g.argv[1][0]=='u';
  int nSetting;
Changes to src/dispatch.c.
261
262
263
264
265
266
267






































268
269
270
271
272
273
274
      while( j<n && z[j]!=' ' && z[j]!='=' ){ j++; }
      blob_appendf(pOut, "%#h", j-i, z+i);
      if( zEnd[0] ) blob_append(pOut, zEnd, -1);
      i = j;
    }
  }
}







































/*
** Attempt to reformat plain-text help into HTML for display on a webpage.
**
** The HTML output is appended to Blob pHtml, which should already be
** initialized.
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
      while( j<n && z[j]!=' ' && z[j]!='=' ){ j++; }
      blob_appendf(pOut, "%#h", j-i, z+i);
      if( zEnd[0] ) blob_append(pOut, zEnd, -1);
      i = j;
    }
  }
}

/*
** Input string zIn starts with '['.  If the content is a hyperlink of the
** form [[...]] then return the index of the closing ']'.  Otherwise return 0.
*/
static int help_is_link(const char *z, int n){
  int i;
  char c;
  if( n<5 ) return 0;
  if( z[1]!='[' ) return 0;
  for(i=3; i<n && (c = z[i])!=0; i++){
    if( c==']' && z[i-1]==']' ) return i;
  }
  return 0;
}

/*
** Append text to pOut, adding hyperlink markup for [...].
*/
static void appendLinked(Blob *pOut, const char *z, int n){
  int i = 0;
  int j;
  while( i<n ){
    if( z[i]=='[' && (j = help_is_link(z+i, n-i))>0 ){
      if( i ) blob_append(pOut, z, i);
      z += i+2;
      n -= i+2;
      blob_appendf(pOut, "<a href='%R/help?cmd=%.*s'>%.*s</a>",
         j-3, z, j-3, z);
      z += j-1;
      n -= j-1;
      i = 0;
    }else{
      i++;
    }
  }
  blob_append(pOut, z, i);
}

/*
** Attempt to reformat plain-text help into HTML for display on a webpage.
**
** The HTML output is appended to Blob pHtml, which should already be
** initialized.
**
392
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430








431
432
433
434
435
436
437
        blob_append(pHtml, "</dt>\n", 6);
      }
    }else if( wantBR ){
      appendMixedFont(pHtml, zHelp+nIndent, i-nIndent);
      blob_append(pHtml, "<br>\n", 5);
      wantBR = 0;
    }else{
      blob_appendf(pHtml, "%#h\n", i-nIndent, zHelp+nIndent);

    }
    zHelp += i+1;
    i = 0;
    if( c==0 ) break;
  }
  while( iLevel>0 ){
    blob_appendf(pHtml, "%s\n", azEnd[iLevel--]);
  }
}

/*
** Format help text for TTY display.
*/
static void help_to_text(const char *zHelp, Blob *pText){
  int i;
  char c;
  for(i=0; (c = zHelp[i])!=0; i++){
    if( c=='%' && strncmp(zHelp+i,"%fossil",7)==0 ){
      if( i>0 ) blob_append(pText, zHelp, i);
      blob_append(pText, "fossil", 6);
      zHelp += i+7;
      i = -1;
      continue;
    }
    if( c=='\n' && strncmp(zHelp+i+1,"> ",2)==0 ){
      blob_append(pText, zHelp, i+1);
      blob_append(pText, " ", 1);
      zHelp += i+2;
      i = -1;
      continue;
    }








  }
  if( i>0 ){
    blob_append(pText, zHelp, i);
  }      
}

/*







|
>














|
















>
>
>
>
>
>
>
>







430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
        blob_append(pHtml, "</dt>\n", 6);
      }
    }else if( wantBR ){
      appendMixedFont(pHtml, zHelp+nIndent, i-nIndent);
      blob_append(pHtml, "<br>\n", 5);
      wantBR = 0;
    }else{
      appendLinked(pHtml, zHelp+nIndent, i-nIndent);
      blob_append_char(pHtml, '\n');
    }
    zHelp += i+1;
    i = 0;
    if( c==0 ) break;
  }
  while( iLevel>0 ){
    blob_appendf(pHtml, "%s\n", azEnd[iLevel--]);
  }
}

/*
** Format help text for TTY display.
*/
static void help_to_text(const char *zHelp, Blob *pText){
  int i, x;
  char c;
  for(i=0; (c = zHelp[i])!=0; i++){
    if( c=='%' && strncmp(zHelp+i,"%fossil",7)==0 ){
      if( i>0 ) blob_append(pText, zHelp, i);
      blob_append(pText, "fossil", 6);
      zHelp += i+7;
      i = -1;
      continue;
    }
    if( c=='\n' && strncmp(zHelp+i+1,"> ",2)==0 ){
      blob_append(pText, zHelp, i+1);
      blob_append(pText, " ", 1);
      zHelp += i+2;
      i = -1;
      continue;
    }
    if( c=='[' && (x = help_is_link(zHelp+i, 100000))!=0 ){
      if( i>0 ) blob_append(pText, zHelp, i);
      zHelp += i+2;
      blob_append(pText, zHelp, x-3);
      zHelp += x-1;
      i = -1;
      continue;
    }     
  }
  if( i>0 ){
    blob_append(pText, zHelp, i);
  }      
}

/*
445
446
447
448
449
450
451

452
453
454
455
456

457
458
459
460
461
462
463
**
** Options:
**    -e|--everything   Show all commands and pages.
**    -t|--test         Include test- commands
**    -w|--www          Show WWW pages.
**    -s|--settings     Show settings.
**    -h|--html         Transform output to HTML.

*/
void test_all_help_cmd(void){
  int i;
  int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER;
  int useHtml = find_option("html","h",0)!=0;


  if( find_option("www","w",0) ){
    mask = CMDFLAG_WEBPAGE;
  }
  if( find_option("everything","e",0) ){
    mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER | CMDFLAG_WEBPAGE |
              CMDFLAG_SETTING | CMDFLAG_TEST;







>





>







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
**
** Options:
**    -e|--everything   Show all commands and pages.
**    -t|--test         Include test- commands
**    -w|--www          Show WWW pages.
**    -s|--settings     Show settings.
**    -h|--html         Transform output to HTML.
**    -r|--raw          No output formatting.
*/
void test_all_help_cmd(void){
  int i;
  int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER;
  int useHtml = find_option("html","h",0)!=0;
  int rawOut = find_option("raw","r",0)!=0;

  if( find_option("www","w",0) ){
    mask = CMDFLAG_WEBPAGE;
  }
  if( find_option("everything","e",0) ){
    mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER | CMDFLAG_WEBPAGE |
              CMDFLAG_SETTING | CMDFLAG_TEST;
486
487
488
489
490
491
492



493
494
495
496
497
498
499
    if( useHtml ){
      Blob html;
      blob_init(&html, 0, 0);
      help_to_html(aCommand[i].zHelp, &html);
      fossil_print("<h1>%h</h1>\n", aCommand[i].zName);
      fossil_print("%s\n<hr>\n", blob_str(&html));
      blob_reset(&html);



    }else{
      Blob txt;
      blob_init(&txt, 0, 0);
      help_to_text(aCommand[i].zHelp, &txt);
      fossil_print("# %s\n", aCommand[i].zName);
      fossil_print("%s\n\n", blob_str(&txt));
      blob_reset(&txt);







>
>
>







535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
    if( useHtml ){
      Blob html;
      blob_init(&html, 0, 0);
      help_to_html(aCommand[i].zHelp, &html);
      fossil_print("<h1>%h</h1>\n", aCommand[i].zName);
      fossil_print("%s\n<hr>\n", blob_str(&html));
      blob_reset(&html);
    }else if( rawOut ){
      fossil_print("# %s\n", aCommand[i].zName);
      fossil_print("%s\n\n", aCommand[i].zHelp);
    }else{
      Blob txt;
      blob_init(&txt, 0, 0);
      help_to_text(aCommand[i].zHelp, &txt);
      fossil_print("# %s\n", aCommand[i].zName);
      fossil_print("%s\n\n", blob_str(&txt));
      blob_reset(&txt);