Advertisement
Guest User

lectures.py

a guest
Jan 11th, 2020
1,070
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.55 KB | None | 0 0
  1. #!/usr/bin/python3
  2.  
  3. import os
  4. from datetime import datetime
  5. from pathlib import Path
  6. import locale
  7. import re
  8. import subprocess
  9.  
  10.  
  11. from config import get_week, DATE_FORMAT, CURRENT_COURSE_ROOT
  12.  
  13. # TODO
  14. locale.setlocale(locale.LC_TIME, "en_US.UTF-8")
  15.  
  16.  
  17. def number2filename(n):
  18.     return 'lec_{0:02d}.tex'.format(n)
  19.  
  20. def filename2number(s):
  21.     return int(str(s).replace('.tex', '').replace('lec_', ''))
  22.  
  23. class Lecture():
  24.     def __init__(self, file_path, course):
  25.         with file_path.open() as f:
  26.             for line in f:
  27.                 lecture_match = re.search(r'lecture\{(.*?)\}\{(.*?)\}\{(.*)\}', line)
  28.                 if lecture_match:
  29.                     break;
  30.  
  31.         # number = int(lecture_match.group(1))
  32.  
  33.         date_str = lecture_match.group(2)
  34.         date = datetime.strptime(date_str, DATE_FORMAT)
  35.         week = get_week(date)
  36.  
  37.         title = lecture_match.group(3)
  38.  
  39.         self.file_path = file_path
  40.         self.date = date
  41.         self.week = week
  42.         self.number = filename2number(file_path.stem)
  43.         self.title = title
  44.         self.course = course
  45.  
  46.     def edit(self):
  47.         subprocess.Popen([
  48.             "x-terminal-emulator",
  49.             "-e", "zsh", "-i", "-c",
  50.             f"\\vim --servername kulak --remote-silent {str(self.file_path)}"
  51.         ])
  52.  
  53.     def __str__(self):
  54.         return f'<Lecture {self.course.info["short"]} {self.number} "{self.title}">'
  55.  
  56.  
  57. class Lectures(list):
  58.     def __init__(self, course):
  59.         self.course = course
  60.         self.root = course.path
  61.         self.master_file = self.root / 'master.tex'
  62.         list.__init__(self, self.read_files())
  63.  
  64.     def read_files(self):
  65.         files = self.root.glob('lec_*.tex')
  66.         return sorted((Lecture(f, self.course) for f in files), key=lambda l: l.number)
  67.  
  68.     def parse_lecture_spec(self, string):
  69.         if len(self) == 0:
  70.             return 0
  71.  
  72.         if string.isdigit():
  73.             return int(string)
  74.         elif string == 'last':
  75.             return self[-1].number
  76.         elif string == 'prev':
  77.             return self[-1].number - 1
  78.  
  79.     def parse_range_string(self, arg):
  80.         all_numbers = [lecture.number for lecture in self]
  81.         if 'all' in arg:
  82.             return all_numbers
  83.  
  84.         if '-' in arg:
  85.             start, end = [self.parse_lecture_spec(bit) for bit in arg.split('-')]
  86.             return list(set(all_numbers) & set(range(start, end + 1)))
  87.  
  88.         return [self.parse_lecture_spec(arg)]
  89.  
  90.     @staticmethod
  91.     def get_header_footer(filepath):
  92.         part = 0
  93.         header = ''
  94.         footer = ''
  95.         with filepath.open() as f:
  96.             for line in f:
  97.                 # order of if-statements is important here!
  98.                 if 'end lectures' in line:
  99.                     part = 2
  100.  
  101.                 if part == 0:
  102.                     header += line
  103.                 if part == 2:
  104.                     footer += line
  105.  
  106.                 if 'start lectures' in line:
  107.                     part = 1
  108.         return (header, footer)
  109.  
  110.     def update_lectures_in_master(self, r):
  111.         header, footer = self.get_header_footer(self.master_file)
  112.         body = ''.join(
  113.             ' ' * 4 + r'\input{' + number2filename(number) + '}\n' for number in r)
  114.         self.master_file.write_text(header + body + footer)
  115.  
  116.     def new_lecture(self):
  117.         if len(self) != 0:
  118.             new_lecture_number = self[-1].number + 1
  119.         else:
  120.             new_lecture_number = 1
  121.  
  122.         new_lecture_path = self.root / number2filename(new_lecture_number)
  123.  
  124.         today = datetime.today()
  125.         date = today.strftime(DATE_FORMAT)
  126.  
  127.         new_lecture_path.touch()
  128.         new_lecture_path.write_text(f'\\lecture{{{new_lecture_number}}}{{{date}}}{{}}\n')
  129.  
  130.         if new_lecture_number == 1:
  131.             self.update_lectures_in_master([1])
  132.         else:
  133.             self.update_lectures_in_master([new_lecture_number - 1, new_lecture_number])
  134.  
  135.         self.read_files()
  136.  
  137.  
  138.         l = Lecture(new_lecture_path, self.course)
  139.  
  140.         return l
  141.  
  142.     def compile_master(self):
  143.         subprocess.Popen(
  144.             ['latexmk', '-g', '-f', str(self.master_file)],
  145.             cwd=str(self.root),
  146.             stdout=subprocess.DEVNULL,
  147.             stderr=subprocess.DEVNULL
  148.         )
  149.  
  150. if __name__ == '__main__':
  151.     import sys
  152.     args = sys.argv
  153.     command = args[1]
  154.  
  155.  
  156.     lectures = Lectures(Path.cwd())
  157.  
  158.     if command == 'view':
  159.         lecture_range = args[2]
  160.         lecture_range = lectures.parse_range_string(lecture_range)
  161.         print(lecture_range)
  162.         lectures.update_lectures_in_master(lecture_range)
  163.         lectures.compile_master()
  164.  
  165.     if command == 'new':
  166.         lectures.new_lecture()
  167.  
  168.     if command == 'init':
  169.         from utils import beautify
  170.         course_title = beautify(lectures.root.stem)
  171.         lines = [r'\documentclass[a4paper]{article}',
  172.                  r'\input{../preamble.tex}',
  173.                  fr'\title{{{course_title}}}',
  174.                  r'\begin{document}',
  175.                  r'    \maketitle',
  176.                  r'    \tableofcontents',
  177.                  r'    % start lectures',
  178.                  r'    % end lectures',
  179.                  r'\end{document}'
  180.                 ]
  181.         lectures.master_file.touch()
  182.         lectures.master_file.write_text('\n'.join(lines))
  183.  
  184.         (lectures.root / 'master.tex.latexmain').touch()
  185.  
  186.         info_file = lectures.root / 'info.yaml'
  187.         info_file.touch()
  188.         info_file.write_text(f"title: '{course_title}'")
  189.  
  190.         (lectures.root / 'figures').mkdir()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement