\usepackage{golang}
جمّع LaTeX إلى PDF من Go باستخدام FormaTeX REST API. حزمة net/http القياسية، دون ملف تنفيذي خارجي ودون الحاجة إلى تثبيت TeX Live.
\section{لماذا Go}
انسَ تضمين TeX Live في صورة Docker الخاصة بك. يتولى FormaTeX التجميع على الخادم، فيبقى ملف Go التنفيذي لديك خفيفًا.
FormaTeX API نقطة نهاية HTTP عادية. استخدم المكتبة القياسية، دون SDK خاص ودون أي تبعية جديدة في go.mod.
استخدم goroutines وsync.WaitGroup لتجميع عدة مستندات على التوازي. تتعامل API مع الطلبات المتزامنة دون تقييد معدل goroutines.
\section{بداية سريعة}
يجمّع المثال أدناه مستند LaTeX بسيطًا ويكتب ملف PDF الناتج على القرص. استبدل your-api-key بمفتاح من لوحة التحكم . وفي بيئة الإنتاج اقرأه من os.Getenv("FORMATEX_API_KEY") .
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
const (
apiKey = "your-api-key" // use os.Getenv in production
apiURL = "https://api.formatex.io/api/v1"
)
func main() {
latex := `\documentclass{article}
\usepackage{amsmath}
\begin{document}
Hello from Go! $E = mc^2$
\end{document}`
pdf, err := compileLaTeX(latex, "pdflatex")
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
if err := os.WriteFile("output.pdf", pdf, 0644); err != nil {
fmt.Fprintf(os.Stderr, "write error: %v\n", err)
os.Exit(1)
}
fmt.Println("PDF saved to output.pdf")
}
func compileLaTeX(source, engine string) ([]byte, error) {
body, _ := json.Marshal(map[string]string{
"latex": source,
"engine": engine,
})
req, _ := http.NewRequest("POST", apiURL+"/compile", bytes.NewReader(body))
req.Header.Set("X-API-Key", apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
errBody, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("API error %d: %s", resp.StatusCode, errBody)
}
return io.ReadAll(resp.Body)
}\section{معالج HTTP}
أضف هذا المعالج إلى خادم net/http لديك. يقبل جسم JSON يحتوي على الحقلين source وengine، ويمرّر الطلب إلى FormaTeX، ويبثّ استجابة PDF مباشرة إلى العميل.
package main
import (
"bytes"
"encoding/json"
"io"
"net/http"
"os"
)
func generatePDFHandler(w http.ResponseWriter, r *http.Request) {
var req struct {
Source string `json:"source"`
Engine string `json:"engine"`
}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "invalid request", http.StatusBadRequest)
return
}
if req.Engine == "" {
req.Engine = "pdflatex"
}
body, _ := json.Marshal(map[string]string{
"latex": req.Source,
"engine": req.Engine,
})
apiReq, _ := http.NewRequest("POST",
"https://api.formatex.io/api/v1/compile",
bytes.NewReader(body),
)
apiReq.Header.Set("X-API-Key", os.Getenv("FORMATEX_API_KEY"))
apiReq.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(apiReq)
if err != nil {
http.Error(w, "upstream error", http.StatusBadGateway)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
w.WriteHeader(http.StatusInternalServerError)
io.Copy(w, resp.Body)
return
}
w.Header().Set("Content-Type", "application/pdf")
w.Header().Set("Content-Disposition", "attachment; filename=output.pdf")
io.Copy(w, resp.Body)
}\section{Authentication}
احتفظ بمفتاح API في البيئة، ولا تكتبه أبدًا داخل ملفات المصدر:
apiKey := os.Getenv( "FORMATEX_API_KEY" )
FORMATEX_API_KEY في الصدفة أو في بيئة Docker أو في مدير الأسرار. X-API-Key: <key> .\section{Concurrency}
استخدم goroutines وsync.WaitGroup لتجميع عدة مستندات على التوازي. تُجري كل goroutine طلب HTTP مستقلًا، وينسجم نموذج التزامن في Go بشكل طبيعي مع FormaTeX REST API.
للدفعات الكبيرة، استخدم نقطة نهاية التجميع غير المتزامن التي تعيد معرّف مهمة يمكنك الاستعلام عنه، وهي مثالية عندما تحتاج إلى تجميع مئات المستندات دون إبقاء اتصالات HTTP مفتوحة.
\section{Reference}
| الحقل | النوع | مطلوب | الوصف |
|---|---|---|---|
| latex | string | نعم | كود LaTeX المصدري الكامل كسلسلة نصية |
| engine | string | لا | المحرك المراد استخدامه. الافتراضي: "pdflatex". الخيارات: pdflatex وxelatex وlualatex وlatexmk |
POST https://api.formatex.io/api/v1/compile — يعيد بايتات PDF الخام عند النجاح ( 200)، أو خطأ بصيغة JSON عند الفشل (422/ 401).
\section{معالجة الأخطاء}
تعيد API رموز حالة HTTP. افحص resp.StatusCode قبل قراءة الجسم:
200 — بايتات PDF الخام. اقرأها باستخدام io.ReadAll(resp.Body) .422 — خطأ في تجميع LaTeX. يحتوي جسم JSON على حقل error مع مقتطف من سجل TeX.401 — مفتاح API غير صالح أو مفقود.\end{golang}
احصل على مفتاح API واحصل على ملف PDF من Go خلال دقائق، دون الحاجة إلى TeX Live.