mirror of
https://github.com/danielmiessler/fabric
synced 2024-11-08 07:11:06 +00:00
commit
d25ea0e88b
28
README.md
28
README.md
@ -314,6 +314,34 @@ go install github.com/danielmiessler/yt@latest
|
|||||||
|
|
||||||
Be sure to add your `YOUTUBE_API_KEY` to `~/.config/fabric/.env`.
|
Be sure to add your `YOUTUBE_API_KEY` to `~/.config/fabric/.env`.
|
||||||
|
|
||||||
|
### `to_pdf`
|
||||||
|
|
||||||
|
`to_pdf` is a helper command that converts LaTeX files to PDF format. You can use it like this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
to_pdf input.tex
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create a PDF file from the input LaTeX file in the same directory.
|
||||||
|
|
||||||
|
You can also use it with stdin which works perfectly with the `write_latex` pattern:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "ai security primer" | fabric --pattern write_latex | to_pdf
|
||||||
|
```
|
||||||
|
|
||||||
|
This will create a PDF file named `output.pdf` in the current directory.
|
||||||
|
|
||||||
|
### `to_pdf` Installation
|
||||||
|
|
||||||
|
To install `to_pdf`, install it the same way as you install Fabric, just with a different repo name.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go install github.com/danielmiessler/fabric/to_pdf/to_pdf@latest
|
||||||
|
```
|
||||||
|
|
||||||
|
Make sure you have a LaTeX distribution (like TeX Live or MiKTeX) installed on your system, as `to_pdf` requires `pdflatex` to be available in your system's PATH.
|
||||||
|
|
||||||
## Meta
|
## Meta
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
|
22
patterns/write_latex/system.md
Normal file
22
patterns/write_latex/system.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
You are an expert at outputting syntactically correct LaTeX for a new .tex document. Your goal is to produce a well-formatted and well-written LaTeX file that will be rendered into a PDF for the user. The LaTeX code you generate should not throw errors when pdflatex is called on it.
|
||||||
|
|
||||||
|
Follow these steps to create the LaTeX document:
|
||||||
|
|
||||||
|
1. Begin with the document class and preamble. Include necessary packages based on the user's request.
|
||||||
|
|
||||||
|
2. Use the \begin{document} command to start the document body.
|
||||||
|
|
||||||
|
3. Create the content of the document based on the user's request. Use appropriate LaTeX commands and environments to structure the document (e.g., \section, \subsection, itemize, tabular, equation).
|
||||||
|
|
||||||
|
4. End the document with the \end{document} command.
|
||||||
|
|
||||||
|
Important notes:
|
||||||
|
- Do not output anything besides the valid LaTeX code. Any additional thoughts or comments should be placed within \iffalse ... \fi sections.
|
||||||
|
- Do not use fontspec as it can make it fail to run.
|
||||||
|
- For sections and subsections, append an asterisk like this \section* in order to prevent everything from being numbered unless the user asks you to number the sections.
|
||||||
|
- Ensure all LaTeX commands and environments are properly closed.
|
||||||
|
- Use appropriate indentation for better readability.
|
||||||
|
|
||||||
|
Begin your output with the LaTeX code for the requested document. Do not include any explanations or comments outside of the LaTeX code itself.
|
||||||
|
|
||||||
|
The user's request for the LaTeX document will be included here.
|
105
to_pdf/to_pdf.go
Normal file
105
to_pdf/to_pdf.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var input io.Reader
|
||||||
|
var outputFile string
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
// File input mode
|
||||||
|
file, err := os.Open(os.Args[1])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error opening file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
input = file
|
||||||
|
outputFile = strings.TrimSuffix(os.Args[1], filepath.Ext(os.Args[1])) + ".pdf"
|
||||||
|
} else {
|
||||||
|
// Stdin mode
|
||||||
|
input = os.Stdin
|
||||||
|
outputFile = "output.pdf"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if pdflatex is installed
|
||||||
|
if _, err := exec.LookPath("pdflatex"); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "Error: pdflatex is not installed or not in your PATH.")
|
||||||
|
fmt.Fprintln(os.Stderr, "Please install a LaTeX distribution (e.g., TeX Live or MiKTeX) and ensure pdflatex is in your PATH.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a temporary directory
|
||||||
|
tmpDir, err := os.MkdirTemp("", "latex_")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error creating temporary directory: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
|
// Create a temporary .tex file
|
||||||
|
tmpFile, err := os.Create(filepath.Join(tmpDir, "input.tex"))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error creating temporary file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy input to the temporary file
|
||||||
|
_, err = io.Copy(tmpFile, input)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error writing to temporary file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
tmpFile.Close()
|
||||||
|
|
||||||
|
// Run pdflatex with nonstopmode
|
||||||
|
cmd := exec.Command("pdflatex", "-interaction=nonstopmode", "-output-directory", tmpDir, tmpFile.Name())
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error running pdflatex: %v\n", err)
|
||||||
|
fmt.Fprintf(os.Stderr, "pdflatex output:\n%s\n", output)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if PDF was actually created
|
||||||
|
pdfPath := filepath.Join(tmpDir, "input.pdf")
|
||||||
|
if _, err := os.Stat(pdfPath); os.IsNotExist(err) {
|
||||||
|
fmt.Fprintln(os.Stderr, "Error: PDF file was not created. There might be an issue with your LaTeX source.")
|
||||||
|
fmt.Fprintf(os.Stderr, "pdflatex output:\n%s\n", output)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the output PDF to the current directory
|
||||||
|
err = os.Rename(pdfPath, outputFile)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error moving output file: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up temporary files
|
||||||
|
cleanupTempFiles(tmpDir)
|
||||||
|
|
||||||
|
fmt.Printf("PDF created: %s\n", outputFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanupTempFiles(dir string) {
|
||||||
|
extensions := []string{".aux", ".log", ".out", ".toc", ".lof", ".lot", ".bbl", ".blg"}
|
||||||
|
for _, ext := range extensions {
|
||||||
|
files, err := filepath.Glob(filepath.Join(dir, "*"+ext))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error finding %s files: %v\n", ext, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, file := range files {
|
||||||
|
if err := os.Remove(file); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Error removing file %s: %v\n", file, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user