Add LaTeX compile support with templates (memoir, academic)
This commit is contained in:
@@ -159,3 +159,18 @@ __all__ = [
|
||||
"ExportOptions",
|
||||
"ExportOptions",
|
||||
]
|
||||
|
||||
def __getattr__(name):
|
||||
if name == "LaTeXExporter":
|
||||
from opus_orchestrator.latex_compile import LaTeXExporter
|
||||
return LaTeXExporter
|
||||
if name == "CompileOptions":
|
||||
from opus_orchestrator.latex_compile import CompileOptions
|
||||
return CompileOptions
|
||||
if name == "export_to_latex":
|
||||
from opus_orchestrator.latex_compile import export_to_latex
|
||||
return export_to_latex
|
||||
if name == "compile_pdf":
|
||||
from opus_orchestrator.latex_compile import compile_pdf
|
||||
return compile_pdf
|
||||
raise AttributeError(f"module has no attribute {name!r}")
|
||||
|
||||
@@ -0,0 +1,323 @@
|
||||
"""LaTeX Compile for Opus Orchestrator.
|
||||
|
||||
Handles conversion to LaTeX and PDF compilation.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
|
||||
from opus_orchestrator.schemas import Manuscript, Chapter
|
||||
|
||||
|
||||
@dataclass
|
||||
class CompileOptions:
|
||||
"""Options for LaTeX compilation."""
|
||||
template: str = "memoir" # memoir, academic, base
|
||||
output_format: str = "pdf" # pdf, tex
|
||||
theme: str = "light" # light, dark, sepia
|
||||
font: str = "serif" # serif, sans, mono
|
||||
include_toc: bool = True
|
||||
include_index: bool = False
|
||||
dedication: str = ""
|
||||
epigraph: str = ""
|
||||
acknowledgments: str = ""
|
||||
abstract: str = ""
|
||||
bibliography: str = ""
|
||||
author: str = "Opus Orchestrator"
|
||||
publisher: str = ""
|
||||
isbn: str = ""
|
||||
edition: str = ""
|
||||
series: str = ""
|
||||
date: str = ""
|
||||
|
||||
def __post_init__(self):
|
||||
if not self.date:
|
||||
self.date = datetime.now().strftime("%Y")
|
||||
|
||||
|
||||
class LaTeXExporter:
|
||||
"""Export manuscript to LaTeX and compile to PDF."""
|
||||
|
||||
TEMPLATES = {
|
||||
"memoir": "memoir.tex",
|
||||
"academic": "academic.tex",
|
||||
"base": "base.tex",
|
||||
}
|
||||
|
||||
def __init__(self, template_dir: Optional[str] = None):
|
||||
if template_dir:
|
||||
self.template_dir = Path(template_dir)
|
||||
else:
|
||||
# Default to package templates
|
||||
self.template_dir = Path(__file__).parent / "templates" / "latex"
|
||||
|
||||
def export(
|
||||
self,
|
||||
manuscript: Manuscript,
|
||||
book_title: str,
|
||||
options: Optional[CompileOptions] = None,
|
||||
) -> dict:
|
||||
"""Export manuscript to LaTeX.
|
||||
|
||||
Args:
|
||||
manuscript: The Manuscript to export
|
||||
book_title: Title for the book
|
||||
options: CompileOptions
|
||||
|
||||
Returns:
|
||||
Export metadata with file paths
|
||||
"""
|
||||
opts = options or CompileOptions(template="memoir")
|
||||
|
||||
# Get template
|
||||
template_file = self.TEMPLATES.get(opts.template, "memoir.tex")
|
||||
template_path = self.template_dir / template_file
|
||||
|
||||
if not template_path.exists():
|
||||
raise FileNotFoundError(f"Template not found: {template_path}")
|
||||
|
||||
# Read template
|
||||
template_content = template_path.read_text()
|
||||
|
||||
# Build body from chapters
|
||||
body = self._build_body(manuscript)
|
||||
|
||||
# Fill template
|
||||
latex_content = self._fill_template(
|
||||
template_content,
|
||||
body,
|
||||
book_title,
|
||||
opts,
|
||||
)
|
||||
|
||||
return {
|
||||
"latex": latex_content,
|
||||
"template": opts.template,
|
||||
"options": opts,
|
||||
}
|
||||
|
||||
def export_to_file(
|
||||
self,
|
||||
manuscript: Manuscript,
|
||||
book_title: str,
|
||||
output_path: str,
|
||||
options: Optional[CompileOptions] = None,
|
||||
) -> dict:
|
||||
"""Export to .tex file."""
|
||||
result = self.export(manuscript, book_title, options)
|
||||
|
||||
output_file = Path(output_path)
|
||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
output_file.write_text(result["latex"])
|
||||
|
||||
result["output_file"] = str(output_file)
|
||||
return result
|
||||
|
||||
def compile(
|
||||
self,
|
||||
manuscript: Manuscript,
|
||||
book_title: str,
|
||||
output_path: str,
|
||||
options: Optional[CompileOptions] = None,
|
||||
) -> dict:
|
||||
"""Export and compile to PDF.
|
||||
|
||||
Args:
|
||||
manuscript: The Manuscript
|
||||
book_title: Book title
|
||||
output_path: Output .pdf path
|
||||
options: CompileOptions
|
||||
|
||||
Returns:
|
||||
Compilation result with paths
|
||||
"""
|
||||
# First export to tex
|
||||
tex_path = output_path.replace(".pdf", ".tex")
|
||||
result = self.export_to_file(manuscript, book_title, tex_path, options)
|
||||
|
||||
# Try to compile
|
||||
compile_result = self._compile_latex(tex_path)
|
||||
|
||||
result.update(compile_result)
|
||||
result["pdf_path"] = output_path if compile_result.get("success") else None
|
||||
|
||||
return result
|
||||
|
||||
def _build_body(self, manuscript: Manuscript) -> str:
|
||||
"""Build LaTeX body from chapters."""
|
||||
parts = []
|
||||
|
||||
for chapter in manuscript.chapters:
|
||||
# Chapter heading
|
||||
parts.append(f"\\chapter{{{chapter.title}}}")
|
||||
parts.append("")
|
||||
|
||||
# Content (convert markdown to latex)
|
||||
content = self._markdown_to_latex(chapter.content or "")
|
||||
parts.append(content)
|
||||
parts.append("")
|
||||
|
||||
return "\n".join(parts)
|
||||
|
||||
def _markdown_to_latex(self, text: str) -> str:
|
||||
"""Convert basic markdown to LaTeX."""
|
||||
# Headers
|
||||
text = re.sub(r'^### (.+)$', r'\\subsection{\1}', text, flags=re.MULTILINE)
|
||||
text = re.sub(r'^## (.+)$', r'\\section{\1}', text, flags=re.MULTILINE)
|
||||
text = re.sub(r'^# (.+)$', r'\\chapter{\1}', text, flags=re.MULTILINE)
|
||||
|
||||
# Bold/italic
|
||||
text = re.sub(r'\*\*\*(.+?)\*\*\*', r'\\textbf{\\textit{\1}}', text)
|
||||
text = re.sub(r'\*\*(.+?)\*\*', r'\\textbf{\1}', text)
|
||||
text = re.sub(r'\*(.+?)\*', r'\\textit{\1}', text)
|
||||
|
||||
# Code blocks
|
||||
text = re.sub(r'```(\w+)?\n(.+?)```', r'\\begin{verbatim}\2\\end{verbatim}', text, flags=re.DOTALL)
|
||||
|
||||
# Inline code
|
||||
text = re.sub(r'`(.+?)`', r'\\texttt{\1}', text)
|
||||
|
||||
# Lists
|
||||
text = re.sub(r'^- (.+)$', r'\\item \1', text, flags=re.MULTILINE)
|
||||
text = re.sub(r'^\d+\. (.+)$', r'\\item \1', text, flags=re.MULTILINE)
|
||||
|
||||
# Blockquotes
|
||||
text = re.sub(r'^> (.+)$', r'\\begin{quote}\1\\end{quote}', text, flags=re.MULTILINE)
|
||||
|
||||
# Horizontal rule
|
||||
text = re.sub(r'^---$', r'\\hrulefill', text, flags=re.MULTILINE)
|
||||
|
||||
return text
|
||||
|
||||
def _fill_template(
|
||||
self,
|
||||
template: str,
|
||||
body: str,
|
||||
book_title: str,
|
||||
options: CompileOptions,
|
||||
) -> str:
|
||||
"""Fill template with content."""
|
||||
# Build replacements
|
||||
replacements = {
|
||||
"book_title": book_title,
|
||||
"author": options.author,
|
||||
"date": options.date,
|
||||
"publisher": options.publisher,
|
||||
"isbn": options.isbn,
|
||||
"edition": options.edition,
|
||||
"series": options.series,
|
||||
"dedication": options.dedication,
|
||||
"epigraph": options.epigraph,
|
||||
"acknowledgments": options.acknowledgments,
|
||||
"abstract": options.abstract,
|
||||
"bibliography": options.bibliography,
|
||||
"body": body,
|
||||
}
|
||||
|
||||
# Fill template - handle both ${var} and $var
|
||||
content = template
|
||||
for key, value in replacements.items():
|
||||
# Replace ${var}
|
||||
content = content.replace(f"${{{key}}}", str(value))
|
||||
# Replace standalone $var
|
||||
dollar_key = f"${key}"
|
||||
content = content.replace(dollar_key, str(value))
|
||||
|
||||
return content
|
||||
|
||||
def _compile_latex(self, tex_path: str) -> dict:
|
||||
"""Compile LaTeX to PDF."""
|
||||
tex_file = Path(tex_path)
|
||||
if not tex_file.exists():
|
||||
return {"success": False, "error": "TeX file not found"}
|
||||
|
||||
# Check for xelatex
|
||||
xelatex = shutil.which("xelatex")
|
||||
if not xelatex:
|
||||
return {
|
||||
"success": False,
|
||||
"error": "xelatex not found. Install with: brew install texlab or apt install texlive-xelatex",
|
||||
"tex_file": str(tex_file),
|
||||
}
|
||||
|
||||
# Compile
|
||||
work_dir = tex_file.parent
|
||||
|
||||
try:
|
||||
# Run xelatex
|
||||
result = subprocess.run(
|
||||
[xelatex, "-interaction=nonstopmode", tex_file.name],
|
||||
cwd=work_dir,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=120,
|
||||
)
|
||||
|
||||
success = result.returncode == 0
|
||||
|
||||
return {
|
||||
"success": success,
|
||||
"returncode": result.returncode,
|
||||
"stdout": result.stdout[-2000:] if result.stdout else "",
|
||||
"stderr": result.stderr[-2000:] if result.stderr else "",
|
||||
"tex_file": str(tex_file),
|
||||
}
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
return {"success": False, "error": "Compilation timeout"}
|
||||
except Exception as e:
|
||||
return {"success": False, "error": str(e)}
|
||||
|
||||
|
||||
def export_to_latex(
|
||||
manuscript: Manuscript,
|
||||
book_title: str,
|
||||
output_path: str,
|
||||
template: str = "memoir",
|
||||
**options,
|
||||
) -> dict:
|
||||
"""Convenience function to export to LaTeX.
|
||||
|
||||
Args:
|
||||
manuscript: The Manuscript
|
||||
book_title: Book title
|
||||
output_path: Output .tex path
|
||||
template: Template name (memoir, academic, base)
|
||||
**options: Additional CompileOptions
|
||||
|
||||
Returns:
|
||||
Export result
|
||||
"""
|
||||
opts = CompileOptions(template=template, **options)
|
||||
exporter = LaTeXExporter()
|
||||
return exporter.export_to_file(manuscript, book_title, output_path, opts)
|
||||
|
||||
|
||||
def compile_pdf(
|
||||
manuscript: Manuscript,
|
||||
book_title: str,
|
||||
output_path: str,
|
||||
template: str = "memoir",
|
||||
**options,
|
||||
) -> dict:
|
||||
"""Convenience function to compile to PDF.
|
||||
|
||||
Args:
|
||||
manuscript: The Manuscript
|
||||
book_title: Book title
|
||||
output_path: Output .pdf path
|
||||
template: Template name
|
||||
**options: Additional CompileOptions
|
||||
|
||||
Returns:
|
||||
Compilation result
|
||||
"""
|
||||
opts = CompileOptions(template=template, **options)
|
||||
exporter = LaTeXExporter()
|
||||
return exporter.compile(manuscript, book_title, output_path, opts)
|
||||
@@ -0,0 +1,152 @@
|
||||
% Opus Orchestrator - Academic/Textbook Template
|
||||
% Technical, educational, academic works
|
||||
|
||||
\documentclass[12pt,oneside]{book}
|
||||
|
||||
% Packages
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{amsmath,amssymb}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{geometry}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{natbib}
|
||||
\usepackage{titlesec}
|
||||
\usepackage{booktabs}
|
||||
\usepackage{listings}
|
||||
\usepackage{fancyvrb}
|
||||
\usepackage{multicol}
|
||||
|
||||
% Geometry
|
||||
\geometry{
|
||||
paperwidth=8.5in,
|
||||
paperheight=11in,
|
||||
textwidth=6in,
|
||||
textheight=9in,
|
||||
left=1in,
|
||||
right=1in,
|
||||
top=1in,
|
||||
bottom=1in,
|
||||
}
|
||||
|
||||
% Hyperref
|
||||
\hypersetup{
|
||||
colorlinks=true,
|
||||
linkcolor=blue,
|
||||
citecolor=blue,
|
||||
urlcolor=blue,
|
||||
}
|
||||
|
||||
% Chapter formatting
|
||||
\titleformat{\chapter}[display]
|
||||
{\normalfont\LARGE\bfseries}
|
||||
{\chaptertitlename\ \thechapter}{20pt}{\LARGE\bfseries}
|
||||
|
||||
\titleformat{\section}
|
||||
{\normalfont\Large\bfseries}
|
||||
{\thesection}{12pt}{\Large\bfseries}
|
||||
|
||||
\titleformat{\subsection}
|
||||
{\normalfont\large\bfseries}
|
||||
{\thesubsection}{12pt}{\large\bfseries}
|
||||
|
||||
% Headers
|
||||
\usepackage{fancyhdr}
|
||||
\pagestyle{fancy}
|
||||
\fancyhf{}
|
||||
\fancyhead[LE]{\thepage}
|
||||
\fancyhead[RO]{\thepage}
|
||||
\fancyhead[RE]{\leftmark}
|
||||
\fancyhead[LO]{\rightmark}
|
||||
|
||||
% Code listings
|
||||
\lstset{
|
||||
basicstyle=\ttfamily\small,
|
||||
frame=single,
|
||||
backgroundcolor=\color{lightgray},
|
||||
}
|
||||
|
||||
% Index
|
||||
\makeindex
|
||||
|
||||
% Book metadata
|
||||
\def\booktitle{$book_title$}
|
||||
\def\bookauthor{$author$}
|
||||
\def\bookdate{$date$}
|
||||
\def\bookpublisher{$publisher$}
|
||||
\def\bookedition{$edition$}
|
||||
|
||||
\begin{document}
|
||||
|
||||
% Front matter
|
||||
\frontmatter
|
||||
|
||||
% Title page
|
||||
\begin{titlepage}
|
||||
\begin{center}
|
||||
\vspace*{1in}
|
||||
{\Huge\bfseries\booktitle\par}
|
||||
\vspace{0.5in}
|
||||
{\Large\bookauthor\par}
|
||||
\vfill
|
||||
{\large\bookedition}\\
|
||||
\bigskip
|
||||
{\large\bookpublisher}\\
|
||||
{\large\bookdate}
|
||||
\end{titlepage}
|
||||
|
||||
% Copyright
|
||||
\thispagestyle{empty}
|
||||
\vspace*{\fill}
|
||||
Copyright \textcopyright\ \bookdate\ \bookauthor\\
|
||||
All rights reserved.
|
||||
\vfill
|
||||
|
||||
% Dedication
|
||||
$if(dedication)$
|
||||
\clearpage
|
||||
\begin{center}
|
||||
\textit{$dedication$}
|
||||
\end{center}
|
||||
$endif$
|
||||
|
||||
% Acknowledgments
|
||||
$if(acknowledgments)$
|
||||
\chapter{Acknowledgments}
|
||||
$acknowledgments$
|
||||
$endif$
|
||||
|
||||
% Abstract
|
||||
$if(abstract)$
|
||||
\chapter{Abstract}
|
||||
$abstract$
|
||||
$endif$
|
||||
|
||||
% Table of contents
|
||||
\tableofcontents
|
||||
|
||||
% List of figures
|
||||
\listoffigures
|
||||
|
||||
% List of tables
|
||||
\listoftables
|
||||
|
||||
% Main matter
|
||||
\mainmatter
|
||||
|
||||
$body$
|
||||
|
||||
% Back matter
|
||||
\backmatter
|
||||
|
||||
% Bibliography
|
||||
$if(bibliography)$
|
||||
\bibliographystyle{plainnat}
|
||||
\bibliography{$bibliography$}
|
||||
$endif$
|
||||
|
||||
% Index
|
||||
\printindex
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,123 @@
|
||||
% Opus Orchestrator - Base LaTeX Template
|
||||
% Auto-generated book template
|
||||
|
||||
\documentclass[12pt,openany]{book}
|
||||
|
||||
% Packages
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{amsmath,amssymb}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{geometry}
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage{titlesec}
|
||||
\usepackage{indentfirst}
|
||||
\usepackage{epigraph}
|
||||
\usepackage{changepage}
|
||||
|
||||
% Geometry
|
||||
\geometry{
|
||||
paperwidth=6in,
|
||||
paperheight=9in,
|
||||
textwidth=4.5in,
|
||||
textheight=7in,
|
||||
headheight=12pt,
|
||||
headsep=12pt,
|
||||
footskip=24pt,
|
||||
marginparwidth=0pt,
|
||||
}
|
||||
|
||||
% Hyperref
|
||||
\hypersetup{
|
||||
colorlinks=true,
|
||||
linkcolor=black,
|
||||
citecolor=black,
|
||||
urlcolor=black,
|
||||
}
|
||||
|
||||
% Title formatting
|
||||
\titleformat{\chapter}[display]
|
||||
{\normalfont\LARGE\bfseries}
|
||||
{\chaptertitlefont\thechapter}{1em}{\chaptertitlefont\titlefont}
|
||||
|
||||
\titleformat{\section}
|
||||
{\normalfont\Large\bfseries}
|
||||
{\thesection}{1em}{}
|
||||
|
||||
\titleformat{\subsection}
|
||||
{\normalfont\large\bfseries}
|
||||
{\thesubsection}{1em}{}
|
||||
|
||||
% Headers
|
||||
\fancyhf{}
|
||||
\fancyhead[LE]{\nouppercase{\thechapter}}
|
||||
\fancyhead[RO]{\nouppercase{\rightmark}}
|
||||
\fancyfoot[C]{\thepage}
|
||||
\pagestyle{fancy}
|
||||
|
||||
% Commands
|
||||
\newcommand{\chaptertitlefont}{\scshape}
|
||||
\newcommand{\titlefont}{\scshape}
|
||||
|
||||
% Book metadata (filled by Opus)
|
||||
\def\booktitle{$book_title$}
|
||||
\def\bookauthor{$author$}
|
||||
\def\bookdate{$date$}
|
||||
\def\bookpublisher{$publisher$}
|
||||
\def\bookisbn{$isbn$}
|
||||
|
||||
\begin{document}
|
||||
|
||||
% Frontmatter
|
||||
\frontmatter
|
||||
|
||||
% Title page
|
||||
\begin{titlepage}
|
||||
\begin{center}
|
||||
\vspace*{1in}
|
||||
{\Huge\scshape\booktitle\par}
|
||||
\vspace{2in}
|
||||
{\Large\scshape\bookauthor\par}
|
||||
\vspace{1in}
|
||||
{\large\scshape\bookdate\par}
|
||||
\vfill
|
||||
\end{titlepage}
|
||||
|
||||
% Copyright page
|
||||
\thispagestyle{empty}
|
||||
\vspace*{\fill}
|
||||
\begin{center}
|
||||
Copyright \textcopyright\ \bookdate\ \bookauthor\\
|
||||
All rights reserved.\\
|
||||
\bookisbn
|
||||
\end{center}
|
||||
\vspace*{\fill}
|
||||
|
||||
% Dedication (if any)
|
||||
$if(dedication)$
|
||||
\cleardoublepage
|
||||
\thispagestyle{empty}
|
||||
\vspace*{3in}
|
||||
\begin{center}
|
||||
\textit{$dedication$}
|
||||
\end{center}
|
||||
$endif$
|
||||
|
||||
% Table of contents
|
||||
\tableofcontents
|
||||
|
||||
% Main body
|
||||
\mainmatter
|
||||
|
||||
$body$
|
||||
|
||||
% Backmatter
|
||||
\backmatter
|
||||
|
||||
% Bibliography (if any)
|
||||
$if(bibliography)$
|
||||
\printbibliography
|
||||
$endif$
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,135 @@
|
||||
% Opus Orchestrator - Memoir Template
|
||||
% Novel, memoir, personal narrative
|
||||
|
||||
\documentclass[12pt,openany]{memoir}
|
||||
|
||||
% Packages
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{amsmath,amssymb}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{hyperref}
|
||||
\usepackage{geometry}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{lettrine}
|
||||
|
||||
% Geometry - trade book format
|
||||
\geometry{
|
||||
paperwidth=5.5in,
|
||||
paperheight=8.5in,
|
||||
textwidth=4in,
|
||||
textheight=7in,
|
||||
inner=0.75in,
|
||||
outer=0.5in,
|
||||
top=0.75in,
|
||||
bottom=0.75in,
|
||||
}
|
||||
|
||||
% Hyperref
|
||||
\hypersetup{
|
||||
colorlinks=false,
|
||||
}
|
||||
|
||||
% Memoir settings
|
||||
\chapterstyle{levado}
|
||||
\sectionstyle{hang}
|
||||
\subsectionstyle{runin}
|
||||
|
||||
% Drop caps
|
||||
\def\rubricum#1{{\let\A\firstchar #1}}
|
||||
\let\firstchar=
|
||||
|
||||
% Custom chapter style
|
||||
\makechapterstyle{levado}{
|
||||
\def\chapterheadstart{}
|
||||
\def\beforechaptitle{\centering\spacedallcaps}
|
||||
\def\chapternumber{\chapnumfont\thechapter}
|
||||
\def\afterchaptitle{\par\nobreak\vskip 1.5em}
|
||||
}
|
||||
|
||||
% Epigraphs
|
||||
\epigraphwidth=3in
|
||||
\epigraphsize\small
|
||||
|
||||
% Headers
|
||||
\nouppercaseheads
|
||||
\headsep=12pt
|
||||
\makepagestyle{opus}
|
||||
\makepsmarks{opus}{
|
||||
\createmark{chapter}{left}{shownumber}{\chaptertitleformat}{\ }
|
||||
|
||||
\createmark{section}{right}{shownumber}{\sectiontitleformat}{\ }
|
||||
\nobreak\Cfoot{\thepage}\or
|
||||
\nobreak\cefoot{\thepage}\or
|
||||
\nobreak\cofoot{\thepage}
|
||||
}
|
||||
\pagestyle{opus}
|
||||
|
||||
% Book metadata
|
||||
\def\booktitle{$book_title$}
|
||||
\def\bookauthor{$author$}
|
||||
\def\bookdate{$date$}
|
||||
\def\bookpublisher{$publisher$}
|
||||
\def\bookseries{$series$}
|
||||
|
||||
\begin{document}
|
||||
|
||||
% Half title
|
||||
\thispagestyle{empty}
|
||||
\begin{center}
|
||||
\vspace*{2in}
|
||||
{\Huge\scshape\booktitle\par}
|
||||
\end{center}
|
||||
|
||||
% Title page
|
||||
\clearpage
|
||||
\thispagestyle{empty}
|
||||
\begin{center}
|
||||
\vspace*{1in}
|
||||
{\Huge\scshape\booktitle\par}
|
||||
\vspace{2in}
|
||||
{\Large\scshape\bookauthor\par}
|
||||
\vfill
|
||||
{\large\scshape\bookpublisher\par}
|
||||
{\large\scshape\bookdate\par}
|
||||
\end{center}
|
||||
|
||||
% Copyright
|
||||
\clearpage
|
||||
\thispagestyle{empty}
|
||||
\vspace*{\fill}
|
||||
\begin{center}
|
||||
Copyright \textcopyright\ \bookdate\ \bookauthor\\
|
||||
All rights reserved.\\
|
||||
ISBN: $isbn$
|
||||
\end{center}
|
||||
\vspace*{\fill}
|
||||
|
||||
% Dedication
|
||||
$if(dedication)$
|
||||
\clearpage
|
||||
\thispagestyle{empty}
|
||||
\vspace*{3in}
|
||||
\begin{center}
|
||||
\textit{$dedication$}
|
||||
\end{center}
|
||||
$endif$
|
||||
|
||||
% Epigraph
|
||||
$if(epigraph)$
|
||||
\clearpage
|
||||
\begin{center}
|
||||
\textit{$epigraph$}
|
||||
\end{center}
|
||||
$endif$
|
||||
|
||||
% Contents
|
||||
\clearpage
|
||||
\tableofcontents*
|
||||
|
||||
\clearpage
|
||||
\mainmatter
|
||||
|
||||
$body$
|
||||
|
||||
\end{document}
|
||||
Reference in New Issue
Block a user