Code totaly rewritted + added pad(url:) support
|
|
@ -1 +1 @@
|
|||
FallbackResource /app.php
|
||||
FallbackResource /index.php
|
||||
|
|
|
|||
12
app.php
|
|
@ -1,12 +0,0 @@
|
|||
<?php include('snippets/functions.php') ?>
|
||||
<?php include('snippets/init.php') ?>
|
||||
<?php include('snippets/controller.php') ?>
|
||||
<?php include('snippets/header.php') ?>
|
||||
<div id="container">
|
||||
<?php include('snippets/introduction.php') ?>
|
||||
<?php include('snippets/nav.php') ?>
|
||||
<article>
|
||||
<iframe id="framepad" name="myframe" width=600 height=400 src="<?= $currentiframe ?>"></iframe>
|
||||
</article>
|
||||
</div>
|
||||
<?php include('snippets/footer.php') ?>
|
||||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 864f014cf1f048a25911c3db361c5796e9f9648f
|
||||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 6d6d88512a8146939a9161bb03e95e3e97840439
|
||||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit c999a4b61bfc15d3eed74a40ce814afe6faa21ea
|
||||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 0db5cce7354e4b76f155d092ab5eb3981c21258c
|
||||
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 576c42ecbc9630b52a95da3279f07278572c6b15
|
||||
24
config.php
|
|
@ -1,7 +1,19 @@
|
|||
<?php
|
||||
$instance_url = "http://libreto.net";
|
||||
$instance_name = "Libreto";
|
||||
$pads_host = "https://annuel2.framapad.org";
|
||||
$pads_params = "?showControls=true&showChat=false&showLineNumbers=false&useMonospaceFont=false";
|
||||
$use_subdomain = 0; // if set to TRUE, libreto adress will look like mysite.libreto.net — if FALSE, they will look like libreto.net/mysite
|
||||
$fallback_language = "en"; // Language fallback if local translation not set
|
||||
$providers = array(
|
||||
'framapad' => array(
|
||||
'name' => "Framapad",
|
||||
'url' => "https://annuel2.framapad.org",
|
||||
'default_text' => "–––––",
|
||||
),
|
||||
'board' => array(
|
||||
'name' => "Board",
|
||||
'url' => "https://board.net",
|
||||
'default_text' => "--",
|
||||
)
|
||||
);
|
||||
|
||||
$options = array(
|
||||
'name' => "Libreto",
|
||||
'default_provider' => "framapad",
|
||||
'providers' => $providers,
|
||||
);
|
||||
|
|
|
|||
54
index.php
|
|
@ -1,42 +1,26 @@
|
|||
<?php
|
||||
include('snippets/functions.php');
|
||||
$user_language = get_user_language();
|
||||
$translation = load_translation_file();
|
||||
define('DS', DIRECTORY_SEPARATOR);
|
||||
define('ROOT', __DIR__);
|
||||
|
||||
if(isset($_POST['new_name'])):
|
||||
if($new_name = $_POST['new_name']) :
|
||||
header('Location: ' . 'http://' . $_SERVER["SERVER_NAME"] . '/' . urlencode($new_name) );
|
||||
endif;
|
||||
endif;
|
||||
?>
|
||||
<!doctype html>
|
||||
<html>
|
||||
// load all dependencies
|
||||
require __DIR__ . DS . 'libreto' . DS . 'vendor' . DS . 'load.php';
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
// load all helpers functions
|
||||
require __DIR__ . DS . 'libreto' . DS . 'helpers.php';
|
||||
|
||||
<title>Libreto</title>
|
||||
// load all core classes
|
||||
function loadClass($classe) {
|
||||
require __DIR__ . DS . 'libreto' . DS . $classe . '.php';
|
||||
}
|
||||
spl_autoload_register('loadClass');
|
||||
|
||||
<link rel="stylesheet" href="/assets/style-index.css">
|
||||
</head>
|
||||
// load options
|
||||
require __DIR__ . DS . 'config.php';
|
||||
|
||||
<body class="current-lang-<?= get_user_language() ?>">
|
||||
<article>
|
||||
<?php
|
||||
$markdown = file_get_contents("assets/texts/homepage.md");
|
||||
$Parsedown = new ParsedownExtra();
|
||||
$html = $Parsedown->setBreaksEnabled(true)->text($markdown);
|
||||
echo $html;
|
||||
?>
|
||||
<div class="create_libreto">
|
||||
<form action="" method="POST">
|
||||
<input type="input" autofocus="autofocus" onfocus="this.select()" name="new_name" />
|
||||
<button type="submit" /><?= localize("create-libreto") ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</article>
|
||||
</body>
|
||||
// create Libreto
|
||||
$libreto = new Libreto($options);
|
||||
|
||||
</html>
|
||||
// launch
|
||||
$libreto->launch();
|
||||
|
||||
// var_dump($libreto);
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 411 KiB After Width: | Height: | Size: 411 KiB |
|
Before Width: | Height: | Size: 340 KiB After Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 360 KiB After Width: | Height: | Size: 360 KiB |
|
Before Width: | Height: | Size: 368 KiB After Width: | Height: | Size: 368 KiB |
|
Before Width: | Height: | Size: 298 KiB After Width: | Height: | Size: 298 KiB |
|
Before Width: | Height: | Size: 430 KiB After Width: | Height: | Size: 430 KiB |
|
Before Width: | Height: | Size: 358 KiB After Width: | Height: | Size: 358 KiB |
|
Before Width: | Height: | Size: 433 KiB After Width: | Height: | Size: 433 KiB |
|
Before Width: | Height: | Size: 431 KiB After Width: | Height: | Size: 431 KiB |
|
Before Width: | Height: | Size: 359 KiB After Width: | Height: | Size: 359 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
BIN
libreto/assets/images/logo.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
2
libreto/assets/js/bindery-controls.min.js
vendored
Normal file
2
libreto/assets/js/bindery.min.js
vendored
Normal file
3142
libreto/assets/js/bindery.umd.js
Normal file
|
|
@ -4,11 +4,7 @@ $(document ).ready( function() {
|
|||
$(this).parent().addClass('active').siblings().removeClass('active');
|
||||
var name = $(this).attr('data-name-encoded');
|
||||
var currentUrl = window.location.href.split('://')[1].split('/');
|
||||
if (use_subdomain) {
|
||||
var newUrl = '/' + name;
|
||||
} else {
|
||||
var newUrl = '/' + currentUrl[1] + '/' + name;;
|
||||
}
|
||||
var newUrl = '/' + currentUrl[1] + '/' + name;
|
||||
window.history.pushState("", "", newUrl);
|
||||
$('article').addClass('loading');
|
||||
});
|
||||
|
|
@ -63,7 +63,7 @@ Jean-Luc typeface Copyright (c) 2010 Atelier Carvalho Bernau
|
|||
|
||||
body {
|
||||
font-family: "HKGrotesk";
|
||||
font-size: 18pt;
|
||||
font-size: 16pt;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
|
@ -132,34 +132,23 @@ form {
|
|||
|
||||
input[type=input] {
|
||||
font-family: "HKGrotesk";
|
||||
font-size: 18pt;
|
||||
font-size: 16pt;
|
||||
background: none;
|
||||
border: 1px solid #00da53;
|
||||
padding: 1rem 2rem;
|
||||
border: 1px solid #000;
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
button[type=submit] {
|
||||
font-family: "HKGrotesk";
|
||||
font-size: 18pt;
|
||||
background: #00da53;
|
||||
font-size: 16pt;
|
||||
background: #000;
|
||||
color: #fff;
|
||||
border: 0px solid #ccc;
|
||||
padding: 1rem 2rem;
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
margin-bottom: 1rem;
|
||||
cursor: pointer;
|
||||
border-radius: 2rem;
|
||||
}
|
||||
|
||||
div[class^="lang-"] {
|
||||
display: none;
|
||||
}
|
||||
.current-lang-fr .lang-fr {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.current-lang-en .lang-en {
|
||||
display: block;
|
||||
}
|
||||
|
|
@ -30,7 +30,10 @@
|
|||
body {
|
||||
font-family: 'HKGrotesk';
|
||||
font-size: 16px;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
main {
|
||||
padding: 1rem;
|
||||
max-width: 40rem;
|
||||
}
|
||||
|
||||
|
|
@ -52,3 +55,10 @@ hr {
|
|||
border-bottom: 1px solid #ccc;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin: auto;
|
||||
display: block;
|
||||
}
|
||||
|
|
@ -83,16 +83,31 @@ a {
|
|||
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid #ccc;
|
||||
margin-bottom: 1rem;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1rem 0 ;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: .8rem;
|
||||
padding: .1rem .3rem;
|
||||
background: #eee;
|
||||
font-family: 'whoismono', monospace;
|
||||
border: .5px solid #ddd;
|
||||
margin: .1rem 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
header p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
header ul {
|
||||
margin: 1rem;
|
||||
margin: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
header li {
|
||||
list-style-type: "– ";
|
||||
margin-left: 1.1rem;
|
||||
margin-left: .8rem;
|
||||
list-style-position: outside;
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +117,8 @@ header u {
|
|||
}
|
||||
|
||||
header .full a {
|
||||
border-bottom: 1px solid #ccc;
|
||||
border: 0;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#container {
|
||||
|
|
@ -116,18 +132,18 @@ header .full a {
|
|||
|
||||
header {
|
||||
flex: 2;
|
||||
padding: 1rem;
|
||||
padding-top: 3rem;
|
||||
padding: 3rem 1.5rem 1.5rem 1.5rem;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
z-index: 2;
|
||||
border-right: 1px solid #ccc;
|
||||
border-right: 1px solid #ddd;
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
nav {
|
||||
flex: 1;
|
||||
border-right: 1px solid #ccc;
|
||||
border-right: 1px solid #ddd;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
}
|
||||
|
|
@ -156,7 +172,7 @@ nav li {
|
|||
font-family: 'spungold';
|
||||
font-size: 1.2rem;
|
||||
padding: 1rem;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
nav li.active a {
|
||||
|
|
@ -164,12 +180,12 @@ nav li.active a {
|
|||
}
|
||||
|
||||
nav li.settings {
|
||||
background-color: #ccc;
|
||||
border-bottom: 1px solid #B3B3B3;
|
||||
background-color: #eee;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
nav li.settings:last-child {
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
nav ul.menu {
|
||||
|
|
@ -177,8 +193,8 @@ nav ul.menu {
|
|||
}
|
||||
|
||||
nav ul.helpers {
|
||||
border-top: 1px solid #ccc;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +208,7 @@ nav ul.helpers li {
|
|||
|
||||
nav ul.helpers li {
|
||||
border: 0;
|
||||
border-right: 1px solid #ccc;
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
|
||||
nav ul.helpers li:last-child {
|
||||
|
|
@ -205,6 +221,11 @@ iframe {
|
|||
border: none;
|
||||
}
|
||||
|
||||
header .full {
|
||||
margin-bottom: 3rem;
|
||||
font-size: .9rem;
|
||||
}
|
||||
|
||||
header .colophon {
|
||||
font-size: .8rem;
|
||||
display: flex;
|
||||
|
|
@ -229,6 +250,7 @@ header.close div.full {
|
|||
|
||||
header.close {
|
||||
flex: none;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
header.close div {
|
||||
13
libreto/bootstrap.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
if(!defined('LIBRETO')) define('LIBRETO', true);
|
||||
if(!defined('DS')) define('DS', DIRECTORY_SEPARATOR);
|
||||
|
||||
// load all dependencies
|
||||
require __DIR__ . DS . 'vendor' . DS . 'autoload.php';
|
||||
|
||||
// load all core classes
|
||||
spl_autoload_register('loadClass');
|
||||
|
||||
// load all helper functions
|
||||
require __DIR__ . DS . 'helpers.php';
|
||||
43
libreto/helpers.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
session_start();
|
||||
|
||||
function snippet($name){
|
||||
require ROOT . DS . 'views' . DS . 'snippets' . DS . $name . '.php';
|
||||
}
|
||||
|
||||
function l($keyword, $markdown = true){
|
||||
global $libreto;
|
||||
$keyword = trim($keyword);
|
||||
$template = $libreto->router()->template();
|
||||
$language = $libreto->language();
|
||||
$filename = $template . "." . $language . ".yml";
|
||||
$dictionnary = Spyc::YAMLLoad(ROOT . DS . 'views' . DS . 'languages' . DS . $filename);
|
||||
if(array_key_exists($keyword, $dictionnary)):
|
||||
$text = $dictionnary[$keyword];
|
||||
return ($markdown ? parsedown($text) : $text);
|
||||
else:
|
||||
return $keyword;
|
||||
endif;
|
||||
}
|
||||
|
||||
function parsedown($markdown){
|
||||
global $Parsedown;
|
||||
$html = $Parsedown
|
||||
->setBreaksEnabled(true) # enables automatic line breaks
|
||||
->text($markdown);
|
||||
return $html;
|
||||
}
|
||||
|
||||
function startsWith($haystack, $needle)
|
||||
{
|
||||
$length = strlen($needle);
|
||||
return (substr($haystack, 0, $length) === $needle);
|
||||
}
|
||||
|
||||
function endsWith($haystack, $needle)
|
||||
{
|
||||
$length = strlen($needle);
|
||||
|
||||
return $length === 0 ||
|
||||
(substr($haystack, -$length) === $needle);
|
||||
}
|
||||
179
libreto/libreto.php
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
|
||||
class Libreto
|
||||
|
||||
{
|
||||
|
||||
private $options;
|
||||
private $name;
|
||||
private $language;
|
||||
private $mode;
|
||||
private $menu;
|
||||
private $pads;
|
||||
private $router;
|
||||
private $provider;
|
||||
|
||||
public function defaults(){
|
||||
$defaults = array(
|
||||
'name' => "Libreto",
|
||||
'url' => $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER["SERVER_NAME"],
|
||||
'default_provider' => 'framapad',
|
||||
);
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
public function __construct($options) {
|
||||
|
||||
$this->pads = new Pads();
|
||||
$this->router = new Router();
|
||||
$this->options = array_merge($this->defaults(), $options);
|
||||
|
||||
$this->set_provider();
|
||||
$this->set_name();
|
||||
$this->set_language();
|
||||
$this->set_mode();
|
||||
|
||||
}
|
||||
|
||||
public function launch(){
|
||||
|
||||
$this->set_menu();
|
||||
$this->set_pads();
|
||||
|
||||
// Load template
|
||||
include ROOT . DS . "views" . DS . "templates" . DS . $this->router()->template() . ".php";
|
||||
|
||||
}
|
||||
|
||||
public function set_provider(){
|
||||
$name = $this->router()->provider() ?: $this->options('default_provider');
|
||||
$providers = $this->options('providers');
|
||||
if ($name && array_key_exists($name, $providers)) :
|
||||
$this->provider = $providers[$name];
|
||||
endif;
|
||||
return;
|
||||
}
|
||||
|
||||
public function provider($key = 'url'){
|
||||
return $this->provider[$key];
|
||||
}
|
||||
|
||||
public function set_name(){
|
||||
$this->name = $this->router()->name();
|
||||
}
|
||||
|
||||
public function set_language() {
|
||||
$language = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
|
||||
switch ($language){
|
||||
case "fr":
|
||||
$this->language = "fr";
|
||||
return "fr";
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->language = "en";
|
||||
return "en";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function language()
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
public function set_mode() {
|
||||
if (!isset($_SESSION['mode'])) {
|
||||
$_SESSION['mode'] = 'read';
|
||||
}
|
||||
if(isset($_GET['mode'])):
|
||||
if($_GET['mode'] == "write") :
|
||||
$_SESSION['mode'] = 'write';
|
||||
else :
|
||||
$_SESSION['mode'] = 'read';
|
||||
endif;
|
||||
// redirect to same page without url parameters
|
||||
$url = strtok($_SERVER["REQUEST_URI"],'?');
|
||||
header('Location: ' . $url );
|
||||
endif;
|
||||
$this->mode = $_SESSION['mode'];
|
||||
}
|
||||
|
||||
public function set_menu(){
|
||||
$this->pads()->push('Menu (type: settings visibility: private)');
|
||||
$pad = $this->pads()->find('Menu');
|
||||
$menu = array_values(array_filter(preg_split('/\r\n|\r|\n/', $pad->txt())));
|
||||
$menu = array_map('trim', $menu);
|
||||
// if menu is filled with default text, make it empty
|
||||
if(count($menu)):
|
||||
if( strpos($menu[0], $this->provider('default_text')) === 0 ) :
|
||||
$menu = array();
|
||||
endif;
|
||||
endif;
|
||||
$this->menu = $menu;
|
||||
}
|
||||
|
||||
public function set_pads(){
|
||||
$this->pads->push($this->menu);
|
||||
// find the requested pad or else the first of the menu list
|
||||
$pad = $this->router()->pad() ?: $this->pads->first();
|
||||
// select requested pad
|
||||
if ($pad):
|
||||
$pad->select();
|
||||
endif;
|
||||
}
|
||||
|
||||
public function router(){
|
||||
// Router
|
||||
return $this->router;
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function pads() {
|
||||
return $this->pads;
|
||||
}
|
||||
|
||||
public function credits() {
|
||||
$Parsedown->text(file_get_contents("/libreto/assets/texts/colophon.md"));
|
||||
}
|
||||
|
||||
public function mode(){
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
public function options($key){
|
||||
if(array_key_exists($key, $this->options)):
|
||||
return $this->options[$key];
|
||||
endif;
|
||||
return;
|
||||
}
|
||||
|
||||
public function export(){
|
||||
|
||||
$title = $this->name();
|
||||
$introduction = $this->pads()->find('about')->html();
|
||||
|
||||
$pads = $this->pads()->children();
|
||||
$chapters = array();
|
||||
foreach($pads as $pad) :
|
||||
$chapter = $pad->name();
|
||||
$html = $pad->html();
|
||||
$chapters[] = array("title" => $chapter, "html" => $html);
|
||||
endforeach;
|
||||
|
||||
$odt = new \CatoTH\HTML2OpenDocument\Text();
|
||||
$odt->addHtmlTextBlock('<h1>' . $title . '</h1>');
|
||||
$odt->addHtmlTextBlock($introduction);
|
||||
foreach ($chapters as $chapter) {
|
||||
$odt->addHtmlTextBlock('<h2>' . $chapter['title'] . '</h2>');
|
||||
$odt->addHtmlTextBlock($chapter['html']);
|
||||
}
|
||||
$odt->finishAndOutputOdt('libreto-' . $title . '.odt');
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
166
libreto/pad.php
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
<?php
|
||||
|
||||
class Pad
|
||||
|
||||
{
|
||||
|
||||
private $name;
|
||||
private $color;
|
||||
private $url;
|
||||
private $options;
|
||||
private $selected = false;
|
||||
|
||||
public function __construct($input) {
|
||||
|
||||
$this->color = "#000";
|
||||
$this->options = $this->defaults();
|
||||
$this->name = trim(preg_replace('/(?=[^\]])\([a-z0-9_-]+:.*?\)/', '', $input));
|
||||
|
||||
$search = preg_match('/(?=[^\]])\([a-z0-9_-]+:.*?\)/', $input, $options);
|
||||
if($search):
|
||||
$this->set_options($options[0]);
|
||||
endif;
|
||||
$this->set_urls();
|
||||
|
||||
}
|
||||
|
||||
public function defaults(){
|
||||
$defaults = array(
|
||||
'color' => "#000000",
|
||||
'type' => "default",
|
||||
'url' => false,
|
||||
'visibility' => 'visible'
|
||||
);
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
public function set_options($options) {
|
||||
$tag = trim( rtrim( ltrim( $options, '(' ), ')' ) );
|
||||
$attributes = "color|url|type|visibility";
|
||||
$search = preg_split('!(' . $attributes . '):!i', $tag, false, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
$num = 0;
|
||||
$attr = array();
|
||||
// get an associative array attribute=>value
|
||||
foreach($search as $key) :
|
||||
if(!isset($search[$num+1])) break;
|
||||
$key = trim($search[$num]);
|
||||
$value = trim($search[$num+1]);
|
||||
$this->options[$key] = $value;
|
||||
$num = $num+2;
|
||||
endforeach;
|
||||
}
|
||||
|
||||
public function options($key){
|
||||
if(array_key_exists($key, $this->options)):
|
||||
return $this->options[$key];
|
||||
endif;
|
||||
return;
|
||||
}
|
||||
|
||||
public function set_urls() {
|
||||
global $libreto;
|
||||
|
||||
if($this->options['url']):
|
||||
$title = array_slice(explode('/', trim('/', $this->options['url'])), -1)[0];
|
||||
$url = trim($this->options['url'], '/ ');
|
||||
else:
|
||||
$title = urlencode(strtolower($libreto->options('name'))) . "+" . urlencode(strtolower($libreto->name())) . "+" . urlencode(strtolower($this->name));
|
||||
$url = $libreto->provider('url') . "/p/" . $title;
|
||||
endif;
|
||||
|
||||
$this->url = array(
|
||||
"pad" => $url . $libreto->options('pads_params'),
|
||||
"reader" => "/reader/" . urlencode($libreto->name()) . '/' . urlencode($this->name),
|
||||
"txt" => $url . "/export/txt",
|
||||
"markdown" => $url . "/export/markdown"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function type(){
|
||||
if(array_key_exists('type', $this->options)):
|
||||
return $this->options['type'];
|
||||
endif;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function color(){
|
||||
if(array_key_exists('color', $this->options)):
|
||||
return $this->options['color'];
|
||||
endif;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function select() {
|
||||
$this->selected = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function selected(){
|
||||
return $this->selected;
|
||||
}
|
||||
|
||||
public function url($format = 'pad') {
|
||||
global $libreto;
|
||||
if($format == "pad"):
|
||||
if($libreto->mode() == "read"):
|
||||
return $this->url['reader'];
|
||||
else:
|
||||
return $this->url['pad'];
|
||||
endif;
|
||||
endif;
|
||||
return $this->url[$format];
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function txt() {
|
||||
$txt = file_get_contents($this->url('txt'));
|
||||
return $txt;
|
||||
}
|
||||
|
||||
public function html() {
|
||||
|
||||
global $Parsedown, $Purifier;
|
||||
|
||||
$markdown = file_get_contents($this->url('markdown'));
|
||||
// remove \url{} tags
|
||||
$markdown = preg_replace('#\\\url\{(.+)\}#i', '$1', $markdown);
|
||||
// replace underline tags
|
||||
$markdown = preg_replace('#underline(.+)underline#', '<u>$1</u>', $markdown);
|
||||
// strip slashes
|
||||
$markdown = stripslashes($markdown);
|
||||
// parse
|
||||
$html = $Parsedown->text($markdown);
|
||||
// sanitize
|
||||
$html = $Purifier->purify($html);
|
||||
// return
|
||||
return $html;
|
||||
|
||||
}
|
||||
|
||||
public function css(){
|
||||
$css = strip_tags(file_get_contents($this->url('txt')));
|
||||
return $css;
|
||||
}
|
||||
|
||||
public function visible($filter = false){
|
||||
global $libreto;
|
||||
if($filter) :
|
||||
$filter = (array)$filter;
|
||||
else:
|
||||
$filter = $libreto->mode() == 'read' ? array('visible') : array('visible', 'private');
|
||||
endif;
|
||||
|
||||
if(in_array($this->options('visibility'), $filter ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
83
libreto/pads.php
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
class Pads
|
||||
|
||||
{
|
||||
|
||||
private $pads = array();
|
||||
private $css = false;
|
||||
|
||||
public function __construct($pads = array()) {
|
||||
$this->push($pads);
|
||||
}
|
||||
|
||||
public function push($pads){
|
||||
$pads = (array)$pads;
|
||||
foreach ($pads as $pad) :
|
||||
if(endsWith($pad, '.css')):
|
||||
$this->pads[] = new Pad($pad . ' (type: settings visibility: private)');
|
||||
else:
|
||||
$this->pads[] = new Pad($pad);
|
||||
endif;
|
||||
endforeach;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function css() {
|
||||
if($css = $this->find('style.css')):
|
||||
return $css->css();
|
||||
endif;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function find($p){
|
||||
foreach($this->pads as $pad) :
|
||||
if (strtolower($pad->name()) == strtolower($p)):
|
||||
return $pad;
|
||||
endif;
|
||||
endforeach;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function children($filter = false) {
|
||||
global $libreto;
|
||||
$pads = array_filter($this->pads, function($pad) use ($filter) {
|
||||
if($pad->visible($filter)) { return true; }
|
||||
return false;
|
||||
});
|
||||
$pads = array_values($pads);
|
||||
return $pads;
|
||||
}
|
||||
|
||||
public function first() {
|
||||
$pads = $this->children();
|
||||
if(array_key_exists(0, $pads)):
|
||||
return $pads[0];
|
||||
endif;
|
||||
return;
|
||||
}
|
||||
|
||||
public function selected(){
|
||||
foreach ($this->pads as $pad) {
|
||||
if($pad->selected()) { return $pad; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function selectActivePad() {
|
||||
|
||||
global $libreto;
|
||||
|
||||
// set default pad
|
||||
$default = $this->first() ?: $this->find("help");
|
||||
|
||||
// set requested pad
|
||||
$pad = $libreto->router()->pad() ?: $default;
|
||||
|
||||
$pad->select();
|
||||
|
||||
return $pad;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
96
libreto/router.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
class Router
|
||||
|
||||
{
|
||||
|
||||
private $subdomain;
|
||||
private $directories;
|
||||
|
||||
public function __construct() {
|
||||
$this->split();
|
||||
}
|
||||
|
||||
public function split() {
|
||||
|
||||
// directories
|
||||
$directories = explode( '/', trim($_SERVER['REQUEST_URI'], '/') );
|
||||
$this->directories = array_filter(array_map("urldecode", $directories));
|
||||
|
||||
// subdomain
|
||||
$server_name = explode(".",$_SERVER["SERVER_NAME"]);
|
||||
if (array_key_exists(0, $server_name) && array_key_exists(2, $server_name)):
|
||||
$name = urldecode($server_name[0]);
|
||||
$this->subdomain = strtok( $name ,'?');
|
||||
endif;
|
||||
|
||||
}
|
||||
|
||||
public function provider(){
|
||||
return $this->subdomain;
|
||||
}
|
||||
|
||||
public function template(){
|
||||
if( array_key_exists(0, $this->directories) ):
|
||||
$templates = glob(ROOT . DS . "views" . DS . "templates" . DS . "*.php");
|
||||
$templates = array_map(function($file) {
|
||||
return basename($file, ".php");
|
||||
}, $templates);
|
||||
$directory = strtolower($this->directories[0]);
|
||||
if( in_array($directory, $templates) ):
|
||||
return $directory;
|
||||
else:
|
||||
return "libreto";
|
||||
endif;
|
||||
else:
|
||||
return "home";
|
||||
endif;
|
||||
}
|
||||
|
||||
public function name(){
|
||||
|
||||
global $libreto;
|
||||
|
||||
if($this->template() != "libreto"):
|
||||
$n = 1;
|
||||
else:
|
||||
$n = 0;
|
||||
endif;
|
||||
|
||||
if (array_key_exists($n + 0, $this->directories)):
|
||||
$name = urldecode($this->directories[$n + 0]);
|
||||
$name = strtok( $name ,'?');
|
||||
return $name;
|
||||
else:
|
||||
return false;
|
||||
endif;
|
||||
|
||||
}
|
||||
|
||||
public function pad(){
|
||||
|
||||
global $libreto;
|
||||
|
||||
if($this->template() != "libreto"):
|
||||
$n = 1;
|
||||
else:
|
||||
$n = 0;
|
||||
endif;
|
||||
|
||||
if (array_key_exists($n + 1, $this->directories)):
|
||||
$name = $this->directories[$n + 1];
|
||||
else:
|
||||
return false;
|
||||
endif;
|
||||
|
||||
if ($pad = $libreto->pads()->find($name)):
|
||||
if ($pad->visible()) :
|
||||
return $pad;
|
||||
endif;
|
||||
else:
|
||||
return false;
|
||||
endif;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
12
libreto/vendor/load.php
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
require_once 'parsedown/Parsedown.php';
|
||||
require_once 'parsedown-extra/ParsedownExtra.php';
|
||||
require_once 'html2opendocument/Base.php';
|
||||
require_once 'html2opendocument/Text.php';
|
||||
require_once 'htmlpurifier/library/HTMLPurifier.auto.php';
|
||||
require_once 'spyc/Spyc.php';
|
||||
|
||||
$Purifier = new HTMLPurifier();
|
||||
$Parsedown = new ParsedownExtra();
|
||||
$Parsedown = $Parsedown->setBreaksEnabled(true);
|
||||
35
reader.php
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
include('snippets/functions.php');
|
||||
|
||||
$pad_url = "https://annuel2.framapad.org/p/libreto-help";
|
||||
$host = array_key_exists('host', $_GET) ? $_GET['host'] : false;
|
||||
$css_name = array_key_exists('css', $_GET) ? urlencode($_GET['css']) : false;
|
||||
$pad_name = array_key_exists('pad', $_GET) ? urlencode($_GET['pad']) : false;
|
||||
$html = $css = false;
|
||||
if($host && $pad_name):
|
||||
$pad_url = $host . "/p/" . $pad_name . "/export/markdown";
|
||||
$html = get_html($pad_url);
|
||||
endif;
|
||||
if($css_name) :
|
||||
$css_url = $host . "/p/" . $css_name . "/export/txt";
|
||||
$css = file_get_contents($css_url);
|
||||
endif;
|
||||
?>
|
||||
<!doctype html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>Pad reader</title>
|
||||
<link rel="stylesheet" href="/assets/style-reader.css">
|
||||
<?= $css_name ? "<style>" . $css . "</style>" : "" ?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<?= $html ?>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
<?php
|
||||
// export
|
||||
if(isset($_GET['export'])):
|
||||
export();
|
||||
// redirect to same page without url parameters
|
||||
$url = strtok($_SERVER["REQUEST_URI"],'?');
|
||||
header('Location: ' . $url );
|
||||
endif;
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
<?php
|
||||
session_start();
|
||||
|
||||
require_once './config.php';
|
||||
require_once './assets/parsedown/Parsedown.php';
|
||||
require_once './assets/parsedown-extra/ParsedownExtra.php';
|
||||
require_once './assets/html2opendocument/Base.php';
|
||||
require_once './assets/html2opendocument/Text.php';
|
||||
require_once './assets/htmlpurifier/library/HTMLPurifier.auto.php';
|
||||
require_once './assets/spyc/Spyc.php';
|
||||
|
||||
$Purifier = new HTMLPurifier();
|
||||
$Parsedown = new ParsedownExtra();
|
||||
$Parsedown = $Parsedown->setBreaksEnabled(true);
|
||||
|
||||
function get_homepage() {
|
||||
$homepage = get_html(get_url("introduction", "markdown"));
|
||||
$exerpt = trim(strip_tags($homepage));
|
||||
if(strpos($exerpt, "–––––") === 0):
|
||||
$homepage = get_html(get_url("help", "markdown"));
|
||||
endif;
|
||||
return $homepage;
|
||||
}
|
||||
|
||||
function get_pads_list() {
|
||||
global $libreto_name, $custom_css;
|
||||
$pads_list = file(get_url("menu", "txt"));
|
||||
$pads_list = array_map('trim', $pads_list);
|
||||
// if pad is filled with default text, make pads_list empty
|
||||
$firstline = $pads_list[0];
|
||||
if( strpos($firstline, "–––––") === 0 ) :
|
||||
$pads_list = false;
|
||||
endif;
|
||||
// if a pad is named style.css, use it as css file
|
||||
if($pads_list):
|
||||
foreach ($pads_list as $key=>$pad_name) :
|
||||
if($pad_name == "style.css"):
|
||||
array_splice($pads_list, $key, 1);
|
||||
$custom_css = get_url($pad_name, "txt");
|
||||
endif;
|
||||
endforeach;
|
||||
endif;
|
||||
return $pads_list;
|
||||
}
|
||||
|
||||
function get_url($name, $format = "pad") {
|
||||
global $pads_host, $instance_name, $pads_params, $libreto_name;
|
||||
|
||||
$server = "http://" . $_SERVER["SERVER_NAME"];
|
||||
$pads_prefix = urlencode(strtolower($instance_name)) . "+" . urlencode($libreto_name) . "+";
|
||||
$pad_name = $pads_prefix . urlencode($name);
|
||||
$css_name = $pads_prefix . urlencode("style.css");
|
||||
$pad_url = $pads_host . "/p/" . $pad_name;
|
||||
|
||||
if($name == 'help') :
|
||||
$pad_url = "https://annuel2.framapad.org/p/libreto-help";
|
||||
if ($format == "markdown") {
|
||||
return $pad_url . "/export/markdown";
|
||||
} else {
|
||||
return $server . "/reader.php?host=$pads_host&pad=libreto-help&css=$css_name";
|
||||
}
|
||||
endif;
|
||||
|
||||
switch ($format) :
|
||||
case 'pad':
|
||||
if($_SESSION['mode'] == "write") :
|
||||
return $pad_url . $pads_params ;
|
||||
else:
|
||||
//var_dump($pad_url);
|
||||
return $server . "/reader.php?host=$pads_host&pad=$pad_name&css=$css_name" ;
|
||||
endif;
|
||||
break;
|
||||
|
||||
default:
|
||||
return $pad_url . "/export/" . $format ;
|
||||
break;
|
||||
endswitch;
|
||||
}
|
||||
|
||||
function get_html($markdown_url) {
|
||||
global $Parsedown, $Purifier;
|
||||
$markdown = file_get_contents($markdown_url);
|
||||
// remove \url{} tags
|
||||
$markdown = preg_replace('#\\\url\{(.+)\}#i', '$1', $markdown);
|
||||
// replace underline tags
|
||||
$markdown = preg_replace('#underline(.+)underline#', '<u>$1</u>', $markdown);
|
||||
// remove slashes
|
||||
$markdown = stripslashes($markdown);
|
||||
$html = $Parsedown->text($markdown);
|
||||
// sanitize html
|
||||
$html = $Purifier->purify($html);
|
||||
return $html;
|
||||
}
|
||||
|
||||
function export() {
|
||||
global $libreto_name, $homepage, $pads_list;
|
||||
$title = $libreto_name;
|
||||
$introduction = $homepage;
|
||||
|
||||
$chapters = $pads_list;
|
||||
$chapters = array_map(function($chapter){
|
||||
$url = get_url($chapter, 'markdown');
|
||||
$html = get_html($url);
|
||||
return array("title" => $chapter, "content" => $html);
|
||||
}, $chapters);
|
||||
|
||||
$odt = new \CatoTH\HTML2OpenDocument\Text();
|
||||
$odt->addHtmlTextBlock('<h1>' . $title . '</h1>');
|
||||
$odt->addHtmlTextBlock($homepage);
|
||||
foreach ($chapters as $chapter) {
|
||||
$odt->addHtmlTextBlock('<h2>' . $chapter['title'] . '</h2>');
|
||||
$odt->addHtmlTextBlock($chapter['content']);
|
||||
}
|
||||
$odt->finishAndOutputOdt('Libreto-' . $title . '.odt');
|
||||
}
|
||||
|
||||
function get_current_pad_name() {
|
||||
global $use_subdomain, $pads_list;
|
||||
if(is_array($pads_list)):
|
||||
$default_pad = $pads_list[0];
|
||||
else:
|
||||
$default_pad = false;
|
||||
endif;
|
||||
$uri = explode( '/', trim($_SERVER['REQUEST_URI'], '/') );
|
||||
if($use_subdomain) :
|
||||
if (array_key_exists(0, $uri)):
|
||||
$uri = urldecode($uri[0]);
|
||||
$pad_name = in_array($uri, $pads_list) ? $uri : false;
|
||||
else :
|
||||
$pad_name = $default_pad;
|
||||
endif;
|
||||
else :
|
||||
if (array_key_exists(1, $uri)):
|
||||
$uri = urldecode($uri[1]);
|
||||
if(is_array($pads_list)) :
|
||||
$pad_name = in_array($uri, $pads_list) ? $uri : false;
|
||||
else :
|
||||
$pad_name = false;
|
||||
endif;
|
||||
else :
|
||||
$pad_name = $default_pad;
|
||||
endif;
|
||||
endif;
|
||||
return $pad_name;
|
||||
}
|
||||
|
||||
function get_libreto_name() {
|
||||
global $use_subdomain;
|
||||
if($use_subdomain) :
|
||||
$server_name = explode(".",$_SERVER["SERVER_NAME"]);
|
||||
if (array_key_exists(0, $server_name) && array_key_exists(1, $server_name)):
|
||||
$name = urldecode($server_name[0]);
|
||||
$name = strtok( $name ,'?');
|
||||
endif;
|
||||
else:
|
||||
$uri = explode( '/', trim($_SERVER['REQUEST_URI'], '/') );
|
||||
if (array_key_exists(0, $uri)):
|
||||
$name = urldecode($uri[0]);
|
||||
$name = strtok( $name ,'?');
|
||||
endif;
|
||||
endif;
|
||||
return $name;
|
||||
}
|
||||
|
||||
function get_user_language() {
|
||||
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
|
||||
switch ($lang){
|
||||
case "fr":
|
||||
return "fr";
|
||||
break;
|
||||
default:
|
||||
return "en";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function load_translation_file() {
|
||||
return spyc_load_file("assets/texts/translation.yml");
|
||||
}
|
||||
|
||||
function localize($key) {
|
||||
global $translation, $user_language;
|
||||
if (array_key_exists($key, $translation)) :
|
||||
if (array_key_exists($user_language, $translation[$key])) :
|
||||
return $translation[$key][$user_language];
|
||||
elseif (array_key_exists($fallback_language, $translation[$key])) :
|
||||
return $translation[$key][$fallback_language];
|
||||
endif;
|
||||
else:
|
||||
return "$key ($user_language)";
|
||||
endif;
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title><?= $libreto_name ?> - Libreto</title>
|
||||
<link rel="stylesheet" media="screen" href="https://fontlibrary.org/face/belgica-belgika" type="text/css"/>
|
||||
<link rel="stylesheet" href="/assets/style.css">
|
||||
<script type="text/javascript">
|
||||
var use_subdomain = <?= $use_subdomain ?>;
|
||||
</script>
|
||||
<script src="http://code.jquery.com/jquery-3.3.1.min.js"></script>
|
||||
<script type="text/javascript" src="/assets/script.js"></script>
|
||||
<?= $custom_css ? '<style>' . $custom_css . '</style>' : '' ?>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
<?php
|
||||
// OPEN / CLOSE HEADER
|
||||
if ( ! isset($_SESSION['header']) ) :
|
||||
$_SESSION['header'] = 'close';
|
||||
endif;
|
||||
|
||||
// READ / WRITE MODE
|
||||
if ( ! isset($_SESSION['mode']) ) {
|
||||
$_SESSION['mode'] = 'read';
|
||||
}
|
||||
if(isset($_GET['mode'])):
|
||||
if($_GET['mode'] == "write") :
|
||||
$_SESSION['mode'] = 'write';
|
||||
else :
|
||||
$_SESSION['mode'] = 'read';
|
||||
endif;
|
||||
// redirect to same page without url parameters
|
||||
$url = strtok($_SERVER["REQUEST_URI"],'?');
|
||||
header('Location: ' . $url );
|
||||
endif;
|
||||
|
||||
|
||||
$user_language = get_user_language();
|
||||
$translation = load_translation_file();
|
||||
$custom_css = false;
|
||||
$libreto_name = get_libreto_name();
|
||||
$pads_list = get_pads_list();
|
||||
$current_pad_name = get_current_pad_name();
|
||||
$currentiframe = $current_pad_name ? get_url ( $current_pad_name ) : false ;
|
||||
$homepage = get_homepage();
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
<header class="<?= $_SESSION['header'] ?>">
|
||||
<div class="full">
|
||||
<?= $homepage ?>
|
||||
<div class="colophon">
|
||||
<?= $Parsedown->text(file_get_contents("./assets/texts/colophon.md")); ?>
|
||||
</div>
|
||||
<button class="switch">×</button>
|
||||
</div>
|
||||
<div class="reduced">
|
||||
<p class="instance_name"><a href="<?= $instance_url ?>"><?= $instance_name ?></a></p>
|
||||
<p class="libreto_name"><?= $libreto_name ?></p>
|
||||
<button class="switch">?</button>
|
||||
</div>
|
||||
</header>
|
||||