Volání příkazů jako codeblock #30

Closed
opened 10 months ago by jirikalvoda · 6 comments
Owner

Mohlo by se hodit, kdyby šel vytvořit příkaz, co bude využívat syntaxi bloku kódu.
A pak dostane tento blok jako stringový parametr.

Podobnou věc už vlastně zneužíváme na přímé kusy pythonu, takže to není úplně novinka.
Nicméně kdyby takto šlo volat i příkazy, tak můžu vytvořit příkaz, co například spustí kód v jiném jazyce a vrátí výstup popř. jakkoliv jinak ho zpracuje.

Mohlo by se hodit, kdyby šel vytvořit příkaz, co bude využívat syntaxi bloku kódu. A pak dostane tento blok jako stringový parametr. Podobnou věc už vlastně zneužíváme na přímé kusy pythonu, takže to není úplně novinka. Nicméně kdyby takto šlo volat i příkazy, tak můžu vytvořit příkaz, co například spustí kód v jiném jazyce a vrátí výstup popř. jakkoliv jinak ho zpracuje.

Šlo by udělat něco jako👍:

:::: {c=run_ruby}
```ruby
i don't know the syntax of ruby
```
::::
Šlo by udělat něco jako👍: ```` :::: {c=run_ruby} ```ruby i don't know the syntax of ruby ``` :::: ````
Poster
Owner

Moje představa byla ještě trošku silnější:

```python {define=bash}
import subprocess
c = subprocess.run(["bash", "-c", element.text], stdout=subprocess.PIPE, check=True, encoding="utf-8")
return [pf.Para(pf.Str(c.stdout))]
```

```bash {c=bash}
cat /etc/hostname
```

Implementace by mohla být zhruba takováto:

diff --git a/src/formatitko/transform_processor.py b/src/formatitko/transform_processor.py
index b0032cf..d0cb01c 100644
--- a/src/formatitko/transform_processor.py
+++ b/src/formatitko/transform_processor.py
@@ -446,6 +446,17 @@ class TransformProcessor:
                        e = BlockCommand().replaceSelf(*([] if command_output is None else command_output))
                        return self.transform(e)

+               if "c" in e.attributes:
+                       if not self.context.trusted:
+                               return nullify(e)
+                       if not self.context.get_command(e.attributes["c"]):
+                               raise NameError(f"Command not defined '{e.attributes['c']}'.")
+                       content = self.context.get_command(e.attributes["c"])(e, self.context)
+                       try:
+                               return Div(*content)
+                       except TypeError:
+                               return Div(Para(*content))
+
                if "python" in e.classes and ("define" in e.attributes or "redefine" in e.attributes):
                        if not self.context.trusted:
                                return nullify(e)
Moje představa byla ještě trošku silnější: ```` ```python {define=bash} import subprocess c = subprocess.run(["bash", "-c", element.text], stdout=subprocess.PIPE, check=True, encoding="utf-8") return [pf.Para(pf.Str(c.stdout))] ``` ```bash {c=bash} cat /etc/hostname ``` ```` Implementace by mohla být zhruba takováto: ```diff diff --git a/src/formatitko/transform_processor.py b/src/formatitko/transform_processor.py index b0032cf..d0cb01c 100644 --- a/src/formatitko/transform_processor.py +++ b/src/formatitko/transform_processor.py @@ -446,6 +446,17 @@ class TransformProcessor: e = BlockCommand().replaceSelf(*([] if command_output is None else command_output)) return self.transform(e) + if "c" in e.attributes: + if not self.context.trusted: + return nullify(e) + if not self.context.get_command(e.attributes["c"]): + raise NameError(f"Command not defined '{e.attributes['c']}'.") + content = self.context.get_command(e.attributes["c"])(e, self.context) + try: + return Div(*content) + except TypeError: + return Div(Para(*content)) + if "python" in e.classes and ("define" in e.attributes or "redefine" in e.attributes): if not self.context.trusted: return nullify(e) ```
Poster
Owner

Možná by pak ale stálo za to u definicí funkcí uvádět, jaké módy použití jsou u ní "tolerované", protože podle toho se dost mění, co funkce dostane na vstupu.

Dávalo by za tebe něco takového smysl?

Možná by pak ale stálo za to u definicí funkcí uvádět, jaké módy použití jsou u ní "tolerované", protože podle toho se dost mění, co funkce dostane na vstupu. Dávalo by za tebe něco takového smysl?

Tu silnější představu chápu, ale přijde mi to už jako trochu "syntax sugar", který zbytečně přidává komplexitu formátítku, která by se dala vyřešit relativně malou komplexitou definovaného commandu.

def bash(element, context):
	import subprocess
    if len(element.content) == 1 and isinstance(element.content[0], pf.CodeBlock):
		c = subprocess.run(["bash", "-c", element.content[0].text], 			stdout=subprocess.PIPE, check=True, encoding="utf-8")
		return [pf.Para(pf.Str(c.stdout))]
    else:
    	raise Error("Jsem smutný")

Pak to půjde spustit jako

::: {c=bash}
```bash
cat /etc/passwd
```
:::
Tu silnější představu chápu, ale přijde mi to už jako trochu "syntax sugar", který zbytečně přidává komplexitu formátítku, která by se dala vyřešit relativně malou komplexitou definovaného commandu. ```python def bash(element, context): import subprocess if len(element.content) == 1 and isinstance(element.content[0], pf.CodeBlock): c = subprocess.run(["bash", "-c", element.content[0].text], stdout=subprocess.PIPE, check=True, encoding="utf-8") return [pf.Para(pf.Str(c.stdout))] else: raise Error("Jsem smutný") ``` Pak to půjde spustit jako ````markdown ::: {c=bash} ```bash cat /etc/passwd ``` ::: ````
Poster
Owner

Jasně chápu tvoji připomínku a ano, defakto dělám jen syntaktický cukr, takže je diskutabilní, jestli ho chceme.
Ovšem z mého pohledu mi připadá, že funkce, co berou na vstupu něco, co není markdown ale jen text může být docela častý patern, takže bych se asi na něj nebál optimaliovat.

Na druhou stranu moc netuším, jak se to může vyvynout v budoucnu a kolik věcí by to pak případně zkomplikovalo.

Jasně chápu tvoji připomínku a ano, defakto dělám jen syntaktický cukr, takže je diskutabilní, jestli ho chceme. Ovšem z mého pohledu mi připadá, že funkce, co berou na vstupu něco, co není markdown ale jen text může být docela častý patern, takže bych se asi na něj nebál optimaliovat. Na druhou stranu moc netuším, jak se to může vyvynout v budoucnu a kolik věcí by to pak případně zkomplikovalo.
jan closed this issue 10 months ago

Ok, nakonec jsem to naimplementoval, protože se mi to in hidnsight docela líbí a dá se s tím dělat hezká magie. Chceš aby ti formátítko zbuildilo a spustilo Go? Pětiřádkový command to za tebe vyřeší.

Ok, nakonec jsem to naimplementoval, protože se mi to in hidnsight docela líbí a dá se s tím dělat hezká magie. Chceš aby ti formátítko zbuildilo a spustilo Go? Pětiřádkový command to za tebe vyřeší.
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.