github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/markup/console/console.go (about)

     1  // Copyright 2023 The GitBundle Inc. All rights reserved.
     2  // Copyright 2017 The Gitea Authors. All rights reserved.
     3  // Use of this source code is governed by a MIT-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package console
     7  
     8  import (
     9  	"bytes"
    10  	"io"
    11  	"path/filepath"
    12  	"regexp"
    13  	"strings"
    14  
    15  	"github.com/gitbundle/modules/markup"
    16  	"github.com/gitbundle/modules/setting"
    17  
    18  	trend "github.com/buildkite/terminal-to-html/v3"
    19  	"github.com/go-enry/go-enry/v2"
    20  )
    21  
    22  // MarkupName describes markup's name
    23  var MarkupName = "console"
    24  
    25  func init() {
    26  	markup.RegisterRenderer(Renderer{})
    27  }
    28  
    29  // Renderer implements markup.Renderer
    30  type Renderer struct{}
    31  
    32  // Name implements markup.Renderer
    33  func (Renderer) Name() string {
    34  	return MarkupName
    35  }
    36  
    37  // Extensions implements markup.Renderer
    38  func (Renderer) Extensions() []string {
    39  	return []string{".sh-session"}
    40  }
    41  
    42  // SanitizerRules implements markup.Renderer
    43  func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
    44  	return []setting.MarkupSanitizerRule{
    45  		{Element: "span", AllowAttr: "class", Regexp: regexp.MustCompile(`^term-((fg[ix]?|bg)\d+|container)$`)},
    46  	}
    47  }
    48  
    49  // CanRender implements markup.RendererContentDetector
    50  func (Renderer) CanRender(filename string, input io.Reader) bool {
    51  	buf, err := io.ReadAll(input)
    52  	if err != nil {
    53  		return false
    54  	}
    55  	if enry.GetLanguage(filepath.Base(filename), buf) != enry.OtherLanguage {
    56  		return false
    57  	}
    58  	return bytes.ContainsRune(buf, '\x1b')
    59  }
    60  
    61  // Render renders terminal colors to HTML with all specific handling stuff.
    62  func (Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
    63  	buf, err := io.ReadAll(input)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	buf = trend.Render(buf)
    68  	buf = bytes.ReplaceAll(buf, []byte("\n"), []byte(`<br>`))
    69  	_, err = output.Write(buf)
    70  	return err
    71  }
    72  
    73  // Render renders terminal colors to HTML with all specific handling stuff.
    74  func Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
    75  	if ctx.Type == "" {
    76  		ctx.Type = MarkupName
    77  	}
    78  	return markup.Render(ctx, input, output)
    79  }
    80  
    81  // RenderString renders terminal colors in string to HTML with all specific handling stuff and return string
    82  func RenderString(ctx *markup.RenderContext, content string) (string, error) {
    83  	var buf strings.Builder
    84  	if err := Render(ctx, strings.NewReader(content), &buf); err != nil {
    85  		return "", err
    86  	}
    87  	return buf.String(), nil
    88  }