2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Adapters for the cheat sheets from the Learn X in Y project
|
|
|
|
"""
|
2018-07-03 23:09:51 +03:00
|
|
|
from __future__ import print_function
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
|
|
|
|
class LearnXYAdapter(object):
|
2018-05-06 20:43:54 +03:00
|
|
|
|
|
|
|
"""
|
|
|
|
Parent class of all languages adapters
|
|
|
|
"""
|
|
|
|
|
2017-05-28 17:39:09 +03:00
|
|
|
_learn_xy_path = "/home/igor/git/github.com/adambard/learnxinyminutes-docs"
|
2018-05-06 20:43:54 +03:00
|
|
|
_replace_with = {}
|
|
|
|
_filename = ''
|
|
|
|
prefix = ''
|
2018-05-13 17:31:10 +03:00
|
|
|
_replace_with = {}
|
|
|
|
_splitted = True
|
|
|
|
_block_cut_start = 2
|
|
|
|
_block_cut_end = 0
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
|
|
|
|
self._whole_cheatsheet = self._read_cheatsheet()
|
|
|
|
self._blocks = self._extract_blocks()
|
2018-05-06 20:43:54 +03:00
|
|
|
|
|
|
|
self._topics_list = [x for x, _ in self._blocks]
|
|
|
|
if "Comments" in self._topics_list:
|
|
|
|
self._topics_list = [x for x in self._topics_list if x != "Comments"] + ["Comments"]
|
|
|
|
self._topics_list += [":learn"]
|
2018-07-03 23:09:51 +03:00
|
|
|
print(self.prefix, self._topics_list)
|
2018-05-06 20:43:54 +03:00
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-13 17:31:10 +03:00
|
|
|
if (re.match(r'////////*', before)
|
|
|
|
and re.match(r'// ', now)
|
|
|
|
and re.match(r'////////*', after)):
|
|
|
|
block_name = re.sub(r'//\s*', '', now).replace('(', '').replace(')', '')
|
|
|
|
block_name = '_'.join(block_name.strip(", ").split())
|
|
|
|
for character in '/,':
|
|
|
|
block_name = block_name.replace(character, '')
|
|
|
|
for k in self._replace_with:
|
|
|
|
if k in block_name:
|
|
|
|
block_name = self._replace_with[k]
|
|
|
|
return block_name
|
|
|
|
return None
|
2018-05-06 20:43:54 +03:00
|
|
|
|
2018-05-13 17:31:10 +03:00
|
|
|
def _cut_block(self, block, start_block=False):
|
|
|
|
if not start_block:
|
|
|
|
answer = block[self._block_cut_start:-self._block_cut_end]
|
|
|
|
if answer == []:
|
|
|
|
return answer
|
|
|
|
if answer[0].strip() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].strip() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
def _read_cheatsheet(self):
|
|
|
|
filename = os.path.join(self._learn_xy_path, self._filename)
|
|
|
|
|
2018-05-06 20:43:54 +03:00
|
|
|
with open(filename) as f_cheat_sheet:
|
2017-05-28 17:39:09 +03:00
|
|
|
code_mode = False
|
|
|
|
answer = []
|
2018-05-06 20:43:54 +03:00
|
|
|
for line in f_cheat_sheet.readlines():
|
2017-05-28 17:39:09 +03:00
|
|
|
if line.startswith('```'):
|
|
|
|
if not code_mode:
|
|
|
|
code_mode = True
|
|
|
|
continue
|
|
|
|
else:
|
2017-06-02 18:53:19 +03:00
|
|
|
code_mode = False
|
2017-05-28 17:39:09 +03:00
|
|
|
if code_mode:
|
|
|
|
answer.append(line.rstrip('\n'))
|
2017-06-02 18:53:19 +03:00
|
|
|
return answer
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
def _extract_blocks(self):
|
2018-05-13 17:31:10 +03:00
|
|
|
|
|
|
|
if not self._splitted:
|
|
|
|
return []
|
|
|
|
|
2017-05-28 17:39:09 +03:00
|
|
|
lines = self._whole_cheatsheet
|
|
|
|
answer = []
|
|
|
|
|
|
|
|
block = []
|
2018-05-06 20:43:54 +03:00
|
|
|
block_name = "Comments"
|
2017-05-28 17:39:09 +03:00
|
|
|
for before, now, after in zip([""]+lines, lines, lines[1:]):
|
|
|
|
new_block_name = self._is_block_separator(before, now, after)
|
|
|
|
if new_block_name:
|
|
|
|
if block_name:
|
2018-05-06 20:43:54 +03:00
|
|
|
block_text = self._cut_block(block)
|
|
|
|
if block_text != []:
|
|
|
|
answer.append((block_name, block_text))
|
2017-05-28 17:39:09 +03:00
|
|
|
block_name = new_block_name
|
|
|
|
block = []
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
block.append(before)
|
|
|
|
|
2017-05-29 01:22:46 +03:00
|
|
|
answer.append((block_name, self._cut_block(block)))
|
2017-05-28 17:39:09 +03:00
|
|
|
return answer
|
|
|
|
|
|
|
|
def is_valid(self, name):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Check whether topic `name` is valid.
|
|
|
|
"""
|
|
|
|
|
|
|
|
for topic_list in self._topics_list:
|
|
|
|
if topic_list == name:
|
2017-05-28 17:39:09 +03:00
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
def get_list(self, prefix=False):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Get list of topics for `prefix`
|
|
|
|
"""
|
2017-05-28 17:39:09 +03:00
|
|
|
if prefix:
|
2018-05-06 20:43:54 +03:00
|
|
|
return ["%s/%s" % (self.prefix, x) for x in self._topics_list]
|
|
|
|
return self._topics_list
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
def get_cheat_sheet(self, name, partial=False):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Return specified cheat sheet `name` for the language.
|
|
|
|
If `partial`, cheat sheet name may be shortened
|
|
|
|
"""
|
|
|
|
|
2017-05-29 00:46:35 +03:00
|
|
|
if name == ":list":
|
|
|
|
return "\n".join(self.get_list()) + "\n"
|
|
|
|
|
|
|
|
if name == ":learn":
|
|
|
|
return "\n".join(self._whole_cheatsheet) + "\n"
|
|
|
|
|
2017-05-28 17:39:09 +03:00
|
|
|
if partial:
|
|
|
|
possible_names = []
|
2018-05-06 20:43:54 +03:00
|
|
|
for block_name, _ in self._blocks:
|
|
|
|
if block_name.startswith(name):
|
|
|
|
possible_names.append(block_name)
|
|
|
|
if possible_names == [] or len(possible_names) > 1:
|
2017-05-28 17:39:09 +03:00
|
|
|
return None
|
|
|
|
name = possible_names[0]
|
|
|
|
|
2018-05-06 20:43:54 +03:00
|
|
|
for block_name, block_contents in self._blocks:
|
|
|
|
if block_name == name:
|
|
|
|
|
2018-07-03 23:09:51 +03:00
|
|
|
print("\n".join(block_contents))
|
|
|
|
print(name)
|
2018-05-06 20:43:54 +03:00
|
|
|
return "\n".join(block_contents)
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
#
|
2018-05-06 20:43:54 +03:00
|
|
|
# Specific programming languages LearnXY cheat sheets configurations
|
|
|
|
# Contains much code for the moment; should contain data only
|
|
|
|
# ideally should be replaced with YAML
|
2017-05-28 17:39:09 +03:00
|
|
|
#
|
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnAwkAdapter(LearnXYAdapter):
|
|
|
|
"Learn AWK in Y Minutes"
|
|
|
|
prefix = "awk"
|
|
|
|
_filename = "awk.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnBashAdapter(LearnXYAdapter):
|
|
|
|
"Learn Bash in Y Minutes"
|
|
|
|
prefix = "bash"
|
|
|
|
_filename = "bash.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnBfAdapter(LearnXYAdapter):
|
|
|
|
"Learn Brainfuck in Y Minutes"
|
|
|
|
prefix = "bf"
|
|
|
|
_filename = "bf.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnChapelAdapter(LearnXYAdapter):
|
|
|
|
"Learn Chapel in Y Minutes"
|
|
|
|
prefix = "chapel"
|
|
|
|
_filename = "chapel.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2017-06-15 22:48:28 +03:00
|
|
|
class LearnClojureAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Clojure in Y Minutes
|
|
|
|
"""
|
|
|
|
|
|
|
|
prefix = "clojure"
|
2017-06-15 22:48:28 +03:00
|
|
|
_filename = "clojure.html.markdown"
|
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match(r'\s*$', before)
|
|
|
|
and re.match(r';\s*', now)
|
|
|
|
and re.match(r';;;;;;+', after)):
|
|
|
|
block_name = re.sub(r';\s*', '', now)
|
2017-06-15 22:48:28 +03:00
|
|
|
block_name = '_'.join([x.strip(",&:") for x in block_name.strip(", ").split()])
|
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
|
|
|
if not start_block:
|
|
|
|
answer = block[2:]
|
2017-06-15 22:48:28 +03:00
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnCoffeeScriptAdapter(LearnXYAdapter):
|
|
|
|
"Learn coffeescript in Y Minutes"
|
|
|
|
prefix = "coffee"
|
|
|
|
_filename = "coffeescript.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2017-07-25 20:41:22 +03:00
|
|
|
class LearnCppAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn C++ in Y Minutes
|
|
|
|
"""
|
|
|
|
|
|
|
|
prefix = "cpp"
|
2017-07-25 20:41:22 +03:00
|
|
|
_filename = "c++.html.markdown"
|
2018-05-06 20:43:54 +03:00
|
|
|
_replace_with = {
|
|
|
|
'More_about_Objects': 'Prototypes',
|
|
|
|
}
|
2017-07-25 20:41:22 +03:00
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match(r'////////*', before)
|
|
|
|
and re.match(r'// ', now)
|
|
|
|
and re.match(r'////////*', after)):
|
|
|
|
block_name = re.sub(r'//\s*', '', now).replace('(', '').replace(')', '')
|
2017-07-25 20:41:22 +03:00
|
|
|
block_name = '_'.join(block_name.strip(", ").split())
|
2018-05-06 20:43:54 +03:00
|
|
|
for character in '/,':
|
|
|
|
block_name = block_name.replace(character, '')
|
|
|
|
for k in self._replace_with:
|
2017-07-25 20:41:22 +03:00
|
|
|
if k in block_name:
|
2018-05-06 20:43:54 +03:00
|
|
|
block_name = self._replace_with[k]
|
2017-07-25 20:41:22 +03:00
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-07-25 20:41:22 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-07-25 20:41:22 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer == []:
|
|
|
|
return answer
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnCsharpAdapter(LearnXYAdapter):
|
|
|
|
"Learn C# in Y Minutes"
|
|
|
|
prefix = "csharp"
|
|
|
|
_filename = "csharp.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnDAdapter(LearnXYAdapter):
|
|
|
|
"Learn D in Y Minutes"
|
|
|
|
prefix = "d"
|
|
|
|
_filename = "d.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnDartAdapter(LearnXYAdapter):
|
|
|
|
"Learn Dart in Y Minutes"
|
|
|
|
prefix = "dart"
|
|
|
|
_filename = "dart.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnFactorAdapter(LearnXYAdapter):
|
|
|
|
"Learn Factor in Y Minutes"
|
|
|
|
prefix = "factor"
|
|
|
|
_filename = "factor.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnForthAdapter(LearnXYAdapter):
|
|
|
|
"Learn Forth in Y Minutes"
|
|
|
|
prefix = "forth"
|
|
|
|
_filename = "forth.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnFsharpAdapter(LearnXYAdapter):
|
|
|
|
"Learn F# in Y Minutes"
|
|
|
|
prefix = "fsharp"
|
|
|
|
_filename = "fsharp.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnElispAdapter(LearnXYAdapter):
|
|
|
|
"Learn Elisp in Y Minutes"
|
|
|
|
prefix = "elisp"
|
|
|
|
_filename = "elisp.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2017-06-15 22:48:28 +03:00
|
|
|
class LearnElixirAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Elixir in Y Minutes
|
|
|
|
"""
|
|
|
|
|
|
|
|
prefix = "elixir"
|
2017-06-15 22:48:28 +03:00
|
|
|
_filename = "elixir.html.markdown"
|
2018-05-06 20:43:54 +03:00
|
|
|
_replace_with = {
|
|
|
|
'More_about_Objects': 'Prototypes',
|
|
|
|
}
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match(r'## ---*', before)
|
|
|
|
and re.match(r'## --', now)
|
|
|
|
and re.match(r'## ---*', after)):
|
|
|
|
block_name = re.sub(r'## --\s*', '', now)
|
2017-06-15 22:48:28 +03:00
|
|
|
block_name = '_'.join(block_name.strip(", ").split())
|
2018-05-06 20:43:54 +03:00
|
|
|
for character in '/,':
|
|
|
|
block_name = block_name.replace(character, '')
|
|
|
|
for k in self._replace_with:
|
2017-06-15 22:48:28 +03:00
|
|
|
if k in block_name:
|
2018-05-06 20:43:54 +03:00
|
|
|
block_name = self._replace_with[k]
|
2017-06-15 22:48:28 +03:00
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-15 22:48:28 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
|
|
|
class LearnElmAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Elm in Y Minutes
|
|
|
|
"""
|
|
|
|
|
|
|
|
prefix = "elm"
|
2017-06-15 22:48:28 +03:00
|
|
|
_filename = "elm.html.markdown"
|
2018-05-06 20:43:54 +03:00
|
|
|
_replace_with = {
|
|
|
|
'More_about_Objects': 'Prototypes',
|
|
|
|
}
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match(r'\s*', before)
|
|
|
|
and re.match(r'\{--.*--\}', now)
|
|
|
|
and re.match(r'\s*', after)):
|
|
|
|
block_name = re.sub(r'\{--+\s*', '', now)
|
|
|
|
block_name = re.sub(r'--\}', '', block_name)
|
2017-06-15 22:48:28 +03:00
|
|
|
block_name = '_'.join(block_name.strip(", ").split())
|
2018-05-06 20:43:54 +03:00
|
|
|
for character in '/,':
|
|
|
|
block_name = block_name.replace(character, '')
|
|
|
|
for k in self._replace_with:
|
2017-06-15 22:48:28 +03:00
|
|
|
if k in block_name:
|
2018-05-06 20:43:54 +03:00
|
|
|
block_name = self._replace_with[k]
|
2017-06-15 22:48:28 +03:00
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-15 22:48:28 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
|
|
|
class LearnErlangAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Erlang in Y Minutes
|
|
|
|
"""
|
|
|
|
|
|
|
|
prefix = "erlang"
|
2017-06-15 22:48:28 +03:00
|
|
|
_filename = "erlang.html.markdown"
|
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match('%%%%%%+', before)
|
|
|
|
and re.match(r'%%\s+[0-9]+\.', now)
|
|
|
|
and re.match('%%%%%%+', after)):
|
|
|
|
block_name = re.sub(r'%%+\s+[0-9]+\.\s*', '', now)
|
2017-06-15 22:48:28 +03:00
|
|
|
block_name = '_'.join(block_name.strip('.').strip().split())
|
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-15 22:48:28 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnFortranAdapter(LearnXYAdapter):
|
|
|
|
"Learn Fortran in Y Minutes"
|
|
|
|
prefix = "fortran"
|
|
|
|
_filename = "fortran95.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2018-05-13 17:31:10 +03:00
|
|
|
class LearnGoAdapter(LearnXYAdapter):
|
|
|
|
"Learn Go in Y Minutes"
|
|
|
|
prefix = "go"
|
|
|
|
_filename = "go.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnGroovyAdapter(LearnXYAdapter):
|
|
|
|
"Learn Groovy in Y Minutes"
|
|
|
|
prefix = "groovy"
|
|
|
|
_filename = "groovy.html.markdown"
|
|
|
|
_splitted = False
|
2017-06-02 18:53:19 +03:00
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnJavaAdapter(LearnXYAdapter):
|
|
|
|
"Learn Java in Y Minutes"
|
|
|
|
prefix = "java"
|
|
|
|
_filename = "java.html.markdown"
|
|
|
|
_splitted = False
|
2017-06-02 18:53:19 +03:00
|
|
|
|
2017-06-11 14:52:26 +03:00
|
|
|
class LearnJavaScriptAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn JavaScript in Y Minutes
|
|
|
|
"""
|
|
|
|
prefix = "js"
|
2017-06-11 14:52:26 +03:00
|
|
|
_filename = "javascript.html.markdown"
|
2018-05-06 20:43:54 +03:00
|
|
|
_replace_with = {
|
|
|
|
'More_about_Objects': 'Prototypes',
|
|
|
|
}
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match('//////+', before)
|
|
|
|
and re.match(r'//+\s+[0-9]+\.', now)
|
|
|
|
and re.match(r'\s*', after)):
|
|
|
|
block_name = re.sub(r'//+\s+[0-9]+\.\s*', '', now)
|
2017-06-11 14:52:26 +03:00
|
|
|
block_name = '_'.join(block_name.strip(", ").split())
|
2018-05-06 20:43:54 +03:00
|
|
|
for k in self._replace_with:
|
2017-06-11 14:52:26 +03:00
|
|
|
if k in block_name:
|
2018-05-06 20:43:54 +03:00
|
|
|
block_name = self._replace_with[k]
|
2017-05-28 17:39:09 +03:00
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-11 14:52:26 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
2017-05-28 17:39:09 +03:00
|
|
|
|
2017-06-15 22:48:28 +03:00
|
|
|
class LearnJuliaAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Julia in Y Minutes
|
|
|
|
"""
|
|
|
|
prefix = "julia"
|
2017-06-15 22:48:28 +03:00
|
|
|
_filename = "julia.html.markdown"
|
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match('####+', before)
|
|
|
|
and re.match(r'##\s*', now)
|
|
|
|
and re.match('####+', after)):
|
2017-06-15 22:48:28 +03:00
|
|
|
block_name = re.sub(r'##\s+[0-9]+\.\s*', '', now)
|
|
|
|
block_name = '_'.join(block_name.strip(", ").split())
|
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-15 22:48:28 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
|
|
|
class LearnHaskellAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Haskell in Y Minutes
|
|
|
|
"""
|
|
|
|
prefix = "haskell"
|
2017-06-15 22:48:28 +03:00
|
|
|
_filename = "haskell.html.markdown"
|
2018-05-06 20:43:54 +03:00
|
|
|
_replace_with = {
|
|
|
|
'More_about_Objects': 'Prototypes',
|
|
|
|
}
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match('------+', before)
|
|
|
|
and re.match(r'--+\s+[0-9]+\.', now)
|
|
|
|
and re.match('------+', after)):
|
|
|
|
block_name = re.sub(r'--+\s+[0-9]+\.\s*', '', now)
|
2017-06-15 22:48:28 +03:00
|
|
|
block_name = '_'.join(block_name.strip(", ").split())
|
2018-05-06 20:43:54 +03:00
|
|
|
for k in self._replace_with:
|
2017-06-15 22:48:28 +03:00
|
|
|
if k in block_name:
|
2018-05-06 20:43:54 +03:00
|
|
|
block_name = self._replace_with[k]
|
2017-06-15 22:48:28 +03:00
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-15 22:48:28 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnLispAdapter(LearnXYAdapter):
|
|
|
|
"Learn Lisp in Y Minutes"
|
|
|
|
prefix = "lisp"
|
|
|
|
_filename = "common-lisp.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnLuaAdapter(LearnXYAdapter):
|
|
|
|
"""
|
|
|
|
Learn Lua in Y Minutes
|
|
|
|
"""
|
|
|
|
prefix = "lua"
|
|
|
|
_filename = "lua.html.markdown"
|
|
|
|
_replace_with = {
|
|
|
|
'1_Metatables_and_metamethods': 'Metatables',
|
|
|
|
'2_Class-like_tables_and_inheritance': 'Class-like_tables',
|
|
|
|
'Variables_and_flow_control': 'Flow_control',
|
|
|
|
}
|
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
|
|
|
if (re.match('-----+', before)
|
|
|
|
and re.match('-------+', after)
|
|
|
|
and re.match(r'--\s+[0-9]+\.', now)):
|
|
|
|
block_name = re.sub(r'--+\s+[0-9]+\.\s*', '', now)
|
|
|
|
block_name = '_'.join(block_name.strip('.').strip().split())
|
|
|
|
if block_name in self._replace_with:
|
|
|
|
block_name = self._replace_with[block_name]
|
|
|
|
return block_name
|
|
|
|
return None
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def _cut_block(block, start_block=False):
|
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
|
|
|
class LearnMatlabAdapter(LearnXYAdapter):
|
|
|
|
"Learn Matlab in Y Minutes"
|
|
|
|
prefix = "matlab"
|
|
|
|
_filename = "matlab.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2017-06-11 14:52:26 +03:00
|
|
|
class LearnKotlinAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Kotlin in Y Minutes
|
|
|
|
"""
|
|
|
|
prefix = "kotlin"
|
2017-06-11 14:52:26 +03:00
|
|
|
_filename = "kotlin.html.markdown"
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match('#######+', before)
|
|
|
|
and re.match('#######+', after)
|
|
|
|
and re.match(r'#+\s+[0-9]+\.', now)):
|
|
|
|
block_name = re.sub(r'#+\s+[0-9]+\.\s*', '', now)
|
2017-05-28 17:39:09 +03:00
|
|
|
block_name = '_'.join(block_name.strip().split())
|
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-05-29 01:22:46 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
2017-05-28 17:39:09 +03:00
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnObjectiveCAdapter(LearnXYAdapter):
|
|
|
|
"Learn Objective C in Y Minutes"
|
|
|
|
prefix = "objective-c"
|
|
|
|
_filename = "objective-c.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2017-06-15 22:48:28 +03:00
|
|
|
class LearnOCamlAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn OCaml in Y Minutes
|
|
|
|
"""
|
|
|
|
prefix = "ocaml"
|
2017-06-15 22:48:28 +03:00
|
|
|
_filename = "ocaml.html.markdown"
|
2018-05-06 20:43:54 +03:00
|
|
|
_replace_with = {
|
|
|
|
'More_about_Objects': 'Prototypes',
|
|
|
|
}
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match(r'\s*', before)
|
|
|
|
and re.match(r'\(\*\*\*+', now)
|
|
|
|
and re.match(r'\s*', after)):
|
2017-06-15 22:48:28 +03:00
|
|
|
block_name = re.sub(r'\(\*\*\*+\s*', '', now)
|
|
|
|
block_name = re.sub(r'\s*\*\*\*\)', '', block_name)
|
|
|
|
block_name = '_'.join(block_name.strip(", ").split())
|
2018-05-06 20:43:54 +03:00
|
|
|
for k in self._replace_with:
|
2017-06-15 22:48:28 +03:00
|
|
|
if k in block_name:
|
2018-05-06 20:43:54 +03:00
|
|
|
block_name = self._replace_with[k]
|
2017-06-15 22:48:28 +03:00
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-15 22:48:28 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-15 22:48:28 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
2017-06-02 18:53:19 +03:00
|
|
|
class LearnPerlAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Perl in Y Minutes
|
|
|
|
"""
|
|
|
|
prefix = "perl"
|
2017-06-02 18:53:19 +03:00
|
|
|
_filename = "perl.html.markdown"
|
2018-05-06 20:43:54 +03:00
|
|
|
_replace_with = {
|
|
|
|
'Conditional_and_looping_constructs': 'Control_Flow',
|
|
|
|
'Perl_variable_types': 'Types',
|
|
|
|
'Files_and_I/O': 'Files',
|
|
|
|
'Writing_subroutines': 'Subroutines',
|
|
|
|
}
|
2017-06-02 18:53:19 +03:00
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if re.match(r'####+\s+', now):
|
|
|
|
block_name = re.sub(r'#+\s', '', now)
|
2017-06-02 18:53:19 +03:00
|
|
|
block_name = '_'.join(block_name.strip().split())
|
2018-05-06 20:43:54 +03:00
|
|
|
if block_name in self._replace_with:
|
|
|
|
block_name = self._replace_with[block_name]
|
2017-06-02 18:53:19 +03:00
|
|
|
return block_name
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
|
|
|
if not start_block:
|
|
|
|
answer = block[2:]
|
|
|
|
if answer == []:
|
2017-06-02 18:53:19 +03:00
|
|
|
return answer
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnPerl6Adapter(LearnXYAdapter):
|
|
|
|
"Learn Perl 6 in Y Minutes"
|
|
|
|
prefix = "perl6"
|
|
|
|
_filename = "perl6.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2017-06-11 14:52:26 +03:00
|
|
|
class LearnPHPAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn PHP in Y Minutes
|
|
|
|
"""
|
|
|
|
prefix = "php"
|
2017-06-11 14:52:26 +03:00
|
|
|
_filename = "php.html.markdown"
|
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match(r'/\*\*\*\*\*+', before)
|
|
|
|
and re.match(r'\s*\*/', after)
|
|
|
|
and re.match(r'\s*\*\s*', now)):
|
2017-06-11 14:52:26 +03:00
|
|
|
block_name = re.sub(r'\s*\*\s*', '', now)
|
|
|
|
block_name = re.sub(r'&', '', block_name)
|
|
|
|
block_name = '_'.join(block_name.strip().split())
|
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-11 14:52:26 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-11 14:52:26 +03:00
|
|
|
return block[2:]
|
|
|
|
|
|
|
|
class LearnPythonAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Python in Y Minutes
|
|
|
|
"""
|
|
|
|
prefix = "python"
|
2017-06-11 14:52:26 +03:00
|
|
|
_filename = "python.html.markdown"
|
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match('#######+', before)
|
|
|
|
and re.match('#######+', after)
|
|
|
|
and re.match(r'#+\s+[0-9]+\.', now)):
|
|
|
|
block_name = re.sub(r'#+\s+[0-9]+\.\s*', '', now)
|
2017-06-11 14:52:26 +03:00
|
|
|
block_name = '_'.join(block_name.strip().split())
|
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-11 14:52:26 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-11 14:52:26 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnPython3Adapter(LearnXYAdapter):
|
|
|
|
"Learn Python 3 in Y Minutes"
|
|
|
|
prefix = "python3"
|
|
|
|
_filename = "python3.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnRAdapter(LearnXYAdapter):
|
|
|
|
"Learn R in Y Minutes"
|
|
|
|
prefix = "r"
|
|
|
|
_filename = "r.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnRacketAdapter(LearnXYAdapter):
|
|
|
|
"Learn Racket in Y Minutes"
|
|
|
|
prefix = "racket"
|
|
|
|
_filename = "racket.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2017-06-11 14:52:26 +03:00
|
|
|
class LearnRubyAdapter(LearnXYAdapter):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Learn Ruby in Y Minutes
|
|
|
|
|
|
|
|
Format of the file was changed, so we have to fix the function too.
|
|
|
|
This case is a good case for health check:
|
|
|
|
if number of extracted cheat sheets is suddenly became 1,
|
|
|
|
one should check the markup
|
|
|
|
"""
|
|
|
|
prefix = "ruby"
|
2017-06-11 14:52:26 +03:00
|
|
|
_filename = "ruby.html.markdown"
|
|
|
|
|
|
|
|
def _is_block_separator(self, before, now, after):
|
2018-05-06 20:43:54 +03:00
|
|
|
if (re.match('#######+', before)
|
|
|
|
and re.match('#######+', after)
|
|
|
|
and re.match(r'#+\s+[0-9]+\.', now)):
|
|
|
|
block_name = re.sub(r'#+\s+[0-9]+\.\s*', '', now)
|
2017-06-11 14:52:26 +03:00
|
|
|
block_name = '_'.join(block_name.strip().split())
|
|
|
|
return block_name
|
2018-05-06 20:43:54 +03:00
|
|
|
return None
|
2017-06-11 14:52:26 +03:00
|
|
|
|
|
|
|
@staticmethod
|
2018-05-06 20:43:54 +03:00
|
|
|
def _cut_block(block, start_block=False):
|
2017-06-11 14:52:26 +03:00
|
|
|
answer = block[2:-1]
|
|
|
|
if answer[0].split() == '':
|
|
|
|
answer = answer[1:]
|
|
|
|
if answer[-1].split() == '':
|
|
|
|
answer = answer[:1]
|
|
|
|
return answer
|
|
|
|
|
2018-05-15 02:03:40 +03:00
|
|
|
class LearnSwiftAdapter(LearnXYAdapter):
|
|
|
|
"Learn Swift in Y Minutes"
|
|
|
|
prefix = "swift"
|
|
|
|
_filename = "swift.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnTclAdapter(LearnXYAdapter):
|
|
|
|
"Learn Tcl in Y Minutes"
|
|
|
|
prefix = "tcl"
|
|
|
|
_filename = "tcl.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnTcshAdapter(LearnXYAdapter):
|
|
|
|
"Learn Tcsh in Y Minutes"
|
|
|
|
prefix = "tcsh"
|
|
|
|
_filename = "tcsh.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
|
|
|
class LearnVisualBasicAdapter(LearnXYAdapter):
|
|
|
|
"Learn Visual Basic in Y Minutes"
|
|
|
|
prefix = "vb"
|
|
|
|
_filename = "visualbasic.html.markdown"
|
|
|
|
_splitted = False
|
|
|
|
|
2018-05-06 20:43:54 +03:00
|
|
|
ADAPTERS = {cls.prefix: cls() for cls in vars()['LearnXYAdapter'].__subclasses__()}
|
2017-05-28 17:39:09 +03:00
|
|
|
|
|
|
|
def get_learnxiny(topic):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Return cheat sheet for `topic`
|
|
|
|
or empty string if nothing found
|
|
|
|
"""
|
2017-05-28 17:39:09 +03:00
|
|
|
lang, topic = topic.split('/', 1)
|
|
|
|
if lang not in ADAPTERS:
|
|
|
|
return ''
|
|
|
|
return ADAPTERS[lang].get_cheat_sheet(topic)
|
|
|
|
|
|
|
|
def get_learnxiny_list():
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Return list of all learnxiny topics
|
|
|
|
"""
|
2017-05-28 17:39:09 +03:00
|
|
|
answer = []
|
2018-05-06 20:43:54 +03:00
|
|
|
for language_adapter in ADAPTERS.values():
|
|
|
|
answer += language_adapter.get_list(prefix=True)
|
2017-05-28 17:39:09 +03:00
|
|
|
return answer
|
|
|
|
|
|
|
|
def is_valid_learnxy(topic):
|
2018-05-06 20:43:54 +03:00
|
|
|
"""
|
|
|
|
Return whether `topic` is a valid learnxiny topic
|
|
|
|
"""
|
|
|
|
|
2017-05-28 17:39:09 +03:00
|
|
|
lang, topic = topic.split('/', 1)
|
|
|
|
if lang not in ADAPTERS:
|
|
|
|
return False
|
|
|
|
|
|
|
|
return ADAPTERS[lang].is_valid(topic)
|