Skip to content
Snippets Groups Projects
Commit 0049834a authored by David Paul's avatar David Paul
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Showing with 567 additions and 0 deletions
LICENSE 0 → 100644
The MIT License (MIT)
Copyright © 2022 David Paul
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# PAIL: Personalising Assessment for Individualised Learning
PAIL is a tool designed to automate the generation and personalising of assessments to assist with individualised learning.
## Background
During the covid-19 pandemic, delivery of almost all courses moved online; now, universities commonly offer flexible/hybrid models of teaching and learning ([Crick et al, 2021](https://doi.org/10.1109/FIE44824.2020.9274033)). With the rise of online and/or hybrid teaching ([Turnbull et al, 2021](https://doi.org/10.1007/s10639-021-10633-w)), there has been renewed interest in assessment – its authenticity, the value of examinations, and the corresponding dependence on online assessments and electronic invigilators ([Raptana et al, 2021](https://doi.org/10.1007/s42438-021-00249-1)). The latter has been reported to be vulnerable to problems related to online assessment platforms and associated electronic invigilation tools, and there have been numerous reports of increasing incidence of academic integrity violations, particularly plagiarism and collusion ([Simon et al, 2022](http://leemans.ch/publications/papers/ace2022simon.pdf)).
Using assessment-as-learning ([Yan et al, 2021](https://books.google.com.au/books?id=xl5CEAAAQBAJ&lpg=PP1&ots=7dk5VI-Mp8&lr&pg=PP1#v=onepage&q&f=false)) in the context of ICT, and especially cybersecurity ([Leszczyna, 2021](https://doi.org/10.1016/j.cose.2021.102376)), an assignment looks the same for all students but each assessment presents different input data to students. Students are encouraged to work together to solve their assignment questions and to learn from one another, but they do the assignments on their own since the input data is tailored for each student. While this approach brings assessment-as-learning to the fore, it also has been found to be effective in reducing the incidence of plagiarism and collusion in assessments ([Bretag et al, 2019](https://doi.org/10.1080/02602938.2018.1527892)). This approach has the dual benefits of enhancing peer learning and peer feedback through assessment-as-learning while also reducing academic integrity issues associated with online platforms.
Personalising of assessment ([Jones and McLean, 2018](https://link.springer.com/content/pdf/10.1007/978-981-10-7930-6.pdf)) is the act of formalising an assessment to bring different communities together to enrich and broaden the learner’s experience, through empowering learners to take more control over what and how they learn. This is different from ‘personalised assessment’, which is instruction that is paced to learning needs, tailored to learning preferences, and tailored to the specific interests of different learners. In an environment that is fully personalised, the learning objectives and content, as well as the method and pace, may all vary. Personalised assessment relies heavily on the notion of individualisation and differentiation, which often risks leaving the learner to work alone on an individual task, something that may isolate students. This is in contrast to the notion of personalising of assessment, which is far more focused on the social aspects of learning through collaboration with peers and the wider community for an assessment task.
## Description
PAIL provides a framework to allow the automatic generation of personalising assessments by allowing the instructor to provide a program that will generate individual files for that learner and then present them with a personalising rendered [Markdown](https://en.wikipedia.org/wiki/Markdown) file(s).
The system uses [Learning Tools Interoperability (LTI)](https://en.wikipedia.org/wiki/Learning_Tools_Interoperability) through a [Learning Management System (LMS)](https://en.wikipedia.org/wiki/Learning_management_system) to determine the directory where the personalising files should be stored for each individual learner.
## Setup
PAIL is a PHP wrapper that uses a script to automatically create personalising assessments for users, and then display an associated Markdown file.
To set up, you should upload the PAIL files to a PHP server and modify ```settings.php``` to give the following details:
| Setting | Description |
| ------- | ----------- |
| ```$pail_oauth_consumer_secret``` | The LTI consumer secret that should be used by the LMS
| ```$pail_title``` | The title for the page
| ```$pail_description``` | A short description of the assessment
| ```$pail_generate_command``` | The command used to generate the personalised assessment for the user. It will be passed the directory in which to store any generated files as its last command line argument. There are no checks that this program does only store files in the specified directory, so you should ensure you trust that this command will do the right thing.
| ```$pail_contact``` | The contact email people should be directed to if there are any issues
| ```$pail_reset``` | If false (the default), files are only generated the first time the learner visits the LTI tool (and simply displayed on subsequent visits). If true, the files are generated each time the learner visits.
You can then set up an LTI tool in your LMS that points to the base URL where you have PAIL set up.
PAIL will then automatically generate and render the Markdown file specified by the ```display``` request parameter (or ```display.md``` if no such parameter exists) for each individual learner.
For example, if set up at https://example.edu/pail/, https://example.edu/pail/ would display ```display.md``` and https://example.edu/pail/?display=example.md would display ```example.md```.
### Generate command
The generate command is passed the directory where it should generate files as its final command line parameter.
Note there are very few checks that this program behaves "nicely" (e.g., only generates files in the correct directory), so you should trust that this program works correctly.
The file rendered by PAIL is ```generated/CONTEXT/USER/DISPLAY```, where CONTEXT is the ```context_id``` obtained from the LMS via LTI, USER is the ```user_id``` obtained from the LMS by LTI, and DISPLAY is the value of the ```display``` request parameter (or ```display.md``` if no such parameter is set).
## Authors and acknowledgment
This project is initally supported by the [Australian Council of Deans of Information & Communications Technology (ACDICT)](https://acdict.edu.au/) under their [ALTA small grants scheme 2022](https://acdict.edu.au/alta-small-grants-scheme-2022/) program for the project "Technical and Educational Guidelines for Personalising Assessments through Assessment-as-Learning in Cybersecurity".
Project participants are:
* Dr Amin Sakzad (Monash University, Australia)
* Dr David Paul (University of New England, Australia)
* Prof Judithe Sheard (Monash University, Australia)
* Prof Ljiljana Brankovic (University of New England, Australia)
* Dr Matthew P. Skerritt (Royal Melbourne Institute of Technology, Australia)
* Dr Nan Li (University of Newcastle, Australia)
* A/Prof William Billingsley (University of New England, Australia)
* Dr Simon
## License
This project is released under the [MIT License](https://mit-license.org/) (see LICENSE)
apple-touch-icon.png

9.66 KiB

<h1>Error</h1>
<p>Unable to find your personalised file(s). Please contact <a href="mailto:<?php echo $pail_contact; ?>"><?php echo $pail_contact; ?></a> and let them know.</p>
<h1>Error</h1>
<p>Please connect through a <a href="https://en.wikipedia.org/wiki/Learning_management_system">Learning Management System</a>
using <a href="https://en.wikipedia.org/wiki/Learning_Tools_Interoperability">Learning Tools Interoperability</a>.</p>
<p>If you are unsure what to do, please contact <a href="mailto:<?php echo $pail_contact; ?>"><?php echo $pail_contact; ?></a>.</p>
import sys
import os
import random
from string import Template
# Creates display.md that is world-readable, and answers.md that is readable only by the owner
# in the directory specified in the last command line argument passed to the program
def create_template_from_string(string_in):
""" Creates a simple string Template from the given string """
return Template(string_in)
def create_template_from_file(file):
""" Reads in the contents of the given file and uses it to create a simple string Template """
with open(file, "r") as file_in:
string_in = file_in.read()
return create_template_from_string(string_in)
def output_file_from_template(file_out, template, substitutions = {}, permissions = 0o444):
"""
Uses the given substitutions with the given template to generate content to be written to file_out,
created with the given permissions.
Params:
file_out The file to write content out to
template The template used to write to file_out
substitutions The substitutions to use with the template (defaults to the empty dictionary)
permissions The permissions to give to the specified file (defaults to world-wide readonly)
"""
contents = template.substitute(substitutions)
with open(os.open(file_out, os.O_CREAT | os.O_WRONLY, permissions), "w") as out:
out.write(contents)
if __name__ == "__main__":
directory = sys.argv[-1]
display = directory + "display.md"
answers = directory + "answers.md"
display_template = create_template_from_string("# Simple *Markdown* Test\nThis is the default display file, which contains a random value ${x}")
answer_template = create_template_from_string("# Simple *Markdown* test\nThis is a hiddent answer file.\nMake is readable by the PHP server to allow PAIL to display it.\n It contains the same random value as the display: ${x}")
substitutions = {"x": random.randint(1, 10)}
output_file_from_template(display, display_template, substitutions)
# Make answers.md only readable by the owner
output_file_from_template(answers, answer_template, substitutions, 0o400)
favicon.ico

15 KiB

#!/usr/bin/env bash
set -Eeuo pipefail
trap cleanup SIGINT SIGTERM ERR EXIT
usage() {
cat <<EOF
Usage: $(basename "${BASH_SOURCE[0]}") [-h] [-v] -c context_value -u user_value command_args
Script to personalise assessments for individualised learning
Available options:
-h, --help Print this help and exit
-v, --verbose Print script debug info
-c, --context The context id to generate files for
-u, --user The user id to generate files for
command_args The command to execute to generate files -
it will have the directory where files should be generated passed as its final parameter
EOF
exit
}
main() {
# determine directory (creating if necessary) to pass to the command
local directory="generated/${context}/${user}/"
info "Generating files in ${directory}"
mkdir -p ${directory}
# add directory to command line arguments and execute command passed as arguments
args+=("${directory}")
"${args[@]}"
success "Successfully generated files in ${directory}"
}
parse_params() {
# default values of variables set from params
context=''
user=''
while :; do
case "${1-}" in
-h | --help) usage ;;
-v | --verbose) set -x ;;
--no-color) NO_COLOR=1 && setup_colors ;;
-c | --context)
context="${2-}"
shift
;;
-u | --user)
user="${2-}"
shift
;;
-?*) die "Unknown option: $1" ;;
*) break ;;
esac
shift
done
args=("$@")
# check required params and arguments
[[ -z "${context-}" ]] && die "Missing required parameter: context"
[[ -z "${user-}" ]] && die "Missing required parameter: user"
[[ "${context-}" =~ ^[[:alnum:]]+$ ]] || die "context must be alphanumeric only"
[[ "${user-}" =~ ^[[:alnum:]]]+$ ]] || die "user must be alphanumeric only"
[[ ${#args[@]} -eq 0 ]] && die "No command specified"
return 0
}
cleanup() {
trap - SIGINT SIGTERM ERR EXIT
warn "Performing cleanup"
# script cleanup here
}
setup_colors() {
if [[ -t 2 ]] && [[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]]; then
NOFORMAT='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' ORANGE='\033[0;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' YELLOW='\033[1;33m'
else
NOFORMAT='' RED='' GREEN='' ORANGE='' BLUE='' PURPLE='' CYAN='' YELLOW=''
fi
}
msg() {
echo >&2 -e "${1-}"
}
success() {
msg "${GREEN}Success:${NOFORMAT} ${1}"
}
info() {
msg "${BLUE}Info:${NOFORMAT} ${1}"
}
warn() {
msg "${ORANGE}Warning:${NOFORMAT} ${1}"
}
error() {
msg "${RED}Error:${NOFORMAT} ${1}"
}
die() {
local msg=$1
local code=${2-1} # default exit status 1
error "$msg"
exit "$code"
}
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd -P)
setup_colors
parse_params "$@"
main "$@"
<!doctype html>
<?php
session_start();
require_once("lib/parsedown/Parsedown.php");
require_once("lib/lti/lti_util.php");
require_once("settings.php");
?>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo $pail_title; ?></title>
<meta name="description" content="<?php echo $pail_description; ?>">
<meta name="author" content="PAIL">
<link rel="icon" href="favicon.ico">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
<link rel="stylesheet" href="lib/github-markdown-css/github-markdown.css">
</head>
<body class="markdown-body">
<?php
// Check if this is a valid LTI request
$valid_lti_request = is_lti_request();
if ($valid_lti_request) {
$oauth_consumer_key = "";
$oauth_consumer_secret = "";
if (isset($_POST["oauth_consumer_key"])) {
$oauth_consumer_key = $_POST["oauth_consumer_key"];
$oauth_consumer_secret = $pail_oauth_consumer_secret;
$_SESSION["oauth_consumer_key"] = $oauth_consumer_key;
$_SESSION["oauth_consumer_secret"] = $oauth_consumer_secret;
}
$context = new BLTI($oauth_consumer_secret, true, false);
// Ensure context is valid and context_id and user_id are alphanumeric only
$valid_lti_request = $context->valid
&& ctype_alnum($context->info["context_id"]) && ctype_alnum($context->info["user_id"]);
}
if (!$valid_lti_request) {
// If not a valid LTI request, display an error
require("error_templates/not_lti.php");
} else {
// Determine name of file to display
$pail_dirname = getcwd() . DIRECTORY_SEPARATOR .
"generated" . DIRECTORY_SEPARATOR .
$context->info["context_id"] . DIRECTORY_SEPARATOR .
$context->info["user_id"] . DIRECTORY_SEPARATOR;
// Default to display.md unless another file is requested
$pail_filename = isset($_REQUEST["display"]) ? $_REQUEST["display"] : "display.md";
$pail_filename = $pail_dirname . $pail_filename;
// Generate file if necessary
if ($pail_reset || !file_exists($pail_filename)) {
$output = null;
$retval = null;
$pail_command = "./generate.sh " .
"-c \"" . $context->info["context_id"] . "\"" . " ".
"-u \"" . $context->info["user_id"] . "\" " .
$pail_generate_command;
exec($pail_command, $output, $retval);
}
// Attempt to read the file
$file_contents = false;
if (file_exists($pail_filename)) {
$file_contents = file_get_contents($pail_filename);
}
if ($file_contents === false) {
// Display error if unable to read file
require("error_templates/file_unavailable.php");
// Display file
} else {
echo Parsedown::instance()->text($file_contents) . "\n";
}
}
?>
<footer><small>Generated by PAIL</small></footer>
</body>
</html>
This diff is collapsed.
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# github-markdown-css
> The minimal amount of CSS to replicate the GitHub Markdown style
**The CSS is generated. Contributions should go to [this repo](https://github.com/sindresorhus/generate-github-markdown-css).**
[<img src="https://cloud.githubusercontent.com/assets/170270/5219062/f22a978c-7685-11e4-8316-af25b6c89bc0.png" width="300">](http://sindresorhus.com/github-markdown-css)
## [Demo](https://sindresorhus.com/github-markdown-css)
## Install
Download [manually](https://raw.githubusercontent.com/sindresorhus/github-markdown-css/gh-pages/github-markdown.css), from [CDNJS](https://cdnjs.com/libraries/github-markdown-css), or with npm:
```
$ npm install github-markdown-css
```
## Usage
Import the `github-markdown.css` file and add a `markdown-body` class to the container of your rendered Markdown and set a width for it. GitHub uses `980px` width and `45px` padding, and `15px` padding for mobile.
```html
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="github-markdown.css">
<style>
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
}
@media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}
</style>
<article class="markdown-body">
<h1>Unicorns</h1>
<p>All the things</p>
</article>
```
You can use [GitHub's `/markdown` API](https://docs.github.com/en/free-pro-team@latest/rest/reference/markdown) to turn Markdown into the HTML that GitHub generates, which works well with the CSS in this repo. Other Markdown parsers will mostly work with these styles too. To mimic how GitHub highlights code, you can use [`starry-night`](https://github.com/wooorm/starry-night) with your Markdown parser of choice.
There are 3 themes provided in this package:
- **github-markdown.css**: (default) Automatically switches between light and dark through [`@media (prefers-color-scheme)`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
- **github-markdown-light.css**: Light-only.
- **github-markdown-dark.css**: Dark-only.
You may know that now GitHub supports more than 2 themes including `dark_dimmed`, `dark_high_contrast` and `colorblind` variants. If you want to try these themes, you can generate them on your own! See next section.
## How
See [`generate-github-markdown-css`](https://github.com/sindresorhus/generate-github-markdown-css) for how it's generated and ability to generate your own.
## Dev
Run `npm run make` to update the CSS.
The MIT License
Copyright (c) 2007 Andy Smith
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This diff is collapsed.
This diff is collapsed.
The MIT License (MIT)
Copyright (c) 2013-2018 Emanuil Rusev, erusev.com
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This diff is collapsed.
<!-- ![Parsedown](https://i.imgur.com/yE8afYV.png) -->
<p align="center"><img alt="Parsedown" src="https://i.imgur.com/fKVY6Kz.png" width="240" /></p>
<h1>Parsedown</h1>
[![Build Status](https://travis-ci.org/erusev/parsedown.svg)](https://travis-ci.org/erusev/parsedown)
[![Total Downloads](https://poser.pugx.org/erusev/parsedown/d/total.svg)](https://packagist.org/packages/erusev/parsedown)
[![Version](https://poser.pugx.org/erusev/parsedown/v/stable.svg)](https://packagist.org/packages/erusev/parsedown)
[![License](https://poser.pugx.org/erusev/parsedown/license.svg)](https://packagist.org/packages/erusev/parsedown)
Better Markdown Parser in PHP - <a href="http://parsedown.org/demo">Demo</a>.
## Features
* One File
* No Dependencies
* [Super Fast](http://parsedown.org/speed)
* Extensible
* [GitHub flavored](https://github.github.com/gfm)
* [Tested](http://parsedown.org/tests/) in 5.3 to 7.3
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)
## Installation
Install the [composer package]:
composer require erusev/parsedown
Or download the [latest release] and include `Parsedown.php`
[composer package]: https://packagist.org/packages/erusev/parsedown "The Parsedown package on packagist.org"
[latest release]: https://github.com/erusev/parsedown/releases/latest "The latest release of Parsedown"
## Example
```php
$Parsedown = new Parsedown();
echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
```
You can also parse inline markdown only:
```php
echo $Parsedown->line('Hello _Parsedown_!'); # prints: Hello <em>Parsedown</em>!
```
More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).
## Security
Parsedown is capable of escaping user-input within the HTML that it generates. Additionally Parsedown will apply sanitisation to additional scripting vectors (such as scripting link destinations) that are introduced by the markdown syntax itself.
To tell Parsedown that it is processing untrusted user-input, use the following:
```php
$Parsedown->setSafeMode(true);
```
If instead, you wish to allow HTML within untrusted user-input, but still want output to be free from XSS it is recommended that you make use of a HTML sanitiser that allows HTML tags to be whitelisted, like [HTML Purifier](http://htmlpurifier.org/).
In both cases you should strongly consider employing defence-in-depth measures, like [deploying a Content-Security-Policy](https://scotthelme.co.uk/content-security-policy-an-introduction/) (a browser security feature) so that your page is likely to be safe even if an attacker finds a vulnerability in one of the first lines of defence above.
#### Security of Parsedown Extensions
Safe mode does not necessarily yield safe results when using extensions to Parsedown. Extensions should be evaluated on their own to determine their specific safety against XSS.
## Escaping HTML
> **WARNING:** This method isn't safe from XSS!
If you wish to escape HTML **in trusted input**, you can use the following:
```php
$Parsedown->setMarkupEscaped(true);
```
Beware that this still allows users to insert unsafe scripting vectors, such as links like `[xss](javascript:alert%281%29)`.
## Questions
**How does Parsedown work?**
It tries to read Markdown like a human. First, it looks at the lines. It’s interested in how the lines start. This helps it recognise blocks. It knows, for example, that if a line starts with a `-` then perhaps it belongs to a list. Once it recognises the blocks, it continues to the content. As it reads, it watches out for special characters. This helps it recognise inline elements (or inlines).
We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages.
**Is it compliant with CommonMark?**
It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve.
**Who uses it?**
[Laravel Framework](https://laravel.com/), [Bolt CMS](http://bolt.cm/), [Grav CMS](http://getgrav.org/), [Herbie CMS](http://www.getherbie.org/), [Kirby CMS](http://getkirby.com/), [October CMS](http://octobercms.com/), [Pico CMS](http://picocms.org), [Statamic CMS](http://www.statamic.com/), [phpDocumentor](http://www.phpdoc.org/), [RaspberryPi.org](http://www.raspberrypi.org/), [Symfony Demo](https://github.com/symfony/demo) and [more](https://packagist.org/packages/erusev/parsedown/dependents).
**How can I help?**
Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
**What else should I know?**
I also make [Nota](https://nota.md/) — a writing app designed for Markdown files :)
<?php
// The consumer secret set in your LMS for the LTI External tool.
$pail_oauth_consumer_secret = "12345";
// The title of the page generated by PAIL.
$pail_title = "Personalising Assessment for Individualised Learning";
// A short description of the page generated by PAIL.
$pail_description = "Personalising assessment for individualised learning";
// The command to execute to generate files.
// It will be passed a final parameter that is the directory in which all files should be generated.
$pail_generate_command = "python3 example.py";
// The email address users will be directed to if there are any issues.
$pail_contact = "pail@example.edu";
// If true, files are regenerated each time a user visits the site.
// If false, files are only generated the first time (and then redisplayed on subsequent visits).
$pail_reset = false;
?>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment