<commit_before>package view

import (
	"bytes"
	"fmt"
	"html/template"
	"io"
	"net/http"
	"path"
	"regexp"
	"strings"
)

// Renderer is a view which is set up on each request and renders the response to its writer
type Renderer struct {

	// The view rendering context
	context map[string]interface{}

	// The writer to write the context to
	writer http.ResponseWriter

	// The layout template to render in
	layout string

	// The template to render
	template string

	// The format to render with (html,json etc)
	format string

	// The status to render with
	status int

	// The request path
	path string
}

// RenderContext is the type passed in to New, which helps construct the rendering view
// Alternatively, you can use NewWithPath, which doesn't require a RenderContext
type RenderContext interface {
	Path() string
	RenderContext() map[string]interface{}
	Writer() http.ResponseWriter
}

// New creates a new Renderer
func New(c RenderContext) *Renderer {
	r := &Renderer{
		path:     c.Path(),
		layout:   "app/views/layout.html.got",
		template: "",
		format:   "text/html",
		status:   http.StatusOK,
		context:  c.RenderContext(),
		writer:   c.Writer(),
	}

	// This sets layout and template based on the view.path
	r.setDefaultTemplates()

	return r
}

// NewWithPath creates a new Renderer with a path and an http.ResponseWriter
func NewWithPath(p string, w http.ResponseWriter) *Renderer {
	r := &Renderer{
		path:     p,
		layout:   "app/views/layout.html.got",
		template: "",
		format:   "text/html",
		status:   http.StatusOK,
		context:  make(map[string]interface{}, 0),
		writer:   w,
	}

	// This sets layout and template based on the view.path
	r.setDefaultTemplates()

	return r
}

// Layout sets the layout used
func (r *Renderer) Layout(layout string) *Renderer {
	r.layout = layout
	return r
}

// Template sets the template used
func (r *Renderer) Template(template string) *Renderer {
	r.template = template
	return r
}

// Format sets the format used, e.g. text/html,
func (r *Renderer) Format(format string) *Renderer {
	r.format = format
	return r
}

// Path sets the request path on the renderer (used for choosing a default template)
func (r *Renderer) Path(p string) *Renderer {
	r.path = path.Clean(p)
	return r
}

// Status returns the Renderer status
func (r *Renderer) Status(status int) *Renderer {
	r.status = status
	return r
}

// Text sets the view content as text
func (r *Renderer) Text(content string) *Renderer {
	r.context["content"] = content
	return r
}

// HTML sets the view content as html (use with caution)
func (r *Renderer) HTML(content string) *Renderer {
	r.context["content"] = template.HTML(content)
	return r
}

// AddKey adds a key/value pair to context
func (r *Renderer) AddKey(key string, value interface{}) *Renderer {
	r.context[key] = value
	return r
}

// Context sets the entire context for rendering
func (r *Renderer) Context(c map[string]interface{}) *Renderer {
	r.context = c
	return r
}

