One place for hosting & domains

      PythonMarkdown

      How To Use Python-Markdown with Flask and SQLite


      The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Flask is a framework for building web applications using the Python language. With Flask, you can use SQLite as your database engine to store application data.

      Markdown is a markup language commonly used for the process of writing content in an easy-to-read text format. Using Markdown, you can format plain text with features such as headings, links, and images, you can then convert the text into HTML, which includes these formatting features. To learn how to use Markdown, check out the Markdown syntax standard.

      Python-Markdown is a Python library that allows you to convert Markdown text to HTML; it mostly follows the Markdown standard, with a few minor differences to the standard Markdown syntax.

      In this tutorial, you’ll use Flask, SQLite, and Python-Markdown to build a small note-taking web application that supports formatting text using Markdown. The app will allow users to display, create, and format notes with headings, links, lists, images, and other features. You’ll use the Bootstrap toolkit to style your application.

      Prerequisites

      Step 1 — Setting Up Dependencies

      In this step, you will activate your Python environment and install Flask and Python-Markdown using the pip package installer. Then you’ll create the database you will use to store notes and add some sample data to it.

      First, activate your programming environment if you haven’t already:

      Once you have activated your programming environment, install Flask and the Python-Markdown library using the following command:

      • pip install flask markdown

      Then create a database schema file called schema.sql, which will contain SQL commands to create a notes table. Open the file inside your flask_notes directory:

      Type the following SQL commands inside this file:

      flask_notes/schema.sql

      DROP TABLE IF EXISTS notes;
      
      CREATE TABLE notes (
          id INTEGER PRIMARY KEY AUTOINCREMENT,
          created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
          content TEXT NOT NULL
      );
      

      In this SQL file, you first delete any already existing table named notes, which could cause problems. This ensures that your notes table is exactly as described in this SQL. Note that this will delete all of the content you have in the database whenever you use these SQL commands, so ensure you don’t write any important content in the web application until you finish this tutorial and experiment with the final result.

      You use the CREATE TABLE notes statement to create the notes table with the following columns:

      • id: An integer that represents a primary key; the database will assign this a unique value for each entry (a note).
      • created: The note’s creation date; it will be automatically filled in with the time at which the note was added to the database.
      • content: The note’s content.

      Save and close the file.

      To create the database using the schema.sql file, open a file named init_db.py inside the flask_notes directory:

      Then add the following code:

      flask_notes/init_db.py

      
      import sqlite3
      
      connection = sqlite3.connect('database.db')
      
      
      with open('schema.sql') as f:
          connection.executescript(f.read())
      
      cur = connection.cursor()
      
      cur.execute("INSERT INTO notes (content) VALUES (?)", ('# The First Note',))
      cur.execute("INSERT INTO notes (content) VALUES (?)", ('_Another note_',))
      cur.execute("INSERT INTO notes (content) VALUES (?)", ('Visit [this page](https://www.digitalocean.com/community/tutorials) for more tutorials.',))
      
      connection.commit()
      connection.close()
      

      Here, you first import the sqlite3 module. Next, you connect to a file called database.db that will be created once you execute this program. database.db is the database that will hold all your application’s data. You then open the schema.sql file and run it using the executescript() method that executes multiple SQL statements at once. This will create the notes table.

      Using a Cursor object, you execute a few INSERT SQL statements to create three notes. You’re using Markdown syntax here: the first note is an <h1> heading, the second note is in italic, and the third note contains a link. You use the ? placeholder in the execute() method and pass a tuple containing the note’s content to safely insert data into the database.

      Finally, you commit the changes and close the connection.

      Save and close the file.

      Run the program:

      After execution, a new file called database.db will appear in your flask_notes directory.

      You’ve activated your environment, installed Flask and Python-Markdown, and created the SQLite database. Next, you’ll retrieve the Markdown notes from the database, convert them to HTML, and display them on the application’s homepage.

      Step 2 — Displaying the Notes on the Index Page

      In this step, you will create a Flask application that connects to the database and displays the sample data you have in the database. You will convert the Markdown text in the database to HTML and then render it on the index page.

      First, create the app.py application file inside your flask_notes directory:

      Add the following code to it:

      flask_notes/app.py

      import sqlite3
      import markdown
      from flask import Flask, render_template, request, flash, redirect, url_for
      
      def get_db_connection():
          conn = sqlite3.connect('database.db')
          conn.row_factory = sqlite3.Row
          return conn
      

      You first import the sqlite3 module, the markdown package, and Flask helpers.

      The get_db_connection() function opens a connection to the database.db database file and then sets the row_factory attribute to sqlite3.Row. This gives you name-based access to columns, which means that the database connection will return rows that behave like regular Python dictionaries. Lastly, the function returns the conn connection object you’ll be using to access the database.

      Following that, add the next snippet of code:

      flask_notes/app.py

      #. . .
      
      app = Flask(__name__)
      app.config['SECRET_KEY'] = 'this should be a secret random string'
      

      Here, you create the Flask application object and set a secret key to secure sessions.

      Then add the following code:

      flask_notes/app.py

      #. . .
      
      @app.route('/')
      def index():
          conn = get_db_connection()
          db_notes = conn.execute('SELECT id, created, content FROM notes;').fetchall()
          conn.close()
      
          notes = []
          for note in db_notes:
             note = dict(note)
             note['content'] = markdown.markdown(note['content'])
             notes.append(note)
      
          return render_template('index.html', notes=notes)
      

      The index() function is a Flask view function, which is a function decorated using the special @app.route decorator. Flask converts this function’s return value into an HTTP response that an HTTP client, such as a web browser, will display.

      In the index() view function, you open a database connection and you execute a SELECT SQL statement to fetch the ID, the creation date, and the content for all rows of the notes table. You use the fetchall() method to get a list of all the rows and save this data in the db_notes variable. Then, you close the connection.

      To convert the content of the notes from Markdown to HTML, you create a new empty list called notes. You loop through the db_notes list and convert each note from an sqlite3.Row to a regular Python dictionary using the dict() Python function to allow assignment. Next, you use the markdown.markdown() function to convert the value of note['content'] to HTML. For example, calling markdown.markdown('#Hi') would return the string '<h1>Hi</h1>' because in Markdown # represents the <h1> heading. After modifying note['content'], you append the note to the notes list.

      Finally, you render a template file called index.html, passing it the notes list.

      After all the additions, your file will be as follows:

      flask_notes/app.py

      import sqlite3
      import markdown
      from flask import Flask, render_template, request, flash, redirect, url_for
      
      def get_db_connection():
          conn = sqlite3.connect('database.db')
          conn.row_factory = sqlite3.Row
          return conn
      
      
      app = Flask(__name__)
      app.config['SECRET_KEY'] = 'this should be a secret random string'
      
      
      @app.route('/')
      def index():
          conn = get_db_connection()
          db_notes = conn.execute('SELECT id, created, content FROM notes;').fetchall()
          conn.close()
      
          notes = []
          for note in db_notes:
             note = dict(note)
             note['content'] = markdown.markdown(note['content'])
             notes.append(note)
      
          return render_template('index.html', notes=notes)
      

      Save and close the file.

      Next, you’ll create a base template and the index.html template file.

      In your flask_notes directory, create a templates directory and open a file called base.html inside it:

      • mkdir templates
      • nano templates/base.html

      Add the following code inside base.html; note that you’re using Bootstrap here. If you are not familiar with HTML templates in Flask, read Step 3 of How To Make a Web Application Using Flask in Python 3:

      flask_notes/templates/base.html

      <!doctype html>
      <html lang="en">
        <head>
          <!-- Required meta tags -->
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      
          <!-- Bootstrap CSS -->
          <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
      
          <title>{% block title %} {% endblock %}</title>
        </head>
        <body>
          <nav class="navbar navbar-expand-md navbar-light bg-light">
              <a class="navbar-brand" href="https://www.digitalocean.com/community/tutorials/{{ url_for("index')}}">FlaskNotes</a>
              <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                  <span class="navbar-toggler-icon"></span>
              </button>
              <div class="collapse navbar-collapse" id="navbarNav">
                  <ul class="navbar-nav">
                  <li class="nav-item active">
                      <a class="nav-link" href="#">About</a>
                  </li>
                  </ul>
              </div>
          </nav>
          <div class="container">
              {% for message in get_flashed_messages() %}
                  <div class="alert alert-danger">{{ message }}</div>
              {% endfor %}
              {% block content %} {% endblock %}
          </div>
      
          <!-- Optional JavaScript -->
          <!-- jQuery first, then Popper.js, then Bootstrap JS -->
          <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
          <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
        </body>
      </html>
      

      Most of the code in the preceding block is standard HTML and code required for Bootstrap. The <meta> tags provide information for the web browser, the <link> tag links the Bootstrap CSS files, and the <script> tags are links to JavaScript code that allows some additional Bootstrap features.

      The <title>{% block title %} {% endblock %}</title> tag allows the inheriting templates to define a custom title. You use the for message in get_flashed_messages() loop to display the flashed messages, like warnings and alerts. The {% block content %} {% endblock %} placeholder is where inheriting templates place the content so that all templates have the extra code this base template provides to avoid repetition.

      Save and close the file.

      Next, create the index.html file that will extend this base.html file:

      • nano templates/index.html

      Add the following code to it:

      flask_notes/templates/index.html

      
      {% extends 'base.html' %}
      
      {% block content %}
          <h1>{% block title %} Welcome to FlaskNotes {% endblock %}</h1>
          {% for note in notes %}
          <div class="card">
              <div class="card-body">
                  <span class="badge badge-primary">#{{ note['id'] }}</span>
                  <span class="badge badge-default">{{ note['created'] }}</span>
                  <hr>
                  <p>{{ note['content'] |safe }}</p>
              </div>
          </div>
          <hr>
          {% endfor %}
      {% endblock %}
      

      Here you extend base.html, you define a title, and you use a for loop to go through notes displaying each note in a Bootstrap card. You display the note’s ID, the note’s creation date, and the note’s content, which you converted into HTML in the index() view function.

      You use the |safe Jinja filter, which you apply to the content using |; this is similar to calling a function in Python (in a similar way to safe(note['content'])). The |safe filter allows the browser to render HTML code—if it was not applied, it will display the HTML as plain text. This is usually referred to as “escaping HTML,” which is a security feature that prevents malicious HTML from being interpreted in the browser that would result in a dangerous security vulnerability called cross-site scripting (XSS). Since the Python-Markdown library returns safe HTML, you can allow the browser to render it using the |safe filter. Remember not to use this filter until you are certain that the HTML code you allow is safe and trusted.

      For more, read Flask’s documentation on controlling autoescaping.

      Save and close the file.

      Set the environment variables Flask needs and run the application using the following commands:

      • export FLASK_APP=app
      • export FLASK_ENV=development
      • flask run

      The FLASK_APP environment variable specifies the application you want to run (the app.py file). The FLASK_ENV environment variable specifies the mode; development means that the application will run in development mode with the debugger running (remember to avoid using this mode in production). You run the application using the flask run command.

      Open a browser and type in the URL http://127.0.0.1:5000/.

      Flask Notes Index

      Here, you’ll find that each note is formatted and rendered as HTML in the browser instead of plain text.

      You created a Flask application that connects to the database, fetches notes, converts their content from Markdown text to HTML, and then renders them on the index page. Next, you’ll add a route to allow users to add new notes, which they can write using Markdown syntax.

      Step 3 — Adding New Notes

      In this step, you’ll add a new route that will allow users to take new notes. Users can use Markdown syntax to write their notes—your application will save the notes to the database, which it will then display on the index page with the proper formatting. You will also add a button to the navigation bar that takes users to this new page.

      You will use web forms to allow users to submit data in your Flask application and you’ll store user-submitted data in your database.

      First open the app.py file to add a new route:

      Add the following code to the end of the file:

      flask_notes/app.py

      #. . .
      
      @app.route('/create/', methods=('GET', 'POST'))
      def create():
          conn = get_db_connection()
      
          if request.method == 'POST':
              content = request.form['content']
              if not content:
                  flash('Content is required!')
                  return redirect(url_for('index'))
              conn.execute('INSERT INTO notes (content) VALUES (?)', (content,))
              conn.commit()
              conn.close()
              return redirect(url_for('index'))
      
          return render_template('create.html')
      

      Since you will use this route to insert new data to the database via a web form, you allow both GET and POST requests using methods=('GET', 'POST') in the app.route() decorator. In the create() view function, you open a database connection.

      If the user has submitted a form that means the condition request.method == 'POST' is true, so you extract the note’s content that the user has submitted using request.form['content'] and save it to a variable called content. If the content is empty, you flash a 'Content is required!' message and redirect the user to the index page. If the content was not empty, you use an INSERT SQL statement to add the note’s content to the notes table. You commit the changes and close the connection, then you redirect the user to the index page.

      If the request is a GET request, meaning the user has just visited the page, you render a template file called create.html.

      Save and close the file.

      Next, open the create.html template file:

      • nano templates/create.html

      Add the following code to it:

      flask_notes/templates/create.html

      {% extends 'base.html' %}
      
      {% block content %}
          <h1>{% block title %} Add a New Note {% endblock %}</h1>
          <form method="post">
          <div class="form-group">
              <label for="content">Note Content</label>
              <textarea type="text" name="content"
                     placeholder="Note content, you can use Markdown syntax" class="form-control"
                     value="{{ request.form['content'] }}" autofocus></textarea>
          </div>
      
          <div class="form-group">
              <button type="submit" class="btn btn-primary">Submit</button>
          </div>
          </form>
      
      {% endblock %}
      

      Here, you use a form with a text area for the note’s content. You use request.form to access the form data that is stored in case something goes wrong with your form submission (for example, if no content was provided). You add a submit button under the text area for the user to press to send data to the application in a POST request.

      Save and close the file.

      Next open the base.html file to add a New Note button to the navigation bar:

      Edit the file with the highlighted code as follows:

      flask_notes/templates/base.html

      <!doctype html>
      <html lang="en">
        <head>
          <!-- Required meta tags -->
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
      
          <!-- Bootstrap CSS -->
          <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
      
          <title>{% block title %} {% endblock %}</title>
        </head>
        <body>
          <nav class="navbar navbar-expand-md navbar-light bg-light">
              <a class="navbar-brand" href="https://www.digitalocean.com/community/tutorials/{{ url_for("index')}}">FlaskNotes</a>
              <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                  <span class="navbar-toggler-icon"></span>
              </button>
              <div class="collapse navbar-collapse" id="navbarNav">
                  <ul class="navbar-nav">
                  <li class="nav-item active">
                      <a class="nav-link" href="#">About</a>
                  </li>
      
                  <li class="nav-item active">
                      <a class="nav-link" href="https://www.digitalocean.com/community/tutorials/{{ url_for("create') }}">New Note</a>
                 </li>
                  </ul>
              </div>
          </nav>
          <div class="container">
              {% for message in get_flashed_messages() %}
                  <div class="alert alert-danger">{{ message }}</div>
              {% endfor %}
              {% block content %} {% endblock %}
          </div>
      
          <!-- Optional JavaScript -->
          <!-- jQuery first, then Popper.js, then Bootstrap JS -->
          <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
          <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
        </body>
      </html>
      

      You add a new <li> item to the navigation bar with the url_for() function to link to the create() view function. With this, you can access the page for creating a new note from the navigation bar.

      Run the development server if you haven’t already:

      Use your browser to go to http://127.0.0.1:5000/create and add the following markdown note:

      ### Flask
      Flask is a **web** framework for _Python_.
      
      Here is the Flask logo:
      
      ![Flask Logo](https://flask.palletsprojects.com/en/1.1.x/_images/flask-logo.png)
      

      This markdown contains an h3 heading, the word web in bold, the word Python in italic, and an image.

      Submit the note, you will find that your application formats it into HTML.

      Markdown Formatted Note

      You now have a new route that allows users to add new notes to the database. Users can take notes with Markdown formatting and the application will display the notes in HTML on the index page.

      You can access the full code for the application from this repository.

      Conclusion

      You created a Flask application for taking notes in Markdown format to allow users to use text formatting such as headings, bold and italic text, adding images and links, among other things. You connected your application to a SQLite database to store and retrieve your data. You’ve incorporated Markdown text into HTML conversion so that notes will render on the page. To learn more about using Markdown in Python, read How To Use Python-Markdown to Convert Markdown Text to HTML.

      For further information about Flask, check out the following tutorials:



      Source link

      How To Use Python-Markdown to Convert Markdown Text to HTML


      The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Markdown is a markup language commonly used to simplify the process of writing content in an easy-to-read text format, which a software tool or programming library can convert into HTML to display in a browser or another writing program. Because it uses plain-text syntax, Markdown is compatible with any text editor and can convert headings, lists, links, and other components. Bloggers, tutorial authors, and documentation writers use Markdown widely and websites, such as Github, StackOverflow, and The Python Package Index (PyPI), support it.

      You can learn how to use Markdown from the Markdown syntax standard. Alternatively, you can also try a different Markdown implementation in a web editor, like the DigitalOcean Markdown Preview or the StackEdit editor.

      Python-Markdown is a Python library that allows you to convert Markdown text to HTML in various ways. You can extend its functionality using its different extensions that provide additional features. Note however, that the Python-Markdown has a few minor differences with the standard Markdown syntax.

      In this tutorial, you will install the Python-Markdown library, use it to convert Markdown strings to HTML, convert Markdown files to HTML files, and use the Python-Markdown command line interface to convert Markdown to HTML.

      Prerequisites

      Before you start following this guide, you will need:

      Step 1 — Installing Python-Markdown

      In this step, you will install Python-Markdown and explore one of its functions to convert Markdown strings to HTML in the Python REPL.

      If you haven’t already activated your programming environment, make sure you’re in your project directory (pymark) and use the following command to activate the environment:

      Once you have activated your programming environment, your prompt will now have an env prefix like the following:

      Now you’ll install Python packages and isolate your project code away from the main Python system installation.

      Use pip to install the Python-Markdown library (markdown) by running the following command:

      Once the installation finishes successfully, you can experiment with it in the Python REPL, which you can open by typing the following command:

      You will notice a new prompt with the prefix >>>; you can use this to type in Python code and receive immediate output.

      First you will import the markdown package and use it to convert a piece of Markdown text from Markdown syntax to HTML:

      • import markdown
      • markdown.markdown('#Hi')

      In this code, you import the markdown package you installed earlier. You use the markdown.markdown() function to convert the Markdown text #Hi (with # representing an H1-level header) to its HTML equivalent. If you type the code into the Python REPL, you will receive the following output:

      Output

      '<h1>Hi</h1>'

      The HTML output is the equivalent of the #Hi Markdown text.

      You can use triple single quotes (''') to type multi-line Markdown text into the Python REPL like so:

      • import markdown
      • output = markdown.markdown('''
      • # Step 1
      • ## Step 2
      • * item 1
      • * item 2
      • Visit [the tutorials page](https://www.digitalocean.com/community/tutorials) for more tutorials!
      • ''')
      • print(output)

      In this example, you pass an H1 header, an H2 header, two list items, and a paragraph containing a link. You then save the output in a variable called output and print it with the print() Python function.

      You will receive the following output:

      Output

      <h1>Step 1</h1> <h2>Step 2</h2> <ul> <li>item 1</li> <li>item 2</li> </ul> <p>Visit <a href="https://www.digitalocean.com/community/tutorials">the tutorials page</a> for more tutorials!</p>

      You’ll notice that the output results in the HTML version of the provided Markdown text.

      Now that you’ve used the markdown package to convert Markdown text to HTML, you will make a small program to read and convert Markdown files to HTML files.

      Step 2 — Creating a Program to Convert Markdown Files to HTML

      In this step, you will create a Python program that reads a Markdown file, converts its contents to HTML using the markdown.markdown() function, and saves the HTML code in a new file.

      First, open a new file called Picnic.md to hold the Markdown text:

      Type the following Markdown text into it:

      pymark/Picnic.md

      # Things to bring
      
      * Food.
      * Water.
      * Knife.
      * Plates.
      

      In this file you have an H1 header and four list items.

      Once you’re done, save and close the file.

      Next, open a new file called convert.py to hold the code for converting the Picnic.md Markdown file to an HTML file:

      Type the following Python code into it:

      pymark/convert.py

      import markdown
      
      with open('Picnic.md', 'r') as f:
          text = f.read()
          html = markdown.markdown(text)
      
      with open('Picnic.html', 'w') as f:
          f.write(html)
      

      Here, you first import the markdown package. You use the open() function to open the Picnic.md file; passing the value 'r' to the mode parameter to signify that Python should open it for reading.

      You save the file object in a variable called f, which you can use to reference the file. Then you read the file and save its contents inside the text variable. After, you convert the text using markdown.markdown(), saving the result in a variable called html.

      With the same pattern, you open a new file called Picnic.html in writing mode ('w')—note that this file does not yet exist—and write the contents of the html variable to the file. This creates and saves the new file on your system. Using the with statement when opening a file guarantees that Python will close it once processing has finished.

      Save and close the file.

      Run the convert.py program:

      This creates a new file called Picnic.html in your project directory with the following contents:

      pymark/Picnic.html

      <h1>Things to bring</h1>
      <ul>
      <li>Food.</li>
      <li>Water.</li>
      <li>Knife.</li>
      <li>Plates.</li>
      </ul>
      

      Now that you know how to open and convert Markdown files using the markdown.markdown() function, you can generate Markdown text in Python and convert Markdown files without the need to read them first.

      Step 3 — Generating Markdown from Data and Converting it to HTML

      In this step, you will create a program that generates Markdown text from a Python dictionary, saves it to a Markdown file, and converts the Markdown text to an HTML file using the markdown.markdownFromFile() function.

      Your program will generate a Markdown file called cities.md with a list of countries and their top three largest cities. After, the program will convert the generated Markdown text into HTML, then it will save the HTML in a file called cities.html.

      First open a new Python file called citygen.py:

      Then add the following Python code:

      pymark/citygen.py

      import markdown
      
      
      country_cities = {'Japan': ['Tokyo', 'Osaka', 'Nagoya'],
                        'France': ['Paris', 'Marseille', 'Lyon'],
                        'Germany': ['Berlin', 'Hamburg', 'Munich'],
                        }
      

      In this code you first import the Python-Markdown library with import markdown. Then you define a country_cities dictionary containing a few countries as the keys and a list of the largest three cities for each country as the value. This dictionary is an example data structure; you can replace it with fetched data from a web API, a database, or any other data source.

      Next add the following code after your dictionary:

      pymark/citygen.py

      . . .
      with open('cities.md', 'bw+') as f:
          for country, cities in country_cities.items():
              f.write('# {}n'.format(country).encode('utf-8'))
              for city in cities:
                  f.write('* {}n'.format(city).encode('utf-8'))
          f.seek(0)
          markdown.markdownFromFile(input=f, output="cities.html")
      

      After constructing the dictionary that holds the data, you use the with open(...) as ... syntax to open a file called cities.md, which doesn’t exist yet. You open it in binary mode ('b') for writing and reading ('w+'). You use binary mode, because if you pass a string to markdown.markdownFromFile(), it will be interpreted as a path to a readable file on the file system (that is, '/home/file.md'). Also binary mode allows you to avoid issues related to converting characters to a platform-specific representation; this guarantees that the Python program will behave the same way on any platform.

      You then go through the dictionary’s items extracting each key that contains the country’s name and saving it in the country variable. Alongside this, you extract the value that represents the list of the country’s largest cities and save it in the cities variable.

      Inside the first loop, you write the country’s name to the new cities.md file in a # Markdown header (the <h1> HTML tag). n is a special character for inserting a new line. You use .encode() because you have opened the file in binary mode. The second for loop iterates through each city and writes its name to the Markdown file as a * list item (the <li> HTML tag).

      After the first loop finishes, you have moved to the end of the file, which means markdown.markdownFromFile() won’t be able to read its contents; therefore, you use f.seek(0) to go back to the top of the file. Before passing the f object to markdown.markdownFromFile() as input, to convert it to HTML and save it to a new file called cities.html.

      Once you’re done, save and close the file.

      Run the citygen.py program:

      This command will generate two files:

      • cities.md: A Markdown file with the following contents:

      pymark/cities.md

      # Japan
      * Tokyo
      * Osaka
      * Nagoya
      # France
      * Paris
      * Marseille
      * Lyon
      # Germany
      * Berlin
      * Hamburg
      * Munich
      
      • cities.html: An HTML file that contains the result of converting the contents of cities.md:

      pymark/cities.html

      <h1>Japan</h1>
      <ul>
      <li>Tokyo</li>
      <li>Osaka</li>
      <li>Nagoya</li>
      </ul>
      <h1>France</h1>
      <ul>
      <li>Paris</li>
      <li>Marseille</li>
      <li>Lyon</li>
      </ul>
      <h1>Germany</h1>
      <ul>
      <li>Berlin</li>
      <li>Hamburg</li>
      <li>Munich</li>
      </ul>
      

      You can also use the function markdown.markdownFromFile() to convert an existing Markdown file. For example, you can convert the Picnic.md file to a file called Picnic-out.html using the following code:

      example.py

      import markdown
      
      markdown.markdownFromFile(input="Picnic.md", output="Picnic-out.html")
      

      You can use the markdown.markdownFromFile() function to directly convert a file, if the file does not need any modification. If you do need to modify the Markdown file, you can read it, then convert it using the method demonstrated in Step 2.

      You’ve converted Markdown text to HTML in Python code, but Python-Markdown also provides a helpful command line interface (CLI) to quickly convert Markdown files to HTML—you’ll review this tool in the next step.

      Step 4 — Using Python-Markdown’s Command Line Interface

      In this step you will use Python-Markdown’s CLI to convert a Markdown file to HTML and print the output, or save it to an HTML file.

      You can run the Python-Markdown command line script using the -m flag supported by Python, which runs a library module as a script. For example, to convert a Markdown file, you can pass it to the markdown command as follows, replacing filename.md with the name of the file you want to convert:

      • python -m markdown filename.md

      Executing this command will print the HTML code for the Markdown text that’s present in the filename.md file.

      For example, to convert the Picnic.md file, run the following command:

      • python -m markdown Picnic.md

      This will print the following output:

      Output

      <h1>Things to bring</h1> <ul> <li>Food.</li> <li>Water.</li> <li>Knife.</li> <li>Plates.</li> </ul>

      To save the output to a file called output.html, use the following command:

      • python -m markdown Picnic.md -f output.html

      With this, you’ve now used the markdown command line interface to convert a Markdown file to HTML.

      Conclusion

      In this tutorial, you have used Python to convert Markdown text to HTML. You can now write your own Python programs that take advantage of the Markdown syntax in different contexts, such as web applications using a web framework like Flask or Django. For more on how to use Markdown, check out the Markdown website. For more information on using Markdown with Python, check out the Python-Markdown documentation.

      Here are a few extensions officially supported by Python-Markdown:

      • Extra: An extension that adds extra features to the standard Markdown syntax, such as defining abbreviations, adding attributes to various HTML elements, footnotes, tables, and other features.
      • CodeHilite: An extension that adds syntax highlighting to code blocks.
      • Table of Contents: An extension that generates a table of contents from a Markdown document and adds it into the resulting HTML document.



      Source link