{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Margo Syntax Primer\n", "\n", "This is probably the last notebook you should read.\n", "\n", "So far we've seen how Margo notes are used with `margo_loader` and the `margo-tool` CLI tool. But Margo is a flexible syntax, designed to extend Jupyter Notebooks in any way you can imagine.\n", "\n", "In fact, all of the keywords we've read about in this tutorial, like `ignore-cell` are not even part of Margo's syntax specification. Margo's syntax has no keywords. Instead, it's up to the community to decide on the meaning of keywords.\n", "\n", "For information on reserving Margo keywords, like `ignore-cell`, see the [Margo Keyword Proposal repository](https://github.com/margo-notebooks/margo-keyword-proposals).\n", "\n", "This document just describes the syntax of Margo notes not *semantics*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Margo statements\n", "\n", "Every Margo statement is either a directive, which is a name without a value, or an assignment, which is a name plus a value.\n", "\n", "Margo statements are separated with `::`, which in Margo is called an \"endblock.\"\n", "\n", "When Margo is embedded in Python code cells, every line of Margo should begin with `# ::`. Margo can be embedded in any programming language's code cells, but they should begin with an the correct line comment character. In C they would look like this: `// ::`. So here's an example you should be familar with:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# :: ignore-cell ::" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When embedding Margo in Markdown cells, use backtick fence notation plus \"margo\" as the language, like this: " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```Margo\n", "# :: ignore-cell ::\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Margo preamble\n", "\n", "The top of a Code or Markdown cell is called the Margo preamble. That's where Margo notes should go when working with Margo Loader or margo-tool. Other applications may read Margo notes from different positions in a code cell, but these tools only read Margo notes that appear before any code or non-Margo Markdown content." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Directives\n", "\n", "Directives have a name, but no associated value, like `# :: ignore-cell ::`. The `ignore-cell` in this example could be any string of alphanumeric characters, plus the underscore `_` , period `.` , or hyphen `-` characters.\n", "\n", "Here are some more examples." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# :: defines-a-function ::" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# :: poorly-written-code-123 ::" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You get the idea. Just because these are valid Margo syntax doesn't mean they will have any meaning to an application. Margo Loader would not know what to do with these two examples and would just ignore them." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Assignments\n", "\n", "Assignments assign a value to a name, using two syntaxes: Margo Value Format and External Value Format." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### MVF assignments\n", "\n", "MVF assignments are the default format for Margo assignemnts. They accept values that are valid JSON arrays that omit the enclosing square brackets and may contain only scalars (true, false, null, numbers, strings) and not collections (objects and arrays).\n", "\n", "Here are some examples:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# :: input: \"population.csv\" :: " ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# :: output: \"report.pdf\", \"report.html\" ::" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EVF asignments\n", "\n", "EVF assignments take assignments as either JSON, YAML or RAW text. They follow the format:\n", "\n", "```python\n", "# :: {name} [{format}] : {value}\n", "```\n", "\n", "Name is any valid keyword that could be used as the name of a directive.\n", "Format is the format identifier. Currently accepted values are \"json\",\"yaml\",\"raw\".\n", "Value is a string that is properly formatted in the given format.\n", "\n", "Examples are:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# :: hello_world [raw] : '\n", "# :: This is a raw text Margo Value\n", "# :: ------------------------------\n", "# :: \n", "# :: This can be handy for multiline string values.\n", "# :: '" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# :: interface [json]: '{\n", "# :: \"input\": \"population.csv\",\n", "# :: \"output\": \"report.pdf\", \"report.html\"\n", "# :: }' ::" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# :: interface [yaml]: '\n", "# :: input: population.csv\n", "# :: output:\n", "# :: - report.pdf\n", "# :: - report.html\n", "# :: ' ::" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.9" } }, "nbformat": 4, "nbformat_minor": 4 }