add html rendering
parent
5868ae2f13
commit
7e4456450c
|
@ -22,6 +22,7 @@ var configList = []string{
|
||||||
"publish to html",
|
"publish to html",
|
||||||
"publish to gopher",
|
"publish to gopher",
|
||||||
"default to nopub",
|
"default to nopub",
|
||||||
|
"default to html",
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
|
@ -52,6 +53,10 @@ visible from your gopherhole, and will be purged from your gophermap on your
|
||||||
next entry update.`,
|
next entry update.`,
|
||||||
`should your posts automatically show up on your world-visible pages, such as
|
`should your posts automatically show up on your world-visible pages, such as
|
||||||
html and gopher? you can change this behaviour on a per-post basis after the
|
html and gopher? you can change this behaviour on a per-post basis after the
|
||||||
|
fact. changes to this setting will not be made retroactively.`,
|
||||||
|
`should your posts automatically be parsed as html in the neofeels reader?
|
||||||
|
this is not related to the html publishing option, and only applies to the
|
||||||
|
terminal reader. you can change this behaviour on a per-post basis after the
|
||||||
fact. changes to this setting will not be made retroactively.`,
|
fact. changes to this setting will not be made retroactively.`,
|
||||||
`in which directory under public_html should your blog reside? for example,
|
`in which directory under public_html should your blog reside? for example,
|
||||||
"blog" will make it visible under https://tilde.town/~you/blog.`,
|
"blog" will make it visible under https://tilde.town/~you/blog.`,
|
||||||
|
@ -75,12 +80,6 @@ func (config *Config) Event(state *ui.State, event vaxis.Event) (processed bool)
|
||||||
case "0", "1":
|
case "0", "1":
|
||||||
i, _ := strconv.Atoi(key.String())
|
i, _ := strconv.Atoi(key.String())
|
||||||
config.list.SetIndex(i)
|
config.list.SetIndex(i)
|
||||||
case "2", "3":
|
|
||||||
if config.config.Publishing {
|
|
||||||
|
|
||||||
i, _ := strconv.Atoi(key.String())
|
|
||||||
config.list.SetIndex(i)
|
|
||||||
}
|
|
||||||
case "q", "h", "Left":
|
case "q", "h", "Left":
|
||||||
ui.ViewChange <- NewMainMenu(6)
|
ui.ViewChange <- NewMainMenu(6)
|
||||||
case "Enter", "l", "Right", "Space":
|
case "Enter", "l", "Right", "Space":
|
||||||
|
@ -92,6 +91,8 @@ func (config *Config) Event(state *ui.State, event vaxis.Event) (processed bool)
|
||||||
case 2:
|
case 2:
|
||||||
config.config.Nopub = !config.config.Nopub
|
config.config.Nopub = !config.config.Nopub
|
||||||
case 3:
|
case 3:
|
||||||
|
config.config.HTML = !config.config.HTML
|
||||||
|
case 4:
|
||||||
config.config.PublishDir = config.changePublishDir(state)
|
config.config.PublishDir = config.changePublishDir(state)
|
||||||
}
|
}
|
||||||
config.config.Write()
|
config.config.Write()
|
||||||
|
@ -116,17 +117,18 @@ func (config *Config) Draw(state *ui.State) {
|
||||||
Column: win.Width/2 - 21,
|
Column: win.Width/2 - 21,
|
||||||
Row: win.Height/2 - 2,
|
Row: win.Height/2 - 2,
|
||||||
Width: 28,
|
Width: 28,
|
||||||
Height: 4,
|
Height: 5,
|
||||||
})
|
})
|
||||||
win.New(win.Width/2-40, win.Height/2+3, 80, 10).Print(vaxis.Segment{Text: config.descriptions[config.list.Index()]})
|
win.New(win.Width/2-40, win.Height/2+4, 80, 10).Print(vaxis.Segment{Text: config.descriptions[config.list.Index()]})
|
||||||
win.New(win.Width/2-15, win.Height/2+13, 30, 1).Print(vaxis.Segment{Text: config.help})
|
win.New(win.Width/2-15, win.Height/2+14, 30, 1).Print(vaxis.Segment{Text: config.help})
|
||||||
|
|
||||||
// drawing the current selected options
|
// drawing the current selected options
|
||||||
win.New(win.Width/2+7, win.Height/2-2, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.Publishing)})
|
win.New(win.Width/2+7, win.Height/2-2, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.Publishing)})
|
||||||
win.New(win.Width/2+7, win.Height/2-1, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.Gopher)})
|
win.New(win.Width/2+7, win.Height/2-1, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.Gopher)})
|
||||||
win.New(win.Width/2+7, win.Height/2, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.Nopub)})
|
win.New(win.Width/2+7, win.Height/2, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.Nopub)})
|
||||||
|
win.New(win.Width/2+7, win.Height/2+1, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.HTML)})
|
||||||
if config.config.Publishing {
|
if config.config.Publishing {
|
||||||
win.New(win.Width/2+7, win.Height/2+1, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.PublishDir)})
|
win.New(win.Width/2+7, win.Height/2+2, 14, 1).Print(vaxis.Segment{Text: fmt.Sprintf(" %-12v", config.config.PublishDir)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +141,7 @@ func (config *Config) changePublishDir(state *ui.State) string {
|
||||||
Vx: win.Vx,
|
Vx: win.Vx,
|
||||||
Parent: &win,
|
Parent: &win,
|
||||||
Column: win.Width/2 + 9,
|
Column: win.Width/2 + 9,
|
||||||
Row: win.Height/2 + 1,
|
Row: win.Height/2 + 2,
|
||||||
Width: 12,
|
Width: 12,
|
||||||
Height: 1,
|
Height: 1,
|
||||||
})
|
})
|
||||||
|
@ -158,7 +160,7 @@ func (config *Config) changePublishDir(state *ui.State) string {
|
||||||
Vx: win.Vx,
|
Vx: win.Vx,
|
||||||
Parent: nil,
|
Parent: nil,
|
||||||
Column: win.Width/2 + 9,
|
Column: win.Width/2 + 9,
|
||||||
Row: win.Height/2 + 1,
|
Row: win.Height/2 + 2,
|
||||||
Width: 12,
|
Width: 12,
|
||||||
Height: 1,
|
Height: 1,
|
||||||
})
|
})
|
||||||
|
|
|
@ -28,20 +28,23 @@ func NewPublishing() *Publishing {
|
||||||
return &Publishing{
|
return &Publishing{
|
||||||
title,
|
title,
|
||||||
ui.NewList(list, 0),
|
ui.NewList(list, 0),
|
||||||
"↑↓/kj move ↵ enter q return",
|
"↑↓/kj move n nopub m html q return",
|
||||||
posts,
|
posts,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatPublishing(post ttbp.Post) string {
|
func formatPublishing(post ttbp.Post) string {
|
||||||
nopub := ""
|
status := ""
|
||||||
if post.Nopub {
|
if post.Nopub {
|
||||||
nopub = "(nopub)"
|
status += "(nopub) "
|
||||||
|
}
|
||||||
|
if post.HTML {
|
||||||
|
status += "(html)"
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"%s %s",
|
"%s %s",
|
||||||
post.Date.Format("2006-01-02"),
|
post.Date.Format("2006-01-02"),
|
||||||
nopub,
|
status,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,12 +67,18 @@ func (publishing *Publishing) Event(state *ui.State, event vaxis.Event) (process
|
||||||
case "q", "h", "Left":
|
case "q", "h", "Left":
|
||||||
ttbp.Publish()
|
ttbp.Publish()
|
||||||
ui.ViewChange <- NewManagement(1)
|
ui.ViewChange <- NewManagement(1)
|
||||||
case "Enter", "l", "Right":
|
case "n":
|
||||||
if len(publishing.list.Items()) > 0 {
|
if len(publishing.list.Items()) > 0 {
|
||||||
publishing.posts[publishing.list.Index()].Nopub = !publishing.posts[publishing.list.Index()].Nopub
|
publishing.posts[publishing.list.Index()].Nopub = !publishing.posts[publishing.list.Index()].Nopub
|
||||||
ttbp.ToggleNopub(publishing.posts[publishing.list.Index()].Date)
|
ttbp.ToggleNopub(publishing.posts[publishing.list.Index()].Date)
|
||||||
publishing.list.SetItem(publishing.list.Index(), formatPublishing(publishing.posts[publishing.list.Index()]))
|
publishing.list.SetItem(publishing.list.Index(), formatPublishing(publishing.posts[publishing.list.Index()]))
|
||||||
}
|
}
|
||||||
|
case "m":
|
||||||
|
if len(publishing.list.Items()) > 0 {
|
||||||
|
publishing.posts[publishing.list.Index()].HTML = !publishing.posts[publishing.list.Index()].HTML
|
||||||
|
ttbp.ToggleHTML(publishing.posts[publishing.list.Index()].Date)
|
||||||
|
publishing.list.SetItem(publishing.list.Index(), formatPublishing(publishing.posts[publishing.list.Index()]))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
processed = true
|
processed = true
|
||||||
}
|
}
|
||||||
|
@ -83,10 +92,10 @@ func (publishing *Publishing) Draw(state *ui.State) {
|
||||||
publishing.list.Draw(vaxis.Window{
|
publishing.list.Draw(vaxis.Window{
|
||||||
Vx: win.Vx,
|
Vx: win.Vx,
|
||||||
Parent: nil,
|
Parent: nil,
|
||||||
Column: win.Width/2 - 14,
|
Column: win.Width/2 - 15,
|
||||||
Row: win.Height/2 - 2,
|
Row: win.Height/2 - 2,
|
||||||
Width: 28,
|
Width: 30,
|
||||||
Height: 10,
|
Height: 10,
|
||||||
})
|
})
|
||||||
win.New(win.Width/2-15, win.Height/2+9, 30, 1).Print(vaxis.Segment{Text: publishing.help})
|
win.New(win.Width/2-19, win.Height/2+9, 38, 1).Print(vaxis.Segment{Text: publishing.help})
|
||||||
}
|
}
|
||||||
|
|
10
app/user.go
10
app/user.go
|
@ -94,11 +94,19 @@ func showPost(state *ui.State, post ttbp.Post) {
|
||||||
vt.TERM = os.Getenv("TERM")
|
vt.TERM = os.Getenv("TERM")
|
||||||
vt.Attach(state.PostEvent())
|
vt.Attach(state.PostEvent())
|
||||||
vt.Focus()
|
vt.Focus()
|
||||||
|
|
||||||
pager := os.ExpandEnv(os.Getenv("PAGER"))
|
pager := os.ExpandEnv(os.Getenv("PAGER"))
|
||||||
if pager == "" {
|
if pager == "" {
|
||||||
pager = "less"
|
pager = "less"
|
||||||
}
|
}
|
||||||
err := vt.Start(exec.Command(pager, path.Join("/home", post.Author, ".ttbp/entries", post.Date.Format("20060102")+".txt")))
|
|
||||||
|
prepro := "cat"
|
||||||
|
if post.HTML {
|
||||||
|
prepro = "lynx -dump -force_html"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := fmt.Sprintf("%s %s | %s", prepro, path.Join("/home", post.Author, ".ttbp/entries", post.Date.Format("20060102")+".txt"), pager)
|
||||||
|
err := vt.Start(exec.Command("sh", "-c", cmd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ type Config struct {
|
||||||
PublishDir string `json:"publish dir"`
|
PublishDir string `json:"publish dir"`
|
||||||
Publishing bool `json:"publishing"`
|
Publishing bool `json:"publishing"`
|
||||||
Rainbows bool `json:"rainbows"` // we don't care about this
|
Rainbows bool `json:"rainbows"` // we don't care about this
|
||||||
|
HTML bool `json:"html"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var Default = &Config{
|
var Default = &Config{
|
||||||
|
@ -22,6 +23,7 @@ var Default = &Config{
|
||||||
PublishDir: "blog",
|
PublishDir: "blog",
|
||||||
Publishing: false,
|
Publishing: false,
|
||||||
Rainbows: false,
|
Rainbows: false,
|
||||||
|
HTML: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
func Read() (config *Config, err error) {
|
func Read() (config *Config, err error) {
|
||||||
|
|
126
ttbp/ttbp.go
126
ttbp/ttbp.go
|
@ -17,24 +17,25 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
PathVar = "/var/global/ttbp"
|
PathVar = "/var/global/ttbp"
|
||||||
PathVarWWW = path.Join(PathVar, "www")
|
PathVarWWW = path.Join(PathVar, "www")
|
||||||
PathLive = "https://tilde.town/~"
|
PathLive = "https://tilde.town/~"
|
||||||
PathUserFile = path.Join(PathVar, "users.txt")
|
PathUserFile = path.Join(PathVar, "users.txt")
|
||||||
PathGraff = path.Join(PathVar, "graffiti")
|
PathGraff = path.Join(PathVar, "graffiti")
|
||||||
PathWall = path.Join(PathGraff, "wall.txt")
|
PathWall = path.Join(PathGraff, "wall.txt")
|
||||||
PathWallLock = path.Join(PathGraff, ".lock")
|
PathWallLock = path.Join(PathGraff, ".lock")
|
||||||
PathUser = os.Getenv("HOME")
|
PathUser = os.Getenv("HOME")
|
||||||
PathUserFeels = path.Join(PathUser, ".ttbp")
|
PathUserFeels = path.Join(PathUser, ".ttbp")
|
||||||
PathUserHTML = path.Join(PathUser, "public_html")
|
PathUserHTML = path.Join(PathUser, "public_html")
|
||||||
PathUserConfig = path.Join(PathUserFeels, "config")
|
PathUserConfig = path.Join(PathUserFeels, "config")
|
||||||
PathUserEntries = path.Join(PathUserFeels, "entries")
|
PathUserEntries = path.Join(PathUserFeels, "entries")
|
||||||
PathUserBuried = path.Join(PathUserFeels, "buried")
|
PathUserBuried = path.Join(PathUserFeels, "buried")
|
||||||
PathUserBackups = path.Join(PathUserFeels, "backups")
|
PathUserBackups = path.Join(PathUserFeels, "backups")
|
||||||
PathUserWWW = path.Join(PathUserFeels, "www")
|
PathUserWWW = path.Join(PathUserFeels, "www")
|
||||||
PathUserRc = path.Join(PathUserConfig, "ttbprc")
|
PathUserRc = path.Join(PathUserConfig, "ttbprc")
|
||||||
PathUserNopub = path.Join(PathUserConfig, "nopub")
|
PathUserNopub = path.Join(PathUserConfig, "nopub")
|
||||||
PathUserSubs = path.Join(PathUserConfig, "subs")
|
PathUserHTMLRender = path.Join(PathUserConfig, "html")
|
||||||
|
PathUserSubs = path.Join(PathUserConfig, "subs")
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
|
@ -103,6 +104,7 @@ type Post struct {
|
||||||
Words int
|
Words int
|
||||||
Author string
|
Author string
|
||||||
Nopub bool
|
Nopub bool
|
||||||
|
HTML bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPostsForUser(user string) (posts []Post) {
|
func GetPostsForUser(user string) (posts []Post) {
|
||||||
|
@ -110,6 +112,7 @@ func GetPostsForUser(user string) (posts []Post) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nopubFile, err := os.OpenFile(PathUserNopub, os.O_RDONLY|os.O_CREATE, 0644)
|
nopubFile, err := os.OpenFile(PathUserNopub, os.O_RDONLY|os.O_CREATE, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -120,6 +123,18 @@ func GetPostsForUser(user string) (posts []Post) {
|
||||||
for nopubScanner.Scan() {
|
for nopubScanner.Scan() {
|
||||||
nopubs = append(nopubs, nopubScanner.Text())
|
nopubs = append(nopubs, nopubScanner.Text())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
htmlFile, err := os.OpenFile(PathUserHTMLRender, os.O_RDONLY|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer htmlFile.Close()
|
||||||
|
var htmls []string
|
||||||
|
htmlScanner := bufio.NewScanner(htmlFile)
|
||||||
|
for htmlScanner.Scan() {
|
||||||
|
htmls = append(htmls, htmlScanner.Text())
|
||||||
|
}
|
||||||
|
|
||||||
for _, post := range postFiles {
|
for _, post := range postFiles {
|
||||||
// retrieve date of file
|
// retrieve date of file
|
||||||
// assume file ends in .txt
|
// assume file ends in .txt
|
||||||
|
@ -154,12 +169,22 @@ func GetPostsForUser(user string) (posts []Post) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// see if file is in html
|
||||||
|
html := false
|
||||||
|
for _, name := range htmls {
|
||||||
|
if name == post.Name() {
|
||||||
|
html = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
posts = append([]Post{Post{
|
posts = append([]Post{Post{
|
||||||
Author: user,
|
Author: user,
|
||||||
Date: fileDate,
|
Date: fileDate,
|
||||||
LastEdited: stat.ModTime(),
|
LastEdited: stat.ModTime(),
|
||||||
Words: count,
|
Words: count,
|
||||||
Nopub: nopub,
|
Nopub: nopub,
|
||||||
|
HTML: html,
|
||||||
}}, posts...)
|
}}, posts...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,6 +327,71 @@ func ToggleNopub(t time.Time) {
|
||||||
writer.Flush()
|
writer.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewHTML(t time.Time) {
|
||||||
|
cfg, err := config.Read()
|
||||||
|
if err != nil || (!cfg.HTML) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dateString := t.Format("20060102.txt")
|
||||||
|
file, err := os.OpenFile(PathUserHTMLRender, os.O_RDWR|os.O_CREATE, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(file)
|
||||||
|
for scanner.Scan() {
|
||||||
|
if scanner.Text() == dateString {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer := bufio.NewWriter(file)
|
||||||
|
writer.WriteString(dateString)
|
||||||
|
writer.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToggleHTML(t time.Time) {
|
||||||
|
dateString := t.Format("20060102.txt")
|
||||||
|
htmls, err := os.ReadFile(PathUserHTMLRender)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(strings.TrimSpace(string(htmls)), "\n")
|
||||||
|
|
||||||
|
newLines := []string{}
|
||||||
|
exists := false
|
||||||
|
for _, line := range lines {
|
||||||
|
if line == dateString {
|
||||||
|
exists = true
|
||||||
|
} else {
|
||||||
|
newLines = append(newLines, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !exists {
|
||||||
|
newLines = append(newLines, dateString)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(PathUserHTMLRender)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
writer := bufio.NewWriter(file)
|
||||||
|
for _, line := range newLines {
|
||||||
|
if line == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_, err := writer.WriteString(line + "\n")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
func Publish() {
|
func Publish() {
|
||||||
cfg, err := config.Read()
|
cfg, err := config.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue