mirror of
https://github.com/ae-utbm/sith.git
synced 2026-09-03 19:19:19 +00:00
-11
@@ -3,7 +3,6 @@ from typing import Annotated, Literal
|
|||||||
from annotated_types import Ge, Le, MinLen
|
from annotated_types import Ge, Le, MinLen
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from django.http import HttpResponse
|
|
||||||
from ninja import File, Query
|
from ninja import File, Query
|
||||||
from ninja.security import SessionAuth
|
from ninja.security import SessionAuth
|
||||||
from ninja_extra import ControllerBase, api_controller, paginate, route
|
from ninja_extra import ControllerBase, api_controller, paginate, route
|
||||||
@@ -18,7 +17,6 @@ from core.models import Group, QuickUploadImage, SithFile, User
|
|||||||
from core.schemas import (
|
from core.schemas import (
|
||||||
FamilyGodfatherSchema,
|
FamilyGodfatherSchema,
|
||||||
GroupSchema,
|
GroupSchema,
|
||||||
MarkdownSchema,
|
|
||||||
SithFileSchema,
|
SithFileSchema,
|
||||||
UploadedFileSchema,
|
UploadedFileSchema,
|
||||||
UploadedImage,
|
UploadedImage,
|
||||||
@@ -28,18 +26,9 @@ from core.schemas import (
|
|||||||
UserSchema,
|
UserSchema,
|
||||||
ValidationErrorSchema,
|
ValidationErrorSchema,
|
||||||
)
|
)
|
||||||
from core.templatetags.renderer import markdown
|
|
||||||
from counter.utils import is_logged_in_counter
|
from counter.utils import is_logged_in_counter
|
||||||
|
|
||||||
|
|
||||||
@api_controller("/markdown")
|
|
||||||
class MarkdownController(ControllerBase):
|
|
||||||
@route.post("", url_name="markdown")
|
|
||||||
def render_markdown(self, body: MarkdownSchema):
|
|
||||||
"""Convert the markdown text into html."""
|
|
||||||
return HttpResponse(markdown(body.text), content_type="text/html")
|
|
||||||
|
|
||||||
|
|
||||||
@api_controller("/upload")
|
@api_controller("/upload")
|
||||||
class UploadController(ControllerBase):
|
class UploadController(ControllerBase):
|
||||||
@route.post(
|
@route.post(
|
||||||
|
|||||||
@@ -161,10 +161,6 @@ class UserFilterSchema(FilterSchema):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
class MarkdownSchema(Schema):
|
|
||||||
text: str
|
|
||||||
|
|
||||||
|
|
||||||
class FamilyGodfatherSchema(Schema):
|
class FamilyGodfatherSchema(Schema):
|
||||||
godfather: int
|
godfather: int
|
||||||
godchild: int
|
godchild: int
|
||||||
|
|||||||
@@ -3,16 +3,12 @@
|
|||||||
import "codemirror/lib/codemirror.css";
|
import "codemirror/lib/codemirror.css";
|
||||||
// @ts-expect-error 2307
|
// @ts-expect-error 2307
|
||||||
import "easymde/src/css/easymde.css";
|
import "easymde/src/css/easymde.css";
|
||||||
|
import { markdown } from "@ae_utbm/aemark";
|
||||||
// biome-ignore lint/correctness/noUndeclaredDependencies: Imported by EasyMDE
|
// biome-ignore lint/correctness/noUndeclaredDependencies: Imported by EasyMDE
|
||||||
import type CodeMirror from "codemirror";
|
import type CodeMirror from "codemirror"; // biome-ignore lint/style/useNamingConvention: This is how they called their namespace
|
||||||
// biome-ignore lint/style/useNamingConvention: This is how they called their namespace
|
|
||||||
import EasyMDE from "easymde";
|
import EasyMDE from "easymde";
|
||||||
import { inheritHtmlElement, registerComponent } from "#core:utils/web-components";
|
import { inheritHtmlElement, registerComponent } from "#core:utils/web-components";
|
||||||
import {
|
import { type UploadUploadImageErrors, uploadUploadImage } from "#openapi";
|
||||||
markdownRenderMarkdown,
|
|
||||||
type UploadUploadImageErrors,
|
|
||||||
uploadUploadImage,
|
|
||||||
} from "#openapi";
|
|
||||||
|
|
||||||
const loadEasyMde = (textarea: HTMLTextAreaElement) => {
|
const loadEasyMde = (textarea: HTMLTextAreaElement) => {
|
||||||
const easymde = new EasyMDE({
|
const easymde = new EasyMDE({
|
||||||
@@ -64,19 +60,7 @@ const loadEasyMde = (textarea: HTMLTextAreaElement) => {
|
|||||||
});
|
});
|
||||||
easymde.codemirror.replaceSelection("\n");
|
easymde.codemirror.replaceSelection("\n");
|
||||||
},
|
},
|
||||||
previewRender: (plainText, preview) => {
|
previewRender: (plainText) => markdown(plainText),
|
||||||
/* This is wrapped this way to allow time for Alpine to be loaded on the page */
|
|
||||||
return Alpine.debounce(() => {
|
|
||||||
const func = async () => {
|
|
||||||
preview.innerHTML = (
|
|
||||||
await markdownRenderMarkdown({ body: { text: plainText } })
|
|
||||||
).data as string;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
func().then();
|
|
||||||
return null;
|
|
||||||
}, 300)();
|
|
||||||
},
|
|
||||||
forceSync: true, // Avoid validation error on generic create view
|
forceSync: true, // Avoid validation error on generic create view
|
||||||
imageTexts: {
|
imageTexts: {
|
||||||
sbInit: gettext("Attach files by drag and dropping or pasting from clipboard."),
|
sbInit: gettext("Attach files by drag and dropping or pasting from clipboard."),
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
## syntaxe aemark
|
||||||
|
|
||||||
|
Le site AE utilise markdown pour le rendu de la plupart
|
||||||
|
des textes saisis par les utilisateurs.
|
||||||
|
Cependant, la syntaxe utilisée n'est pas celle officielle
|
||||||
|
telle que définie par John Gruber,
|
||||||
|
mais est basée sur [CommonMark](https://commonmark.org/),
|
||||||
|
avec quelques variations pour les usages particuliers du site AE.
|
||||||
|
|
||||||
|
Les deux principaux ajouts sont :
|
||||||
|
|
||||||
|
- Les urls commençant par `page://` sont modifiées pour commencer par `/page/`
|
||||||
|
- Des modificateurs de taille peuvent être indiqués directement dans la source
|
||||||
|
d'une image
|
||||||
|
|
||||||
|
Les variations d'aemark sont documentées sur
|
||||||
|
[le site AE](https://ae.utbm.fr/page/Aide_sur_la_syntaxe/).
|
||||||
|
|
||||||
|
Le code est hébergé sur le dépôt Git [aemark](https://github.com/ae-utbm/ae-markdown).
|
||||||
|
|
||||||
|
## Utiliser aemark
|
||||||
|
|
||||||
|
Le code du parser aemark est écrit en Rust dans une librairie
|
||||||
|
indépendante, avec des bindings vers différents langages.
|
||||||
|
Les librairies mises à disposition exposent une seule fonction,
|
||||||
|
qui prend simplement du markdown en entrée et renvoie l'HTML correspondant.
|
||||||
|
|
||||||
|
Les librairies pour les différents langages sont toutes
|
||||||
|
basées sur le même code Rust.
|
||||||
|
La seule différence entre chacune tient uniquement dans la manière
|
||||||
|
d'intégrer ce code dans les bindings.
|
||||||
|
De cette manière, le comportement est assuré d'être le même
|
||||||
|
sur toutes les plateformes disponibles, avec en prime des performances
|
||||||
|
respectables.
|
||||||
|
|
||||||
|
|
||||||
|
=== ":simple-python: Python"
|
||||||
|
|
||||||
|
```python
|
||||||
|
from aemark import markdown
|
||||||
|
|
||||||
|
result = markdown("this is some *markdown text* with __formatting__")
|
||||||
|
```
|
||||||
|
|
||||||
|
=== ":simple-javascript: Javascript"
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { markdown } from "@ae_utbm/aemark"
|
||||||
|
|
||||||
|
const result = markdown("this is some *markdown text* with __formatting__");
|
||||||
|
```
|
||||||
@@ -71,6 +71,7 @@ nav:
|
|||||||
- API:
|
- API:
|
||||||
- Développement: tutorial/api/dev.md
|
- Développement: tutorial/api/dev.md
|
||||||
- Connexion à l'API: tutorial/api/connect.md
|
- Connexion à l'API: tutorial/api/connect.md
|
||||||
|
- Markdown AE: tutorial/markdown.md
|
||||||
- Etransactions: tutorial/etransaction.md
|
- Etransactions: tutorial/etransaction.md
|
||||||
- How-to:
|
- How-to:
|
||||||
- L'ORM de Django: howto/querysets.md
|
- L'ORM de Django: howto/querysets.md
|
||||||
|
|||||||
Generated
+6
@@ -9,6 +9,7 @@
|
|||||||
"version": "3",
|
"version": "3",
|
||||||
"license": "GPL-3.0-only",
|
"license": "GPL-3.0-only",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ae_utbm/aemark": "^0.1.1",
|
||||||
"@alpinejs/sort": "^3.16.2",
|
"@alpinejs/sort": "^3.16.2",
|
||||||
"@arendjr/text-clipper": "npm:@jsr/arendjr__text-clipper@^3.0.0",
|
"@arendjr/text-clipper": "npm:@jsr/arendjr__text-clipper@^3.0.0",
|
||||||
"@floating-ui/dom": "^1.8.0",
|
"@floating-ui/dom": "^1.8.0",
|
||||||
@@ -56,6 +57,11 @@
|
|||||||
"vite": "^8.2.2"
|
"vite": "^8.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ae_utbm/aemark": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ae_utbm/aemark/-/aemark-0.1.1.tgz",
|
||||||
|
"integrity": "sha512-ZH5ebIfTjx02fMJexMG/To+AakmnedG0DH5Q/W3gUqRBimp0k5y/eUpvAmPXDdV9NnWy0IFxEZvKur0x6gidxA=="
|
||||||
|
},
|
||||||
"node_modules/@alpinejs/sort": {
|
"node_modules/@alpinejs/sort": {
|
||||||
"version": "3.16.2",
|
"version": "3.16.2",
|
||||||
"resolved": "https://registry.npmjs.org/@alpinejs/sort/-/sort-3.16.2.tgz",
|
"resolved": "https://registry.npmjs.org/@alpinejs/sort/-/sort-3.16.2.tgz",
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
"vite": "^8.2.2"
|
"vite": "^8.2.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@ae_utbm/aemark": "^0.1.1",
|
||||||
"@alpinejs/sort": "^3.16.2",
|
"@alpinejs/sort": "^3.16.2",
|
||||||
"@arendjr/text-clipper": "npm:@jsr/arendjr__text-clipper@^3.0.0",
|
"@arendjr/text-clipper": "npm:@jsr/arendjr__text-clipper@^3.0.0",
|
||||||
"@floating-ui/dom": "^1.8.0",
|
"@floating-ui/dom": "^1.8.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user