Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cloustile/njuthesis
  • GGbond/njuthesis
  • caomeng/njuthesis
  • yilye/njuthesis
  • kopanswer/njuthesis
  • Dansen/njuthesis
  • junjimy/njuthesis
  • wuqizuo123/njuthesis
  • zxlll-/njuthesis
  • Michael/njuthesis
  • bcbhfz/njuthesis
  • LingDu/njuthesis
  • jiejiangwu/njuthesis
  • Tilnel/njuthesisundergraduate
  • nju-lug/nju-latex-templates/njuthesis
15 results
Show changes
Showing
with 10300 additions and 9 deletions
# https://github.com/stone-zeng/tl-depend-analysis/
if [ -z "$1" ]; then
MIRROR=https://mirror.ctan.org
else
MIRROR=$1
fi
curl -o texlive.tlpdb $MIRROR/systems/texlive/tlnet/tlpkg/texlive.tlpdb
curl -o texlive.tlpdb.sha512 $MIRROR/systems/texlive/tlnet/tlpkg/texlive.tlpdb.sha512
sha512sum -c texlive.tlpdb.sha512
rm texlive.tlpdb.sha512
if [ ! -d data ]; then
mkdir data
fi
mv texlive.tlpdb data/
# https://github.com/stone-zeng/tl-depend-analysis/
import os
import re
import sys
from typing import TextIO
LUA_MODULE_PATTERN = re.compile(r'''
\brequire\s*
\(?\s*["'](.+?)["']
''', re.VERBOSE)
LUALIBS_MODULE_PATTERN = re.compile(r'''
loadmodule\s*
\(*\s*["'](.+\.lua)["']
''', re.VERBOSE)
CLASS_PATTERN = re.compile(r'''
\\(?:LoadClass|LoadClassWithOptions|documentclass)\s*
(?:\[.*\]\s*)?
\{\s*(.+?)\s*\}
''', re.VERBOSE)
PACKAGE_PATTERN = re.compile(r'''
\\(?:RequirePackage|RequirePackageWithOptions|usepackage)\s*
(?:\[.*\]\s*)?
\{\s*(.+?)\s*\}
''', re.VERBOSE)
USEFONT_PATTERN = re.compile(r'''
\\usefont\s*
\{\s*(.+?)\s*\}\s*
\{\s*(.+?)\s*\}
''', re.VERBOSE)
class Parser:
def __init__(self, path: str):
self.path = path
self.state = State()
self.depend: set[str] = set()
def parse(self):
try:
with open(self.path, 'r', encoding='utf-8', errors='replace') as fp:
match os.path.splitext(self.path)[1]:
case '.tex' | '.ltx' | '.cls' | '.sty' | '.def' | '.clo':
self._parse_tex(fp)
case '.lua':
self._parse_lua(fp)
case _:
print('Unknown file type:', self.path, file=sys.stderr)
except FileNotFoundError:
print('File not found:', self.path, file=sys.stderr)
def _parse_lua(self, fp: TextIO):
comment_flag = False
for line in fp:
line = line.strip()
if line.startswith('--[['):
comment_flag = True
continue
if line.endswith(']]') or line.endswith(']]--'):
comment_flag = False
continue
if not comment_flag and not line.startswith('--'):
self.depend.update(self._parse_lua_line(line))
def _parse_lua_line(self, line: str) -> list[str]:
if match := LUA_MODULE_PATTERN.findall(line):
return [match[0] + '.lua']
if match := LUALIBS_MODULE_PATTERN.findall(line):
return [match[0]]
return []
def _parse_tex(self, fp: TextIO):
for line in fp:
if line.rstrip() == '\\endinput':
return
if not line.strip().startswith('%'):
self.depend.update(self._parse_tex_line(line))
def _parse_tex_line(self, line: str) -> list[str]:
if self.state.stack == '':
# Classes (single line)
# - \LoadClass[...]{class}
# - \documentclass[...]{class}
if match := CLASS_PATTERN.findall(line):
return self._parse_cls_sty_match(match, suffix='.cls')
# Packages (single line)
# - \RequirePackage[...]{package}
# - \usepackage[...]{package}
if match := PACKAGE_PATTERN.findall(line):
return self._parse_cls_sty_match(match, suffix='.sty')
# Packages (multiple line)
if '\\RequirePackage' in line or '\\usepackage' in line:
self.state.update(line.split('%')[0].strip())
if match := USEFONT_PATTERN.findall(line):
return self._parse_font_match(match)
return []
self.state.update(line.split('%')[0].strip())
if self.state.is_braces_closed():
match = PACKAGE_PATTERN.findall(self.state.stack)
self.state.reset()
return self._parse_cls_sty_match(match, suffix='.sty')
return []
@staticmethod
def _parse_cls_sty_match(match: list[str], suffix: str) -> list[str]:
res = []
for m in match:
for s in map(str.strip, m.split(',')):
if Parser._is_valid_name(s):
res.append(s + suffix)
return res
@staticmethod
def _parse_font_match(match: list[str]) -> list[str]:
res = []
for m in match:
encoding, family = m
if Parser._is_valid_name(encoding) and Parser._is_valid_name(family):
res.append(f'{encoding.strip()}{family.strip()}.fd'.lower())
return res
@staticmethod
def _is_valid_name(name: str) -> bool:
return (
name != ''
and '\\' not in name and '#' not in name
and not name.startswith('.')
)
class State:
def __init__(self):
self.stack = ''
self.braces_count = 0
self.braces_open = False
self.brackets_count = 0
self.brackets_open = False
def __repr__(self) -> str:
return ', '.join([
f'stack = "{self.stack}"',
f'braces_count = {self.braces_count}',
f'braces_open = {self.braces_open}',
f'brackets_count = {self.brackets_count}',
f'brackets_open = {self.brackets_open}',
])
def update(self, line: str):
self.stack += line
for c in line:
match c:
case '{':
self.braces_count += 1
self.braces_open = True
case '}':
self.braces_count -= 1
case '[':
self.brackets_count += 1
self.brackets_open = True
case ']':
self.brackets_count -= 1
self.brackets_open = False
def is_braces_closed(self):
return self.braces_count == 0 and self.braces_open and not self.brackets_open
def reset(self):
self.stack = ''
self.braces_count = 0
self.braces_open = False
self.brackets_count = 0
self.brackets_open = False
def _main():
if len(sys.argv) < 2:
print('Usage: python file_parser.py <file>', file=sys.stderr)
sys.exit(1)
parser = Parser(sys.argv[1])
parser.parse()
for d in sorted(parser.depend):
print(d)
if __name__ == '__main__':
_main()
@ECHO OFF
pdflatex --shell-escape generate-img
DEL "generate-img.pdf"
DEL "*.aux"
DEL "*.auxlock"
DEL "*.dpth"
DEL "*.log"
DEL "*.md5"
#!/usr/bin/env sh
pdflatex --shell-escape generate-img
rm generate-img.pdf
rm *.aux
rm *.auxlock
rm *.dpth
rm *.log
rm *.md5
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 本文件用于生成校徽和校名图片
% 编译命令为 pdflatex --shell-escape generate-img
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass{article}
\usepackage{njuvisual}
\usetikzlibrary{external}
\tikzexternalize[prefix=nju-]
\begin{document}
% 黑色
\tikzsetnextfilename{emblem} \njuemblem[black]{!}{!}
\tikzsetnextfilename{name} \njuname [black]{!}{!}
% 紫色
\tikzsetnextfilename{emblem-purple} \njuemblem[njupurple]{!}{!}
\tikzsetnextfilename{name-purple} \njuname [njupurple]{!}{!}
\end{document}
# adapted from https://github.com/stone-zeng/tl-depend-analysis/
# under MIT license
# require python>=3.10
import dataclasses
import json
import os
import subprocess
import sys
from typing import Any
from argparse import ArgumentParser
from file_parser import Parser
arg_parser = ArgumentParser(
description='Find and install dependencies of a given LaTeX module')
arg_parser.add_argument('-m', '--module', type=str, default='njuthesis',
help='Name of your module')
arg_parser.add_argument('-p', '--pkg', type=str, default='',
help='Additional package name to be installed')
arg_parser.add_argument('-e', '--exclude', type=str, default='',
help='Module file to be excluded from searching')
args = arg_parser.parse_args()
MODULE_NAME = args.module
EXCLUDE_FILE = set(args.exclude.split())
INIT_PACKAGES = set(args.pkg.split())
TLPDB_PATH = 'data/texlive.tlpdb'
TL_DEPEND_PATH = 'data/tl-depend.json'
L3BUILD_UNPACKED_PATH = "../build/unpacked"
TEST_PATH = "../test"
TEXMFDIST_PATH = subprocess.run(
['kpsewhich', '-var-value', 'TEXMFDIST'],
capture_output=True, check=True).stdout.decode().strip()
# TEXMFDIST_PATH = '/usr/local/texlive/2023/texmf-dist'
@dataclasses.dataclass
class Package:
name: str
category: str
revision: int
tl_depend: list[str]
depend: list[str]
runfiles: list[str]
class PackageEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, Package):
return {
'name': o.name,
'depend': o.depend,
'tl_depend': o.tl_depend,
}
# return dataclasses.asdict(o)
return json.JSONEncoder.default(self, o)
class TLDepend:
def __init__(self):
self.packages: list[Package] = []
self.file_mappings: dict[str, str] = {}
self.njuthesis_depend: set[str] = []
def parse_tlpdb(self):
with open(TLPDB_PATH, 'r', encoding='utf-8') as fp:
items = fp.read().strip().split('\n\n')
for item in items:
lines = item.split('\n')
_, name = lines[0].split()
if not name.startswith('00') and '.' not in name:
self.packages.append(
Package(name=name, depend=[], **self._parse_tlpdb_item(lines)))
@staticmethod
def _parse_tlpdb_item(lines: list[str]):
package: dict[str, Any] = {
'tl_depend': [],
'runfiles': [],
}
runfiles_flag = False
for line in lines:
key, *value = line.strip().split(maxsplit=1)
value = value[0] if value else None
match key:
case 'category':
package['category'] = value
case 'revision':
package['revision'] = int(value) if value else -1
case 'depend':
package['tl_depend'].append(value)
case 'runfiles':
runfiles_flag = True
case _ if runfiles_flag:
if line.startswith(' '):
package['runfiles'].append(line.strip())
else:
runfiles_flag = False
return package
def get_file_mappings(self, verbose: bool = False):
for package in self.packages:
if package.name.endswith('-dev'):
if verbose:
print('Skip dev package:', package.name, file=sys.stderr)
continue
for file in package.runfiles:
if file.startswith('RELOC') or file.startswith('texmf-dist'):
_, path = file.split('/', maxsplit=1)
# if path.startswith('fonts'):
# continue
if (name := os.path.basename(path)) in self.file_mappings:
if verbose:
print('Duplicate file:', file, file=sys.stderr)
else:
self.file_mappings[name] = package.name
def get_module_depend(self, file_paths: list, verbose: bool = False):
depend: set[str] = INIT_PACKAGES
for fp in file_paths:
for f in os.listdir(fp):
full_path = os.path.join(fp, f)
if not f in EXCLUDE_FILE and not os.path.isdir(full_path):
if verbose:
print('Process file', full_path)
depend.update(self._get_depend_from_file(full_path, verbose))
depend.discard(MODULE_NAME)
self.njuthesis_depend = depend
def update_module_depend(self, verbose: bool = False):
init_depend = self.njuthesis_depend.copy()
full_depend: set[str] = set()
with open(TL_DEPEND_PATH, mode="r", encoding='utf-8') as f:
data = json.load(f)
while len(init_depend) > 0:
# recursive method
pkg = init_depend.pop()
full_depend.update([pkg])
for entry in data:
if entry["name"] == pkg:
temp = set(entry["depend"])
common = full_depend.intersection(temp)
init_depend.update(temp.difference(common))
if verbose:
print(len(full_depend), len(init_depend), pkg)
self.njuthesis_depend = sorted(full_depend)
def install(self):
os.system('tlmgr install ' + ' '.join(self.njuthesis_depend))
def _get_depend_from_file(self, file: str, verbose: bool = False):
depend: set[str] = set()
parser = Parser(file)
parser.parse()
for d in parser.depend:
try:
depend.add(self.file_mappings[d])
except KeyError:
print('Dependency not found:', d, file=sys.stderr)
if verbose:
if depend == set():
print('Find no package')
else:
print('Add packages', ' '.join(sorted(depend)))
print('-----')
return depend
def main():
analyzer = TLDepend()
analyzer.parse_tlpdb()
analyzer.get_file_mappings()
analyzer.get_module_depend([L3BUILD_UNPACKED_PATH, TEST_PATH], True)
analyzer.update_module_depend()
# print(analyzer.njuthesis_depend)
analyzer.install()
if __name__ == '__main__':
main()
# Latexmk configuration file for njuthesis documentation.
# vim: set ft=perl:
# Use XeLaTeX to compile.
$pdf_mode = 5;
$xelatex = "xelatex -shell-escape -file-line-error -halt-on-error -interaction=nonstopmode -no-pdf -synctex=1 %O %S";
$xdvipdfmx = "xdvipdfmx -q -E -o %D %O %S";
$bibtex_use = 1.5;
# Clean auxiliary files .
$clean_ext = "hd loe ptc run.xml synctex.gz thm xdv";
# Process index.
$makeindex = "makeindex %O -s gind.ist -o %D %S";
add_cus_dep('glo','gls',0,'makeindex');
sub makeindex {
......@@ -21,8 +24,5 @@ sub makeindex {
}
$makeindex_silent_switch = "-q";
add_cus_dep('nlo', 'nls', 0, 'nlo2nls');
sub nlo2nls {
system("makeindex -s nomencl.ist -o \"$_[0].nls\" \"$_[0].nlo\"");
}
push @generated_exts, 'nlo', 'nls';
# Show CPU time used.
$show_time = 1;
This diff is collapsed.
\njuchapter{攻读博士学位期间研究成果及参与项目情况}
\njupaperlist[攻读博士学位期间发表的学术论文]{Nemec1997-209-214,Chiani1998-2998-3008,Chiani1998a}
\section*{攻读博士学位期间参与的科研课题}
\begin{enumerate}[label=\arabic*., labelindent=0em, leftmargin=*]
\item 2020.1-2023.12, 国家自然科学基金, 12345678, 这是项目名称, 负责人: 老板1, 60 万.
\item 2020.1-2022.12, 国家自然科学基金, 23456789, 这是项目名称, 负责人: 老板2, 25 万.
\item 2020.1-2023.12, 国家自然科学基金, 34567890, 这是项目名称, 负责人: 老板3, 66 万.
\end{enumerate}
\chapter{引用参考文献}
\label{chap:bibliography}
\section{引用命令}
顺序编码制的 \cite{qiujinhengetal2010,njuthesis,riedl2009quasi}(上标可设置页码)、\parencite{qiujinhengetal2010}(非上标可设置页码)、\pagescite{qiujinhengetal2010}(上
标加自动页码)、\textcite{qiujinhengetal2010}(提供作者为主语加非上标编号)、\authornumcite{qiujinhengetal2010}(提供作
者为主语加上标编号)、\footfullcite{qiujinhengetal2010}(脚注方式)
著者-年份制的\cite{qiujinhengetal2010,njuthesis,riedl2009quasi}(作者加年份用
括号包围可设置页码)、\pagescite{qiujinhengetal2010}(作者加年份用括号包围自动页码)、\yearcite{qiujinhengetal2010}(提供
年份用括号包围)、\yearpagescite{qiujinhengetal2010}(提供年份用括号包围自动页码)、\textcite{qiujinhengetal2010}(提供主
语作者加括号包围年份)、\footfullcite{qiujinhengetal2010}(脚注方式)。
\chapter{图片、表格与代码}
\section{图片}
插入一张图片,就像\cref{fig:arcaea}这样。
\begin{figure}[htbp]
\centering
\includegraphics[width=0.5\textwidth]{test.png}
\caption{火热劲爆 Arcaea}
\label{fig:arcaea}
\end{figure}
\zhlipsum[3][name=aspirin]
% \subsection{文字环绕图像}
% % wrapfigure后面不能有空行
% \begin{wrapfigure}{r}{0cm}
% \label{fig:arcaeaedge}
% \includegraphics[width=.15\textwidth]{test.png}
% \caption{闊靛緥婧愮偣}
% \end{wrapfigure}
% \zhlipsum[2][name=simp]
% \subsection{多个图像}
% \begin{figure}[htbp]
% \centering
% \begin{subfigure}{.32\textwidth}
% \centering
% \includegraphics[width=\textwidth]{test.png}
% \caption{闊靛緥婧愮偣}
% \end{subfigure}
% \begin{subfigure}{.32\textwidth}
% \centering
% \includegraphics[width=\textwidth]{test.png}
% \caption{Arcaea}
% \end{subfigure}
% \begin{subfigure}{.32\textwidth}
% \centering
% \includegraphics[width=\textwidth]{test.png}
% \caption{闊虫父}
% \end{subfigure}
% \caption{新概念空间立体节奏游戏}
% \end{figure}
\section{表格}
你可以使用 |table| 环境插入标准三线表,如\cref{tab:testtab}所示。
\begin{table}[htbp]
% \centering
\caption{经过测试的环境}
\label{tab:testtab}
\begin{tabular}{ccc}
\toprule
OS & TeX & 测试情况 \\
\midrule
Windows 10 & TeX Live 2021 &\\
Windows 10 & MiKTeX &\\
Windows 10 & TeX Live 2020 & × \\
Ubuntu 20.04 & TeX Live 2021 &\\
南大 TeX & Overleaf &\\
\bottomrule
\end{tabular}
\end{table}
全部预定义的数学环境如\cref{tab:mathenv}所示。
\begin{table}[htbp]
% \centering
\caption{数学环境}
\label{tab:mathenv}
\begin{tabular}{cc|cc}
\toprule
标签 & 名称 & 标签 & 名称 \\
\midrule
axiom & 公理 & lemma & 引理 \\
corollary & 推论 & proof & 证明 \\
definition & 定义 & theorem & 定理 \\
example && & \\
\bottomrule
\end{tabular}
\end{table}
\chapter{数学公式与定理}
\section{符号示例}
Caligraphic letters: $\mathcal{A}$
Mathbb letters: $\mathbb{A}$
Mathfrak letters: $\mathfrak{A}$
Math Sans serif letters: $\mathsf{A}$
Math bold letters: $\mathbf{A},\symbf{A}$
Math bold italic letters: $\mathbi{A}$
\section{公式示例}
% Thanks to github.com/YuanshengZhao/Garamond-Math
公式字体示例
\[
\displaystyle \ointctrclockwise\mathcal{D}[x(t)]\sqrt{\frac{\displaystyle3\uppi^2-\sum_{q=0}^{\infty}(z+\hat L)^{q}\exp(\symrm{i}q^2 \hbar x)}{\displaystyle (\symsfup{Tr}\symbfcal{A})\left(\symbf\Lambda_{j_1j_2}^{i_1i_2}\Gamma_{i_1i_2}^{j_1j_2}\hookrightarrow\vec D\cdot \symbf P \right)}}
=\underbrace{\widetilde{\left\langle \frac{\notin \emptyset}{\varpi\alpha_{k\uparrow}}\middle\vert \frac{\partial_\mu T_{\mu\nu}}{2}\right\rangle}}_{\mathrm{K}_3\mathrm{Fe}(\mathrm{CN})_6} ,\forall z \in \mathbb{R}
\]
你可以使用\verb|equation|环境插入公式,如\cref{eq:dewitt}
\begin{equation}\label{eq:dewitt}
\int \mathrm{e}^{ax} \tanh {bx} \, \mathrm{d}x =
\begin{dcases}
\begin{multlined}
\frac{\mathrm{e}^{(a+2b)x}}{(a + 2b)} \,
{{}_2F_1} \left( 1 + \frac{a}{2b}, 1, 2+\frac{a}{2b}, -\mathrm{e}^{2bx} \right) \\
- \frac{1}{a} \mathrm{e}^{ax} \, {{}_2F_1} \left( 1, \frac{a}{2b}, 1 + \frac{a}{2b}, -\mathrm{e}^{2bx} \right)
\end{multlined}
& a \ne b \\
\frac{e^{ax} - 2 \tan^{-1}(\mathrm{e}^{ax})}{a} & a = b
\end{dcases}
\end{equation}
\section{定理环境}
\cref{pf:me1}\cref{pf:me1}\cref{def:others1}\cref{def:others1}\cref{thm:sleep}
\begin{proof}\label{pf:me1}
证明我是我
\end{proof}
\begin{definition}[他人]\label{def:others1}
定义他人即地狱
\end{definition}
\begin{proof}\label{pf:me2}
证明我是我
\end{proof}
\begin{definition}[他人]\label{def:others2}
定义他人即地狱
\end{definition}
\begin{theorem}[睡觉]\label{thm:sleep}
管他呢先睡觉吧!
\end{theorem}
This diff is collapsed.
\chapter{南京大学本科毕业论文(设计)的
撰写规范和装订要求(试行)}
\chapter[本科毕业论文格式规定]{南京大学本科毕业论文(设计)的撰写规范和装订要求(试行)}
\label{chap:standard}
本科毕业论文(设计)是本科教学中的重要环节,为规范本科毕业论文(设计)的工作,特制订毕业论文(设计)的撰写和装订要求,请同学们按照要求执行。如各院系已经制定了相应的规范,则按照院系的要求执行。
......@@ -82,7 +81,8 @@
\subsection{注释}
毕业论文(设计)中有个别名词或情况需要解释时,可加注说明。注释采用脚注,每页独立编号,即每页都从1开始编码,编号用1,2,3……,文中编号用上标。
(十)参考文献
\subsection{参考文献}
参考文献的著录应符合国家标准,参考文献的序号左顶格,并用数字加方括号表示,如“[1]”。每一条参考文献著录均以“.”结束。
\section{毕业论文(设计)装订要求}
......
test/name.png

106 KiB

\def\TEST{}
\documentclass{njuthesis}
\njusetup{bib/style=author-year}
\input{test.tex}
\def\TEST{}
\documentclass[type=doctor,nl-cover]{njuthesis}
\input{test.tex}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.