// RenderToString renders our template into layout using our context and return a string
func (r *Renderer) RenderToString() (string, error) {
	var rendered bytes.Buffer

	// We require a template
	if len(r.template) > 0 {
		mu.RLock()
		t := scanner.Templates[r.template]
		mu.RUnlock()
		if t == nil {
			return "", fmt.Errorf("No such template found %s", r.template)
		}

		// Render the template to a buffer
		err := t.Render(&rendered, r.context)
		if err != nil {
			return "", err
		}

		// Render that buffer into the layout if we have one
		if len(r.layout) > 0 {
			r.context["content"] = template.HTML(rendered.String())

			mu.RLock()
			l := scanner.Templates[r.layout]
			mu.RUnlock()
			if l == nil {
				return "", fmt.Errorf("No such layout found %s", r.layout)
			}

			// Render the layout to the buffer<commit_msg>Added RenderToStringWithLayout to avoid possible clashes<commit_after>package view

import (
	"bytes"
	"fmt"
	"html/template"
	"io"
	"net/http"
	"path"
	"regexp"
	"strings"
)

// Renderer is a view which is set up on each request and renders the response to its writer
type Renderer struct {

	// The view rendering context
	context map[string]interface{}

	// The writer to write the context to
	writer http.ResponseWriter

	// The layout template to render in
	layout string

	// The template to render
	template string

	// The format to render with (html,json etc)
	format string

	// The status to render with
	status int

	// The request path
	path string
}

// RenderContext is the type passed in to New, which helps construct the rendering view
// Alternatively, you can use NewWithPath, which doesn't require a RenderContext
type RenderContext interface {
	Path() string
	RenderContext() map[string]interface{}
	Writer() http.ResponseWriter
}

// New creates a new Renderer
func New(c RenderContext) *Renderer {
	r := &Renderer{
		path:     c.Path(),
		layout:   "app/views/layout.html.got",
		template: "",
		format:   "text/html",
		status:   http.StatusOK,
		context:  c.RenderContext(),
		writer:   c.Writer(),
	}

	// This sets layout and template based on the view.path
	r.setDefaultTemplates()

	return r
}

// NewWithPath creates a new Renderer with a path and an http.ResponseWriter
func NewWithPath(p string, w http.ResponseWriter) *Renderer {
	r := &Renderer{
		path:     p,
		layout:   "app/views/layout.html.got",
		template: "",
		format:   "text/html",
		status:   http.StatusOK,
		context:  make(map[string]interface{}, 0),
		writer:   w,
	}

	// This sets layout and template based on the view.path
	r.setDefaultTemplates()

	return r
}

// Layout sets the layout used
func (r *Renderer) Layout(layout string) *Renderer {
	r.layout = layout
	return r
}

// Template sets the template used
func (r *Renderer) Template(template string) *Renderer {
	r.template = template
	return r
}

// Format sets the format used, e.g. text/html,
func (r *Renderer) Format(format string) *Renderer {
	r.format = format
	return r
}

// Path sets the request path on the renderer (used for choosing a default template)
func (r *Renderer) Path(p string) *Renderer {
	r.path = path.Clean(p)
	return r
}

// Status returns the Renderer status
func (r *Renderer) Status(status int) *Renderer {
	r.status = status
	return r
}

// Text sets the view content as text
func (r *Renderer) Text(content string) *Renderer {
	r.context["content"] = content
	return r
}

// HTML sets the view content as html (use with caution)
func (r *Renderer) HTML(content string) *Renderer {
	r.context["content"] = template.HTML(content)
	return r
}

// AddKey adds a key/value pair to context
func (r *Renderer) AddKey(key string, value interface{}) *Renderer {
	r.context[key] = value
	return r
}

// Context sets the entire context for rendering
func (r *Renderer) Context(c map[string]interface{}) *Renderer {
	r.context = c
	return r
}

// RenderToString renders our template into layout using our context and return a string
func (r *Renderer) RenderToString() (string, error) {

	content := ""

	if len(r.template) > 0 {
		mu.RLock()
		t := scanner.Templates[r.template]
		mu.RUnlock()
		if t == nil {
			return content, fmt.Errorf("No such template found %s", r.template)
		}

		var rendered bytes.Buffer
		err := t.Render(&rendered, r.context)
		if err != nil {
			return content, err
		}

		content = rendered.String()
	}

	return content, nil
}

// FIXME - test for side-effects then replace RenderToString with the layout version as a bug fix

// RenderToStringWithLayout renders our template into layout using our context and return a string
func (r *Renderer) RenderToStringWithLayout() (string, error) {
	var rendered bytes.Buffer

	// We require a template
	if len(r.template) > 0 {
		mu.RLock()
		t := scanner.Templates[r.template]
		mu.RUnlock()
		if t == nil {
			return "", fmt.Errorf("No such template found %s", r.template)
		}

		// Render the template to a buffer
		err := t.Render(&rendered, r.context)
		if err != nil {
			return "", err
		}

		// Render that buffer into the layout if we have one
		if len(r.layout) > 0 {
			r.context["content"] = template.HTML(rendered.String())

			mu.RLock()
			l := scanner.Templates[r.layout]
			mu.RUnlock()
			if l == nil {
				return "", fmt.Errorf("No such layout found %s", r.layout)
			}

			// Render the layout to the buffer
{'fraction_non_alphanumeric': 0.11203670167813594, 'fraction_numerical': 0.0008451044307618013, 'mean_word_length': 3.4899728997289974, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '279595', 'n_tokens_mistral': 2731, 'n_tokens_neox': 2582, 'n_words': 968}