github.com/elves/elvish@v0.15.0/website/cmd/macros/macros.go (about)

     1  // The macros program implements an ad-hoc preprocessor for Markdown files, used
     2  // in Elvish's website.
     3  package main
     4  
     5  import (
     6  	"bufio"
     7  	"bytes"
     8  	"fmt"
     9  	"io/ioutil"
    10  	"log"
    11  	"os"
    12  	"path"
    13  	"strings"
    14  )
    15  
    16  const (
    17  	ttyshot = "@ttyshot "
    18  	cf      = "@cf "
    19  	dl      = "@dl "
    20  )
    21  
    22  func main() {
    23  	scanner := bufio.NewScanner(os.Stdin)
    24  	for scanner.Scan() {
    25  		line := scanner.Text()
    26  		line = expandTtyshot(line)
    27  		line = expandCf(line)
    28  		line = expandDl(line)
    29  		fmt.Println(line)
    30  	}
    31  }
    32  
    33  func expandTtyshot(line string) string {
    34  	i := strings.Index(line, ttyshot)
    35  	if i < 0 {
    36  		return line
    37  	}
    38  	name := line[i+len(ttyshot):]
    39  	content, err := ioutil.ReadFile(path.Join("ttyshot", name+".html"))
    40  	if err != nil {
    41  		log.Fatal(err)
    42  	}
    43  	var buf bytes.Buffer
    44  	buf.WriteString(line[:i])
    45  	buf.WriteString(`<pre class="ttyshot"><code>`)
    46  	buf.Write(bytes.Replace(
    47  		content, []byte("\n"), []byte("<br>"), -1))
    48  	buf.WriteString("</code></pre>")
    49  	return buf.String()
    50  }
    51  
    52  func expandCf(line string) string {
    53  	i := strings.Index(line, cf)
    54  	if i < 0 {
    55  		return line
    56  	}
    57  	targets := strings.Split(line[i+len(cf):], " ")
    58  	var buf strings.Builder
    59  	buf.WriteString("See also")
    60  	for i, target := range targets {
    61  		if i == 0 {
    62  			buf.WriteString(" ")
    63  		} else if i == len(targets)-1 {
    64  			buf.WriteString(" and ")
    65  		} else {
    66  			buf.WriteString(", ")
    67  		}
    68  		fmt.Fprintf(&buf, "[`%s`](%s)", target, cfHref(target))
    69  	}
    70  	buf.WriteString(".")
    71  	return buf.String()
    72  }
    73  
    74  // Returns the href for a `@cf` reference.
    75  func cfHref(target string) string {
    76  	i := strings.IndexRune(target, ':')
    77  	if i == -1 {
    78  		// A link within the builtin page. Use unqualified name (e.g. #put).
    79  		return "#" + target
    80  	}
    81  
    82  	module, symbol := target[:i], target[i+1:]
    83  	if module == "builtin" {
    84  		// A link from outside the builtin page to the builtin page. Use
    85  		// unqualified name (e.g. #put).
    86  		return "builtin.html#" + symbol
    87  	}
    88  	// A link to a non-builtin page. The section names are always qualified
    89  	// names (e.g str:join), but pandoc strips the colons from the anchor (e.g.
    90  	// #strjoin).
    91  	return module + ".html#" + strings.ReplaceAll(target, ":", "")
    92  }
    93  
    94  func expandDl(line string) string {
    95  	i := strings.Index(line, dl)
    96  	if i < 0 {
    97  		return line
    98  	}
    99  	fields := strings.SplitN(line[i+len(dl):], " ", 2)
   100  	name := fields[0]
   101  	url := name
   102  	if len(fields) == 2 {
   103  		url = fields[1]
   104  	}
   105  	return line[:i] + fmt.Sprintf(
   106  		`<a href="https://dl.elv.sh/%s">%s</a>`, url, name)
   107  }