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
# 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}
......@@ -7,6 +7,10 @@
\usetikzlibrary{external}
\tikzexternalize[prefix=nju-]
\begin{document}
\tikzsetnextfilename{emblem}\njuemblem[black]{!}{!}
\tikzsetnextfilename{name}\njuname[black]{!}{!}
% 黑色
\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()
This diff is collapsed.
......@@ -48,7 +48,7 @@
你可以使用 |table| 环境插入标准三线表,如\cref{tab:testtab}所示。
\begin{table}[htbp]
\centering
% \centering
\caption{经过测试的环境}
\label{tab:testtab}
\begin{tabular}{ccc}
......@@ -67,7 +67,7 @@
全部预定义的数学环境如\cref{tab:mathenv}所示。
\begin{table}[htbp]
\centering
% \centering
\caption{数学环境}
\label{tab:mathenv}
\begin{tabular}{cc|cc}
......
......@@ -2,7 +2,7 @@
\section{符号示例}
Caligraphic letters: $\mathcal{A}$
Caligraphic letters: $\mathcal{A}$
Mathbb letters: $\mathbb{A}$
......@@ -10,7 +10,7 @@ Mathfrak letters: $\mathfrak{A}$
Math Sans serif letters: $\mathsf{A}$
Math bold letters: $\mathbf{A}$
Math bold letters: $\mathbf{A},\symbf{A}$
Math bold italic letters: $\mathbi{A}$
......@@ -40,12 +40,24 @@ Math bold italic letters: $\mathbi{A}$
\section{定理环境}
\cref{pf:me}\cref{def:others}
\cref{pf:me1}\cref{pf:me1}\cref{def:others1}\cref{def:others1}\cref{thm:sleep}
\begin{proof}\label{pf:me}
\begin{proof}\label{pf:me1}
证明我是我
\end{proof}
\begin{definition}[他人]\label{def:others}
\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}
\def\TEST{}
\documentclass{njuthesis}
\njusetup{bib/style=author-year}
\input{test.tex}
\def\TEST{}
\documentclass[type=doctor,nl-cover]{njuthesis}
\input{test.tex}
\def\TEST{}
\documentclass[type=master,decl-page]{njuthesis}
\input{test.tex}
\def\TEST{}
\documentclass[decl-page,oneside]{njuthesis}
\input{test.tex}
......@@ -3,76 +3,102 @@
% 其内容不具有任何参考意义
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 自行编译前需反注释以下任意命令
% \documentclass{njuthesis}
% \documentclass[oneside]{njuthesis}
% \documentclass[cjk-font=noto,latin-font=gyre]{njuthesis}
% \documentclass[cjk-font=source,latin-font=gyre]{njuthesis}
% \documentclass[cjk-font=founder,latin-font=gyre]{njuthesis}
% \documentclass[decl-page]{njuthesis}
% \documentclass[draft]{njuthesis}
% \documentclass[type=design]{njuthesis}
% \documentclass[degree=mg]{njuthesis}
% \documentclass[degree=mf,oneside,decl-page]{njuthesis}
% \documentclass[degree=phd,draft]{njuthesis}
% \documentclass[degree=phd,nlcover]{njuthesis}
\njusetup {
info = {
title = {一种使用南京大学 \hologo{LaTeX} 模板\\编写毕业论文的经验性方法},
title* = {An Empirical Way of Composing Thesis with NJU \hologo{LaTeX} Template},
keywords = {我,就是,充数的,关键词},
keywords* = {Dummy,Keywords,Here,{it is}},
grade = {2018},
% student-id = {DZ18114514},
student-id = {189114514},
author = {周煜华},
author* = {Zhou~Yuhua},
department = {拉太赫科学与技术学院},
department* = {School~of~\hologo{LaTeX}},
major = {拉太赫语言学},
major* = {\hologo{LaTeX}~Linguistics},
field = {拉太赫语言在现当代的使用},
field* = {Contemporary~Usage~of~the~\hologo{LaTeX}~Language},
supervisor = {李成殿,教授},
supervisor* = {Professor Li Chengdian},
% supervisor-ii = {孙赫弥,副教授},
% supervisor-ii* = {Associate~professor~Sun~Hemi},
% submit-date = {2021-08-10},
% defend-date = {2021-09-19},
chairman = {张晓山~教授},
reviewer = {王瑞希~教授,郭德纲~副教授,华芈库~教授,戴菲菲~教授},
clc = {0175.2},
secret-level = {限制},
udc = {004.72},
supervisor-contact = {拉太赫科学与技术学院~枝江市结丘路~19~号~114514},
},
bib = {
% style = author-year,
resource = {test.bib},
option = {doi=false, isbn=false, url=false, eprint=false}
},
style = {
emblem-img = {wug},
name-img = {name},
abstract-in-toc = false,
toc-in-toc = false
}
}
\ifdefined\TEST\else
% 自行编译前需反注释以下任意命令
\documentclass{njuthesis}
% \documentclass[minimal]{njuthesis}
% \documentclass[type=master]{njuthesis}
% \documentclass[type=doctor]{njuthesis}
% \documentclass[type=postdoc]{njuthesis}
% \documentclass[oneside]{njuthesis}
% \documentclass[cjk-font=noto,latin-font=gyre]{njuthesis}
% \documentclass[cjk-font=source,latin-font=gyre]{njuthesis}
% \documentclass[cjk-font=founder,latin-font=gyre]{njuthesis}
% \documentclass[decl-page]{njuthesis}
% \documentclass[draft]{njuthesis}
\fi
\njusetup[info]{
title = {一种使用南京大学 \hologo{LaTeX} 模板\\编写毕业论文的经验性方法},
title* = {An Empirical Way of Composing Thesis with NJU \hologo{LaTeX} Template},
keywords = {我,就是,充数的,关键词},
keywords* = {Dummy,Keywords,Here,{it is}},
grade = {2018},
% student-id = {DZ18114514},
student-id = {189114514},
author = {周煜华},
author* = {Zhou~Yuhua},
department = {拉太赫科学与技术学院},
department* = {School~of~\hologo{LaTeX}},
major = {拉太赫语言学},
major* = {\hologo{LaTeX}~Linguistics},
field = {拉太赫语言在现当代的使用},
field* = {Contemporary~Usage~of~the~\hologo{LaTeX}~Language},
supervisor = {李成殿,教授},
supervisor* = {Professor Li Chengdian},
% supervisor-ii = {孙赫弥,副教授},
% supervisor-ii* = {Associate~professor~Sun~Hemi},
% submit-date = {2021-08-10},
% defend-date = {2021-09-19},
chairman = {张晓山~教授},
reviewer = {王瑞希~教授,郭德纲~副教授,华芈库~教授,戴菲菲~教授},
clc = {0175.2},
secret-level = {限制},
udc = {004.72},
supervisor-contact = {拉太赫科学与技术学院~枝江市结丘路~19~号~114514},
email={git+nju-lug-email-3104-issue-@yaoge123.cn}
}
\njusetup[bib]{
% style = author-year,
resource = {test.bib},
option = {doi=false, isbn=false, url=false, eprint=false}
}
\njusetup[image]{
nju-emblem = {wug},
nju-name = {name}
}
\njusetup[abstract/title-style]{natural}
\njusetup{
abstract/toc-entry = false,
tableofcontents/toc-entry = false,
math/style = ISO
}
\njusetup[theorem]{
style = remark,
header-font = \sffamily\bfseries,
body-font = \ttfamily,
qed-symbol = \ensuremath { \male },
counter = section,
define,
}
\njusetup[footnote]{
style={circled},
circledtext-option={resize=none,boxcolor=blue,boxtype=ox+,boxfill=red!30}
}
% \addbibresource{test.bib}
\ctexset{
contentsname = {\hspace{2em}},
% \ctexset{
% contentsname = { 目\qquad{}次 },
% listfigurename = { 插图清单 },
% listtablename = { 表格清单 }
}
% }
\njusetname{notation}{术语表}
\njusetname{tableofcontents}{\qquad{}}
\njusetname{listoffigures}{插图清单}
\njusetname{listoftables}{表格清单}
\njusetname{abstract}[b]{我是摘要}
\njusetname*{abstract}[b]{Abstract}
% \njusetlength{coveruline}{330pt}
\njusetformat{chapter}{\raggedleft\kaishu\zihao{-1}}
% \usepackage{multirow,tabularray,wrapfig,subcaption}
% \usepackage{listings,algorithm,algorithmic}
% \usepackage{siunitx,physics,chemfig}
% \usepackage[version=4]{mhchem}
\usepackage{hologo,blindtext,zhlipsum}
\usepackage{hologo,blindtext,zhlipsum,mathtools}
% \setmonofont{cmun}[
% Extension = .otf,
......@@ -116,8 +142,6 @@
% https://tex.stackexchange.com/questions/33264/span-as-a-math-operator
\DeclareMathOperator{\spn}{span}
\renewcommand{\vec}[1]{\mathbf{#1}}
% \RenewDocumentCommand\vec{m}{\mathbf{#1}}
\NewDocumentCommand\mathbi{m}{\textbf{\em #1}}
\begin{document}
......@@ -138,7 +162,7 @@
% \end{preface}
\begin{abstract}
\zhlipsum[76][name=zhufu]
\zhlipsum[76-90][name=zhufu]
\end{abstract}
\begin{abstract*}
......@@ -146,7 +170,6 @@
\end{abstract*}
\raggedbottom
% \flushbottom
\tableofcontents
\listoffigures
......@@ -237,10 +260,7 @@
\input{chapters/Mathematics}
\input{chapters/Bibliography}
\bgroup
\sloppy
\printbibliography
\egroup
\printbibliography
\begin{acknowledgement}
感谢\href{https://git.nju.edu.cn/nju-lug/lug-introduction}{NJU Linux User Group}
......