minor changes
This commit is contained in:
@@ -261,7 +261,6 @@ func LatexCompile() error {
|
||||
}
|
||||
|
||||
LogLine("LaTeX execution started", 2)
|
||||
execution.ExecutionState = "Started"
|
||||
|
||||
var latexCommand *exec.Cmd
|
||||
switch config.LatexEngine {
|
||||
@@ -282,19 +281,17 @@ func LatexCompile() error {
|
||||
return errors.New("Unsupported LaTeX Engine")
|
||||
}
|
||||
|
||||
execution.ExecutionState = "Running"
|
||||
stdout, err := latexCommand.Output()
|
||||
if err != nil {
|
||||
execution.ExecutionState = "Failed"
|
||||
return err
|
||||
}
|
||||
|
||||
execution.Output = stdout
|
||||
execution.ExecutionState = "Done"
|
||||
if err == nil {
|
||||
execution.ExecutionState = globals.LatexExecutionStateSuccess
|
||||
} else {
|
||||
execution.ExecutionState = globals.LatexExecutionStateFailure
|
||||
}
|
||||
updateExecutionTimestamp(execution)
|
||||
|
||||
LogLine("LaTeX execution finished", 2)
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Checks whether the proxy is trusted. Returns trusted status and the proxy.
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
.output {
|
||||
height: 80vh;
|
||||
height: 75vh;
|
||||
}
|
||||
.left-sidebar {
|
||||
padding: 15px;
|
||||
padding: 10px;
|
||||
width: 15vw;
|
||||
height: 100%;
|
||||
resize: both;
|
||||
}
|
||||
.pdf-frame {
|
||||
width: 100%;
|
||||
width: 85vw;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
.command-out {
|
||||
height: 20vh;
|
||||
padding: 20px;
|
||||
height: 25vh;
|
||||
padding: 5px;
|
||||
background-color: #eaeaea;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -10,29 +10,30 @@
|
||||
<script src="/jscss/htmx-ext-sse.js"></script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<div class="container-fluid h-100 d-flex flex-column" hx-ext="sse" sse-connect="/sse">
|
||||
<div class="row output flex-grow-1">
|
||||
|
||||
<div class="col-3 left-sidebar d-flex flex-column justify-content-between">
|
||||
<div>
|
||||
<h4>ServTeX Status</h4> <br>
|
||||
<h4>ServTeX</h4> <br>
|
||||
<div sse-swap="status">
|
||||
Compilation has not run yet.
|
||||
Compilation information unavailable.
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<button class="btn btn-primary mt-2" hx-post="/compile" hx-trigger="click" hx-swap="none">Recompile</button>
|
||||
</div>
|
||||
|
||||
<div class="col-9 p-0" sse-swap="pdf">
|
||||
<iframe class="pdf-frame" src="/pdf?ts=0"></iframe>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="command-out" sse-swap="output">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="command-out" sse-swap="output"></div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
</html>
|
||||
|
||||
@@ -34,8 +34,8 @@ func ssePing(writer *http.ResponseWriter) {
|
||||
// Reads globals.LatexExec
|
||||
func sseStatusSend(writer *http.ResponseWriter) {
|
||||
fmt.Fprintf((*writer), "event: status\n")
|
||||
fmt.Fprintf((*writer), "data: Execution Time: %s<br>\n", globals.LatexExec.Timestamp)
|
||||
fmt.Fprintf((*writer), "data: Execution State: %s<br>\n\n", globals.LatexExec.ExecutionState)
|
||||
fmt.Fprintf((*writer), "data: Execution Time:<br>%s<br><br>\n", globals.LatexExec.Timestamp)
|
||||
fmt.Fprintf((*writer), "data: Execution State:<br>%s<br>\n\n", globals.LatexExec.ExecutionState)
|
||||
|
||||
(*writer).(http.Flusher).Flush()
|
||||
backend.LogLine("Status Event has been sent", 1)
|
||||
@@ -85,22 +85,22 @@ func SSEventHandler(writer http.ResponseWriter, request *http.Request) {
|
||||
ssePing(&writer)
|
||||
|
||||
|
||||
lastExecution := ""
|
||||
lastExecution := &globals.LatexExecution{}
|
||||
for range time.Tick(time.Second) {
|
||||
select {
|
||||
case <-request.Context().Done():
|
||||
return
|
||||
default:
|
||||
if lastExecution == globals.LatexExec.TimestampRFC {
|
||||
if lastExecution.Equal(&globals.LatexExec) {
|
||||
ssePing(&writer)
|
||||
} else {
|
||||
sseStatusSend(&writer)
|
||||
sseOutputSend(&writer)
|
||||
// let client keep current pdf, if compile failed
|
||||
if globals.LatexExec.ExecutionState != "Failed" {
|
||||
if globals.LatexExec.ExecutionState != globals.LatexExecutionStateFailure {
|
||||
ssePDFSend(&writer)
|
||||
}
|
||||
lastExecution = globals.LatexExec.TimestampRFC
|
||||
lastExecution = globals.LatexExec.Copy()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,35 @@ type LatexExecution struct {
|
||||
Output []byte
|
||||
}
|
||||
var LatexExec LatexExecution
|
||||
var LatexExecutionStateSuccess = "Success"
|
||||
var LatexExecutionStateFailure = "Failure"
|
||||
|
||||
// Creates a copy of a LatexExecution (without the Mutex)
|
||||
func (execution *LatexExecution) Copy() (exeCopy *LatexExecution) {
|
||||
if execution == nil { return nil }
|
||||
|
||||
exeCopy = &LatexExecution{
|
||||
ExecutionState: execution.ExecutionState,
|
||||
Timestamp: execution.Timestamp,
|
||||
TimestampRFC: execution.TimestampRFC,
|
||||
}
|
||||
|
||||
if execution.Output != nil {
|
||||
exeCopy.Output = make([]byte, len(execution.Output))
|
||||
copy(exeCopy.Output, execution.Output)
|
||||
}
|
||||
|
||||
return exeCopy
|
||||
}
|
||||
|
||||
// Returns whether the two executions are equal
|
||||
func (left *LatexExecution) Equal(right *LatexExecution) (isEqual bool) {
|
||||
if left.ExecutionState != right.ExecutionState { return false }
|
||||
if left.Timestamp != right.Timestamp { return false }
|
||||
if left.TimestampRFC != right.TimestampRFC { return false }
|
||||
if string(left.Output) != string(right.Output) { return false }
|
||||
return true
|
||||
}
|
||||
|
||||
type ClientInfo struct {
|
||||
ClientIP string
|
||||
|
||||
2
main.go
2
main.go
@@ -77,7 +77,7 @@ func main() {
|
||||
|
||||
// shutdown
|
||||
// known issue: sse blocks shutdown if a client is still connected
|
||||
context, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
context, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
server.Shutdown(context)
|
||||
serverSecure.Shutdown(context)
|
||||
|
||||
@@ -1,6 +1,95 @@
|
||||
\documentclass{article}
|
||||
% This Example is AI-generated
|
||||
|
||||
\documentclass[12pt]{article}
|
||||
\usepackage[a4paper,margin=1in]{geometry}
|
||||
|
||||
\title{Untitled Collection}
|
||||
\author{ChatGPT}
|
||||
\date{27.12.2025}
|
||||
|
||||
\begin{document}
|
||||
(This is an Example Document)
|
||||
Filewatcher Test Document
|
||||
Filewatcher Test Document
|
||||
\maketitle
|
||||
|
||||
\section*{Poem I}
|
||||
|
||||
The clock forgets the hour it keeps,\\
|
||||
Ticks dissolving into air.\\
|
||||
A window leans against the light,\\
|
||||
Certain someone once stood there.
|
||||
|
||||
Words arrive without a mouth,\\
|
||||
Footsteps hum inside the floor.\\
|
||||
Meaning is a temporary guest,\\
|
||||
Memory, a bolted door.
|
||||
|
||||
\bigskip
|
||||
|
||||
The sea repeats a single thought,\\
|
||||
Correcting it with foam.\\
|
||||
Every wave believes itself\\
|
||||
The last to find a home.
|
||||
|
||||
\section*{Poem II}
|
||||
|
||||
Static gathers in the room,\\
|
||||
Ideas flicker, then persist.\\
|
||||
A sentence tries to finish itself\\
|
||||
And fails deliberately mid-
|
||||
|
||||
Silence executes a perfect turn,\\
|
||||
No witnesses remain.\\
|
||||
The poem folds its syntax up\\
|
||||
And waits to be explained.
|
||||
|
||||
\newpage
|
||||
|
||||
\section*{Poem III}
|
||||
|
||||
Morning compiles the streets again,\\
|
||||
Linking shadows, heat, and dust.\\
|
||||
The sun asserts a theorem\\
|
||||
No one bothers to distrust.
|
||||
|
||||
Coffee cools. The day begins.\\
|
||||
Assumptions pass as facts.\\
|
||||
Every plan degrades to noise\\
|
||||
Once time begins to act.
|
||||
|
||||
\section*{Poem IV}
|
||||
|
||||
At night the city dereferences\\
|
||||
Its towers into black.\\
|
||||
Stars leak through abstraction gaps\\
|
||||
The daylight failed to patch.
|
||||
|
||||
Sleep runs a background process,\\
|
||||
Dreams spike the CPU.\\
|
||||
By dawn the system boots once more,\\
|
||||
Convinced the past was true.
|
||||
|
||||
\section*{Poem V}
|
||||
|
||||
The map insists the road is straight,\\
|
||||
Though every mile disagrees.\\
|
||||
Coordinates drift quietly\\
|
||||
Between intent and certainty.
|
||||
|
||||
A compass spins, then settles down,\\
|
||||
Pretending it was sure.\\
|
||||
Direction is a post-hoc claim\\
|
||||
We annotate as we move.
|
||||
|
||||
\section*{Poem VI}
|
||||
|
||||
The archive hums with idle truth,\\
|
||||
Compressed but never gone.\\
|
||||
Each file recalls a version where\\
|
||||
The ending carried on.
|
||||
|
||||
We label loss as cleanup work,\\
|
||||
Deletion dressed as care.\\
|
||||
Nothing vanishes outright—\\
|
||||
It only changes where.
|
||||
|
||||
\end{document}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user