- Backend Go: API REST, auth por token (Bearer + cookie HttpOnly), storage em disco com revisões content-addressed (estilo Git: hash, autor, data, diff, restauração) - Editor txt/md/html com preview, tags #tag, categorias, painel de histórico - Preferências: números de linha, marcador de coluna (padrão 80), quebra de linha, fonte/tamanho, 4 temas e colorização de sintaxe (overlay no textarea) - Frontend vanilla embutido via go:embed; Dockerfile multi-stage + docker-compose
57 lines
1.4 KiB
Go
57 lines
1.4 KiB
Go
// Package diffx gera diffs unificados no estilo Git a partir de strings.
|
|
package diffx
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/hexops/gotextdiff"
|
|
"github.com/hexops/gotextdiff/myers"
|
|
"github.com/hexops/gotextdiff/span"
|
|
)
|
|
|
|
// Unified devolve o diff unificado (contexto padrão de 3 linhas) entre
|
|
// before e after, rotulando os lados como oldName e newName.
|
|
func Unified(oldName, newName, before, after string) string {
|
|
if before == after {
|
|
return ""
|
|
}
|
|
edits := myers.ComputeEdits(span.URIFromPath(oldName), before, after)
|
|
unified := gotextdiff.ToUnified(oldName, newName, before, edits)
|
|
return fmt.Sprintf("%s", unified)
|
|
}
|
|
|
|
// Stats conta linhas adicionadas e removidas em um diff unificado já gerado.
|
|
func Stats(unified string) (added, removed int) {
|
|
for _, line := range splitLines(unified) {
|
|
switch {
|
|
case len(line) == 0:
|
|
case line[0] == '+' && !isHeader(line):
|
|
added++
|
|
case line[0] == '-' && !isHeader(line):
|
|
removed++
|
|
}
|
|
}
|
|
return added, removed
|
|
}
|
|
|
|
func isHeader(line string) bool {
|
|
// cabeçalhos de arquivo no formato "--- nome" / "+++ nome" começam com
|
|
// dois sinais; uma linha de conteúdo "++foo" é contada como adição.
|
|
return len(line) >= 3 && line[0] == line[1] && (line[0] == '+' || line[0] == '-')
|
|
}
|
|
|
|
func splitLines(s string) []string {
|
|
var out []string
|
|
start := 0
|
|
for i := range len(s) {
|
|
if s[i] == '\n' {
|
|
out = append(out, s[start:i])
|
|
start = i + 1
|
|
}
|
|
}
|
|
if start < len(s) {
|
|
out = append(out, s[start:])
|
|
}
|
|
return out
|
|
}
|