Skip to content

Commit

Permalink
Merge pull request #5 from deathbeds/multi-langauge
Browse files Browse the repository at this point in the history
nothing matters
  • Loading branch information
tonyfast authored Sep 28, 2024
2 parents 09e9f25 + a46c08b commit 4de525c
Show file tree
Hide file tree
Showing 18 changed files with 2,555 additions and 193 deletions.
18 changes: 17 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"

[project.entry-points.midgy]
md = "midgy.tangle:Markdown"
markdown = "midgy.tangle:Markdown"
py = "midgy.language.python:Python"
python = "midgy.language.python:Python"
# yml = "midgy.language.yaml:Yml"
# yaml = "midgy.language.yaml:Yaml"
# js = "midgy.language.js:Js"
# javascript = "midgy.language.js:Js"
# toml = "midgy.language.toml:Toml"

[tool.hatch.build.targets.sdist]
[tool.hatch.build.targets.wheel]

Expand Down Expand Up @@ -98,4 +109,9 @@ black .

[tool.doit]
verbosity = 2
backend = "json"
loader = "doitoml"
backend = "json"

[tool.doitoml.tasks.dev]
doc = "install midgy (and eventually pidgy in dev mode)"
actions = ["pip install -e."]
25 changes: 22 additions & 3 deletions src/midgy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
"""midgy translates (ie tangles) commonmark markdown to python code."""

__all__ = "Python", "md_to_python"
from .python import Python
import sys

from ._version import __version__

tangle = md_to_python = Python.code_from_string

def load_ipython_extension(shell):
from ._ipython import load_ipython_extension

load_ipython_extension(shell)


def unload_ipython_extension(shell):
from ._ipython import unload_ipython_extension

unload_ipython_extension(shell)


if "IPython" in sys.modules:
import IPython
from ._magics import load_ipython_extension as _load_ipython_extension

_load_ipython_extension(IPython.get_ipython())
del IPython, _load_ipython_extension
del sys
138 changes: 138 additions & 0 deletions src/midgy/_argparser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
from argparse import ArgumentParser, BooleanOptionalAction

parser = ArgumentParser("midgy")
parser.add_argument(
"-l",
"--lang",
"--language",
default=None,
type=str,
dest="language",
help="the target language",
)
parser.add_argument(
"--string",
dest="noncode_blocks",
action="store_true",
default=True,
help="include non code markdown as strings",
)
parser.add_argument(
"--comment",
dest="noncode_blocks",
action="store_false",
help="exclude non code markdown as comments",
)
parser.add_argument(
"-i",
"--no-indent",
dest="indented_code_blocks",
action="store_false",
default=True,
help="exclude indented code blocks",
)
# parser.add_argument(
# "-f",
# "--fence",
# dest="fenced_code_blocks",
# default=None,
# nargs="*",
# help="include fenced code",
# )
parser.add_argument(
"--doctest",
dest="doctest_code_blocks",
default=None,
action="store_true",
help="include doctest code blocks",
)
# parser.add_argument("-d", "--description", type=str, default=None, help="snippet description")
# parser.add_argument(
# "-n",
# "--name",
# dest="var",
# help="assign a variable name to the output",
# default=None,
# type=str,
# )
parser.add_argument(
"-u",
"--unsafe",
dest="unsafe",
help="template source before execution",
default=False,
action="store_true",
)

parser.add_argument(
"-s",
"--show",
action="store_true",
dest="show",
default=None,
help="""show the tangled source code""",
)
parser.add_argument(
"-b",
"--black",
action="store_true",
dest="format",
default=None,
help="""format the tangled source code""",
)
parser.add_argument(
"--weave", action="store_true", dest="weave", help="""show the display""", default=True
)
parser.add_argument(
"--lists",
action="store_true",
dest="lists",
help="""don't translate markdown lists to python lists""",
default=".-*",
)
# yaml uses these for lists
parser.add_argument(
"-d",
"--defs",
action="store_true",
dest="defs",
help="""translate markdown definition lists to python dictionaries""",
default=True,
)
parser.add_argument(
"-n",
"--name",
type=str,
dest="name",
help="""name to store the source code as""",
default=None,
)
parser.add_argument(
"-w", "--no-weave", action="store_false", dest="weave", help="""hide the display"""
)
parser.add_argument(
"-p", "--tokens", action="store_true", default=False, help="show parsed markdown tokens"
)
parser.add_argument("-t", "--unittest", action="store_false", default=True, help="test the code")
parser.add_argument(
"-y", "--run", action="store_true", dest="run", help="""execute the source code""", default=True
)
parser.add_argument(
"-x", "--no-run", action="store_false", dest="run", help="""hide the source code"""
)
parser.add_argument("-m", "--module", type=str, help="""a module to execute""")
parser.add_argument(
"--md",
action="store_false",
help="""use the ipython markdown display instead of the html display""",
dest="html",
default=True,
)
parser.add_argument("-c", "--cmd", type=str, help="""a command to execute""")
parser.add_argument("file", nargs="*", type=str, help="a file to execute")


def run(*args):
from .tangle import Tangle

ns = Tangle.from_argv(*args)
81 changes: 81 additions & 0 deletions src/midgy/_ipython.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import dis
from io import StringIO
from .weave import quick_doctest, weave_argv

NEST_ASYNC = None


def post_run_cell(result):
from IPython.display import display, Markdown
from IPython import get_ipython

shell = get_ipython()
if shell.weave.enabled:
cell = result.info.raw_cell
for line in StringIO(cell):
line = line.strip()
if line:
if line.startswith(("%%",)):
break

display(shell.weave.display_cls(cell))
if shell.weave.unittest and "doctest" not in shell.tangle.code_blocks:
quick_doctest(cell)

return


def load_ipython_extension(shell):
shell.input_transformers_cleanup.insert(0, shell.tangle.render_lines)
shell.events.register("post_run_cell", post_run_cell)


def unload_ipython_extension(shell):
if shell.has_trait("tangle"):
try:
shell.input_transformers_cleanup.remove(shell.tangle.parser.render_lines)
shell.events.unregister("post_run_cell", post_run_cell)
except ValueError:
pass


def iframes(string, width="100%", height="600", **kwargs):
from IPython.display import IFrame, display, Markdown
for url in string.split():
display(Markdown(F"[{url}]({url})"), IFrame(url, width=width, height=height, **kwargs))


def run_ipython(source, _retry=False):
global NEST_ASYNC
from asyncio import get_event_loop
from IPython import get_ipython
from IPython.core.interactiveshell import ExecutionResult, ExecutionInfo
from inspect import CO_COROUTINE
from ast import Expression, Module, PyCF_ALLOW_TOP_LEVEL_AWAIT, PyCF_ONLY_AST, Expr
from uuid import uuid1

shell = get_ipython()

filename = str(uuid1()) + ".py"
source = shell.transform_cell(source)
interactivity = "none" if source.rstrip().endswith(";") else shell.ast_node_interactivity
module = compile(source, filename, "exec", PyCF_ONLY_AST)
module = shell.transform_ast(module)
result = ExecutionResult(ExecutionInfo(source, False, False, False, filename))

if NEST_ASYNC is None:
import nest_asyncio

nest_asyncio.apply()
NEST_ASYNC = True

get_event_loop().run_until_complete(
shell.run_ast_nodes(
module.body,
filename,
compiler=shell.compile,
result=result,
interactivity=interactivity,
)
)
return
Loading

0 comments on commit 4de525c

Please sign in to comment.