diff --git a/104ab42f11_md/media/image1.png b/104ab42f11_md/media/image1.png new file mode 100644 index 0000000..1f3dae6 Binary files /dev/null and b/104ab42f11_md/media/image1.png differ diff --git a/104ab42f11_md/media/image2.png b/104ab42f11_md/media/image2.png new file mode 100644 index 0000000..0140704 Binary files /dev/null and b/104ab42f11_md/media/image2.png differ diff --git a/degrees.py b/degrees.py new file mode 100644 index 0000000..956cb4c --- /dev/null +++ b/degrees.py @@ -0,0 +1,164 @@ +from lark import Lark, Transformer, v_args + + + + +"""describe college courses, their number of units, any other courses that are prerequisites, as well as various degrees which +consist of groups of courses that must be taken. The groups have rules associated with them, such as: +- take all (the following courses) +- take n (where n=3 or 5 or something) +- take at least n units from the following list (so the taken course's unit value must add up to n or greater) +- and so on.""" + + + + +grammar = """ + start: program + + program: course_declaration* + + course_declaration: "course" CNAME INT "prerequisites" (CNAME ","?)* "degree" CNAME "{" degree_rule* "}" + + degree_rule: "take" ("all" | "at" INT "from") ("the" "following") "courses" course_list + + course_list: (CNAME ","?)* + + %import common.CNAME + %import common.INT + %import common.WS + %ignore WS +""" + +class Course: + def __init__(self, name, units, prerequisites, degree): + self.name = name + self.units = units + self.prerequisites = prerequisites + self.degree = degree + +class DegreeRule: + def __init__(self, verb, n, course_list): + self.verb = verb + self.n = n + self.course_list = course_list + +class Degree: + def __init__(self, name, degree_rules): + self.name = name + self.degree_rules = degree_rules + +class Rule: + pass + +class TakeAll(Rule): + def __init__(self, courses): + self.courses = courses + +class TakeN(Rule): + def __init__(self, courses, n): + self.courses = courses + self.n = n + +class TakeNUnits(Rule): + def __init__(self, courses, n): + self.courses = courses + self.n = n + +@v_args(inline=True) +class DSLTransformer(Transformer): + def __init__(self): + self.courses = {} + self.degrees = {} + + def course_declaration(self, name, units, prerequisites, degree): + return Course(name, int(units), prerequisites.children, degree) + + def degree(self, name, required_courses): + self.degrees[name] = Degree(name, required_courses) + + def take_all(self, courses): + return TakeAll(courses) + + def take_n(self, courses, n): + return TakeN(courses, n) + + def take_n_units(self, courses, n): + return TakeNUnits(courses, n) + + def degree_rule(self, items): + verb = items[0] + n = None + course_list = items[-1] + if len(items) == 4: + n = int(items[2]) + return DegreeRule(verb, n, course_list.children) + + def course_list(self, items): + return items[:-1] + + def program(self, items): + courses = [item for item in items if isinstance(item, Course)] + degrees = [item for item in items if isinstance(item, Degree)] + return courses, degrees + + +dsl = DSLTransformer() +dsl.course('CS101', 3) +dsl.course('CS102', 3, prerequisites=['CS101']) +dsl.course('MATH101', 3) +dsl.degree('CS', [ + dsl.take_all(['CS101', 'CS102']), + dsl.take_n_units(['CS101', 'CS102', 'MATH101'], 9), + dsl.take_n(['CS101', 'CS102', 'MATH101'], 2), +]) + +print(dsl.courses) +print(dsl.degrees) + + + + + +parser = Lark(grammar) +transformer = DSLTransformer() + +def parse_dsl(dsl): + tree = parser.parse(dsl) + return transformer.transform(tree) + +dsl = """ +course CS101 3 prerequisites none degree CS { + take all the following courses { + CS102, CS103 + } + take at least 6 from { + MATH101, MATH102, MATH103 + } +} +""" + +courses, degrees = parse_dsl(dsl) +print(courses) +print(degrees) + + + + + +def compute_degree_progress(student_courses, degree): + total_units_completed = 0 + total_required_units = 0 + for course in degree['required_courses']: + if course['id'] in student_courses: + total_units_completed += course['units'] + if 'additional_rules' in course: + for rule in course['additional_rules']: + if rule['type'] == 'at_least_n_units_from_list': + units_from_list = sum([c['units'] for c in degree['courses'] if c['id'] in student_courses and c['id'] in rule['course_list']]) + if units_from_list < rule['n']: + break + total_required_units += course['units'] + progress_percent = total_units_completed / total_required_units * 100 if total_required_units > 0 else 0 + return progress_percent + diff --git a/interactive.py b/interactive.py index e74efd0..5e54a1b 100644 --- a/interactive.py +++ b/interactive.py @@ -16,6 +16,15 @@ from canvas_secrets import flask_secretkey from content import my_site + + + +### SET THIS ENV VAR TO GET RELOADING +# (win) +# set FLASK_ENV=development +# (linux) +# export FLASK_ENV=development + import socket this_host = socket.gethostname() @@ -155,6 +164,15 @@ def flask_thread(q): return image_crop(filename,x,y,w,h,newname) + @app.route('/md', methods=['GET', 'POST']) + def convert_markdown(): + if request.method == 'POST': + markdown_input = request.form.get('markdown_input', '') + html_output = markdown.markdown(markdown_input) + return render_template('basic.html', title='md -> html', html_output=html_output) + return render_template('convert.html') + + # # SAVING STUFF @@ -166,10 +184,13 @@ def flask_thread(q): path = request.form['path'] txt = request.form['content'] - o3 = codecs.open(server.writing_path + path, 'r', 'utf-8') - orig_text = o3.read() - o3.close() - + try: + o3 = codecs.open(server.writing_path + path, 'r', 'utf-8') + orig_text = o3.read() + o3.close() + except Exception as e: + orig_text = '' + bu_filename = server.writing_path + 'older_copies/' + path + '_' + now + '.md' o2 = codecs.open( bu_filename, 'w', 'utf-8' ) o2.write(orig_text) @@ -321,7 +342,7 @@ def flask_thread(q): - socketio.run(app, host= '0.0.0.0') + socketio.run(app, host= '0.0.0.0') # , debug=True diff --git a/server.py b/server.py index 5aaaba7..318937f 100644 --- a/server.py +++ b/server.py @@ -1,5 +1,6 @@ import json, codecs, re, markdown, os, pypandoc, striprtf, sqlite3, random, urllib import subprocess, html, time +from markdownify import markdownify as md from striprtf.striprtf import rtf_to_text from flask import render_template, Response from flask import send_from_directory @@ -145,8 +146,9 @@ def screenoff(): br = "
" nl = "\n" -style = """ +style = """ + """ @@ -188,6 +190,7 @@ def homepage(): a('Pi frame on','/displaypi/on') + br + br + \ a('Pi frame off','/displaypi/off') + br + br + \ a('Knowledge Base','/x/writing/index') + br + \ + a('Markdown -> HTML converter','/md') + br + \ a('Gav web mirror','/mirror') + br + \ a('Graph of users','/x/user/1') + "
" + \ a('Courses in a dept','/x/dept/csis') + "
" + \ @@ -262,7 +265,12 @@ def writing(fname): #output = pypandoc.convert_file('C:/Users/peter/Nextcloud/Documents/writing/' + fname, 'html', output = pypandoc.convert_file(writing_path + fname, 'html', extra_args=['--extract-media=%s' % hash ]) # file:///c:/Users/peter/Nextcloud/Documents/writing - return style + output + output2 = pypandoc.convert_file(writing_path + fname, 'markdown', + extra_args=['--extract-media=%s' % hash+'_md' ]) # file:///c:/Users/peter/Nextcloud/Documents/writing + new_fname = fname[:-5] + '.md' + #as_md = md(output) + return style + output + in_form(editor(output2),new_fname) + return style + markdown.markdown( "".join( [ orgline(x) for x in inp.readlines() ] ) ) diff --git a/templates/basic.html b/templates/basic.html new file mode 100644 index 0000000..403333f --- /dev/null +++ b/templates/basic.html @@ -0,0 +1,14 @@ + + + + {{ title }} + + + +

Converted HTML Output

+
{{ html_output|safe }}
+ + \ No newline at end of file diff --git a/templates/convert.html b/templates/convert.html new file mode 100644 index 0000000..0c421b8 --- /dev/null +++ b/templates/convert.html @@ -0,0 +1,17 @@ + + + + Markdown to HTML Converter + + + +

Markdown to HTML Converter

+
+
+ +
+ + \ No newline at end of file