github.com/getgauge/gauge@v1.6.9/build/man/man.go (about)

     1  /*----------------------------------------------------------------
     2   *  Copyright (c) ThoughtWorks, Inc.
     3   *  Licensed under the Apache License, Version 2.0
     4   *  See LICENSE in the project root for license information.
     5   *----------------------------------------------------------------*/
     6  
     7  package main
     8  
     9  import (
    10  	"log"
    11  
    12  	"strings"
    13  
    14  	"os"
    15  	"path/filepath"
    16  
    17  	"math"
    18  
    19  	"github.com/getgauge/common"
    20  	"github.com/getgauge/gauge/cmd"
    21  	"github.com/russross/blackfriday/v2"
    22  	"github.com/spf13/cobra"
    23  	"github.com/spf13/cobra/doc"
    24  )
    25  
    26  const (
    27  	maxDescLength = 46
    28  	maxLineLength = 77
    29  )
    30  
    31  type text struct {
    32  	name    string
    33  	content string
    34  }
    35  
    36  func main() {
    37  	mdPath := filepath.Join("_man", "md")
    38  	htmlPath := filepath.Join("_man", "html")
    39  	createDir(mdPath)
    40  	createDir(htmlPath)
    41  	if err := genMarkdownManPages(mdPath); err != nil {
    42  		log.Fatal(err.Error())
    43  	}
    44  	texts := indentText(mdPath)
    45  	for _, t := range texts {
    46  		name := strings.TrimSuffix(t.name, filepath.Ext(t.name)) + ".html"
    47  		output := strings.Replace(html, "<!--CONTENT-->", string(blackfriday.Run([]byte(t.content))), -1)
    48  		p := filepath.Join(htmlPath, name)
    49  		err := os.WriteFile(p, []byte(output), 0644)
    50  		if err != nil {
    51  			log.Fatalf("Unable to write file %s: %s", p, err.Error())
    52  		}
    53  	}
    54  	log.Printf("HTML man pages are available in %s dir\n", htmlPath)
    55  }
    56  func createDir(p string) {
    57  	if err := os.MkdirAll(p, common.NewDirectoryPermissions); err != nil {
    58  		log.Fatal(err.Error())
    59  	}
    60  }
    61  
    62  func genMarkdownManPages(out string) error {
    63  	if err := doc.GenMarkdownTree(setupCmd(), out); err != nil {
    64  		return err
    65  	}
    66  	log.Printf("Added markdown man pages to `%s`\n", out)
    67  	return nil
    68  }
    69  
    70  func setupCmd() *cobra.Command {
    71  	cmd.GaugeCmd.Short = "A light-weight cross-platform test automation tool"
    72  	cmd.GaugeCmd.Long = "Gauge is a light-weight cross-platform test automation tool with the ability to author test cases in the business language."
    73  	return cmd.GaugeCmd
    74  }
    75  
    76  func indentText(p string) (texts []text) {
    77  	err := filepath.Walk(p, func(path string, info os.FileInfo, err error) error {
    78  		if strings.HasSuffix(info.Name(), ".md") {
    79  			bytes, err := os.ReadFile(path)
    80  			if err != nil {
    81  				return err
    82  			}
    83  			var lines []string
    84  			for _, l := range strings.Split(string(bytes), string("\n")) {
    85  				tLine := strings.TrimSpace(l)
    86  				if strings.HasPrefix(tLine, "-") && len(tLine) > maxLineLength {
    87  					lines = append(lines, indentFlag(l, tLine)...)
    88  				} else {
    89  					lines = append(lines, strings.Replace(l, ".md", ".html", -1))
    90  				}
    91  			}
    92  			texts = append(texts, text{name: info.Name(), content: strings.Join(lines, "\n")})
    93  		}
    94  		return nil
    95  	})
    96  	if err != nil {
    97  		log.Fatal(err.Error())
    98  	}
    99  
   100  	return
   101  }
   102  
   103  func indentFlag(line, tLine string) (lines []string) {
   104  	words := strings.Split(tLine, "  ")
   105  	desc := strings.TrimSpace(words[len(words)-1])
   106  	dWords := strings.Split(desc, " ")
   107  	times := math.Ceil(float64(len(desc)) / maxDescLength)
   108  	for i := 0; float64(i) < times; i++ {
   109  		till := 0
   110  		length := 0
   111  		for i, v := range dWords {
   112  			length += len(v)
   113  			if length > maxDescLength {
   114  				till = i - 1
   115  				break
   116  			}
   117  			if i == len(dWords)-1 {
   118  				till = len(dWords)
   119  			}
   120  		}
   121  		if len(dWords) == 0 {
   122  			continue
   123  		}
   124  		prefix := strings.Replace(line, desc, strings.Join(dWords[:till], " "), -1)
   125  		if i != 0 {
   126  			prefix = strings.Repeat(" ", strings.Index(line, desc)) + strings.Join(dWords[:till], " ")
   127  		}
   128  		lines = append(lines, prefix)
   129  		dWords = dWords[till:]
   130  	}
   131  	return
   132  }
   133  
   134  const html = `
   135  <!DOCTYPE html>
   136  <html>
   137  
   138  <head>
   139      <title>Gauge - Manual</title>
   140      <link href="https://gauge.org/assets/images/favicons/favicon.ico" rel="shortcut icon" type="image/ico" />
   141      <style type='text/css' media='all'>
   142          body#manpage {
   143              margin: 0;
   144              border-top: 3px solid #f5c10e;
   145          }
   146  
   147          .mp {
   148              max-width: 100ex;
   149              padding: 0 9ex 1ex 4ex;
   150              margin-top: 1.5%;
   151          }
   152  
   153          .mp p,
   154          .mp pre,
   155          .mp ul,
   156          .mp ol,
   157          .mp dl {
   158              margin: 0 0 20px 0;
   159          }
   160  
   161          .mp h2 {
   162              margin: 10px 0 0 0
   163          }
   164  
   165          .mp h3 {
   166              margin: 0 0 0 0;
   167          }
   168  
   169          .mp dt {
   170              margin: 0;
   171              clear: left
   172          }
   173  
   174          .mp dt.flush {
   175              float: left;
   176              width: 8ex
   177          }
   178  
   179          .mp dd {
   180              margin: 0 0 0 9ex
   181          }
   182  
   183          .mp h1,
   184          .mp h2,
   185          .mp h3,
   186          .mp h4 {
   187              clear: left
   188          }
   189  
   190          .mp pre {
   191              margin-bottom: 20px;
   192          }
   193  
   194          .mp pre+h2,
   195          .mp pre+h3 {
   196              margin-top: 22px
   197          }
   198  
   199          .mp h2+pre,
   200          .mp h3+pre {
   201              margin-top: 5px
   202          }
   203  
   204          .mp img {
   205              display: block;
   206              margin: auto
   207          }
   208  
   209          .mp h1.man-title {
   210              display: none
   211          }
   212  
   213          .mp,
   214          .mp code,
   215          .mp pre,
   216          .mp tt,
   217          .mp kbd,
   218          .mp samp,
   219          .mp h3,
   220          .mp h4 {
   221              font-family: monospace;
   222              font-size: 14px;
   223              line-height: 1.42857142857143
   224          }
   225  
   226          .mp h2 {
   227              font-size: 16px;
   228              line-height: 1.25
   229          }
   230  
   231          .mp h1 {
   232              font-size: 20px;
   233              line-height: 2
   234          }
   235  
   236          .mp {
   237              text-align: justify;
   238              background: #fff
   239          }
   240  
   241          .mp,
   242          .mp code,
   243          .mp pre,
   244          .mp pre code,
   245          .mp tt,
   246          .mp kbd,
   247          .mp samp {
   248              color: #131211
   249          }
   250  
   251          .mp h1,
   252          .mp h2,
   253          .mp h3,
   254          .mp h4 {
   255              color: #030201
   256          }
   257  
   258          .mp u {
   259              text-decoration: underline
   260          }
   261  
   262          .mp code,
   263          .mp strong,
   264          .mp b {
   265              font-weight: bold;
   266              color: #131211
   267          }
   268  
   269          .mp em,
   270          .mp var {
   271              font-style: italic;
   272              color: #232221;
   273              text-decoration: none
   274          }
   275  
   276          .mp a,
   277          .mp a:link,
   278          .mp a:hover,
   279          .mp a code,
   280          .mp a pre,
   281          .mp a tt,
   282          .mp a kbd,
   283          .mp a samp {
   284              color: #0000ff
   285          }
   286  
   287          .mp b.man-ref {
   288              font-weight: normal;
   289              color: #434241
   290          }
   291  
   292          .mp pre code {
   293              font-weight: normal;
   294              color: #434241
   295          }
   296  
   297          .mp h2+pre,
   298          h3+pre {
   299              padding-left: 0
   300          }
   301  
   302          ol.man-decor,
   303          ol.man-decor li {
   304              margin: 3px 0 10px 0;
   305              padding: 0;
   306              float: left;
   307              width: 33%;
   308              list-style-type: none;
   309              text-transform: uppercase;
   310              color: #999;
   311              letter-spacing: 1px;
   312          }
   313  
   314          ol.man-decor {
   315              width: 100%;
   316          }
   317  
   318          ol.man-decor li.tl {
   319              text-align: left;
   320          }
   321  
   322          ol.man-decor li.tc {
   323              text-align: center;
   324              letter-spacing: 4px;
   325          }
   326  
   327          ol.man-decor li.tr {
   328              text-align: right;
   329              float: right;
   330          }
   331      </style>
   332  </head>
   333  
   334  <body id='manpage'>
   335      <div class='mp' id='man'>
   336          <!--CONTENT-->
   337  		<div><b>Complete documentation is available <a href="https://docs.gauge.org/">here</a>.</b></div>
   338      </div>
   339  
   340  </body>
   341  
   342  </html>
   343  `