Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nothing matters #5

Merged
merged 23 commits into from
Sep 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading