Skip to content

Commit

Permalink
Mise en forme du contenu des devoirs (#624)
Browse files Browse the repository at this point in the history
  • Loading branch information
ecnivtwelve authored Jan 20, 2025
2 parents b5b4450 + f1ac5f6 commit 12d37ad
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 37 deletions.
78 changes: 49 additions & 29 deletions src/utils/format/format_pronote_homeworks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,81 @@ function parse_homeworks (content: string): string {

const ignoredTags: Set<string> = new Set(["div", "span", "style", "script", "footer", "header"]);

const tagRegex: RegExp = /<\/?([a-zA-Z]+)(?:\s[^>]*)?>|([^<]+)/g;
const tagRegex = /<\/?([a-zA-Z]+)(?:\s[^>]*)?>|([^<]+)/g;

const htmlEntities: { [key: string]: string } = {
const htmlEntities: Record<string, string> = {
"&nbsp;": " ",
"&quot;": "\"",
"&#039;": "'"
"&#039;": "'",
};

// Décodage des entités HTML
function decodeHtmlEntities (text: string): string {
return text.replace(/&#(\d+);/g, (match: string, dec: string) => String.fromCharCode(parseInt(dec, 10)))
.replace(/&([a-zA-Z]+);/g, (match: string) => htmlEntities[match] || match);
return text
.replace(/&#(\d+);/g, (_, dec) => String.fromCharCode(parseInt(dec, 10)))
.replace(/&([a-zA-Z]+);/g, (_, entity) => htmlEntities[entity] || `&${entity};`);
}

let result: string = "";
let match: RegExpExecArray | null;
let result = "";
const stack: Array<{ tag: string; children: string[] }> = [];

let match: RegExpExecArray | null;
while ((match = tagRegex.exec(content)) !== null) {
const [fullMatch, tagName, text] = match;

if (text) {
// Remplace les entités HTML dans le texte
result += decodeHtmlEntities(text);
// Texte brut entre balises
const decodedText = decodeHtmlEntities(text);
if (stack.length > 0) {
stack[stack.length - 1].children.push(decodedText);
} else {
result += decodedText;
}
} else if (tagName) {
const isClosingTag: boolean = fullMatch.startsWith("</");
const tag: string = tagName.toLowerCase();
const tag = tagName.toLowerCase();
const isClosingTag = fullMatch.startsWith("</");

if (!isClosingTag) {
if (isClosingTag) {
// Balise fermante
if (stack.length > 0 && stack[stack.length - 1].tag === tag) {
const { tag: currentTag, children } = stack.pop()!;
const processedContent = children.join("");

if (supportedTags[currentTag]) {
if (typeof supportedTags[currentTag] === "string") {
result += supportedTags[currentTag];
} else {
result += (supportedTags[currentTag] as (text: string) => string)(processedContent);
}
}
}
} else {
// Balise ouvrante ou auto-fermante
if (ignoredTags.has(tag)) {
continue; // Ignore les balises non supportées
} else if (supportedTags[tag]) {
// Balise ouvrante supportée
}

if (supportedTags[tag]) {
if (typeof supportedTags[tag] === "string") {
result += supportedTags[tag] as string;
result += supportedTags[tag];
} else {
const children: string[] = [];
let innerMatch: RegExpExecArray | null;
while ((innerMatch = tagRegex.exec(content)) !== null) {
const [innerFullMatch, innerTagName, innerText] = innerMatch;
if (innerText) {
children.push(innerText);
} else if (innerTagName && innerFullMatch.startsWith("</") && innerTagName.toLowerCase() === tag) {
break;
}
}
result += (supportedTags[tag] as (text: string) => string)(decodeHtmlEntities(children.join("")));
stack.push({ tag, children: [] });
}
}
}
}
}

// if there are multiple spaces, replace them with a single space
result = result.replace(/\s{2,}/g , " ");
// Traite les balises non fermées restantes
while (stack.length > 0) {
const { tag, children } = stack.pop()!;
if (supportedTags[tag] && typeof supportedTags[tag] === "function") {
result += (supportedTags[tag] as (text: string) => string)(children.join(""));
}
}

return result;
// Nettoyage des sauts de ligne en excès
return result.replace(/\n{2,}/g, "").trim();
}

export default parse_homeworks;
29 changes: 22 additions & 7 deletions src/views/account/Homeworks/Atoms/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useCurrentAccount } from "@/stores/account";
import LinkFavicon, { getURLDomain } from "@/components/Global/LinkFavicon";
import { AutoFileIcon } from "@/components/Global/FileIcon";
import { timestampToString } from "@/utils/format/DateHelper";
import parse_homeworks from "@/utils/format/format_pronote_homeworks";


interface HomeworkItemProps {
Expand All @@ -44,7 +45,8 @@ const HomeworkItem = ({ homework, navigation, onDonePressHandler, index, total }
fontFamily: "medium",
fontSize: 16,
lineHeight: 22,
}
maxHeight: 22 * 5,
},
});

useEffect(() => {
Expand Down Expand Up @@ -72,7 +74,7 @@ const HomeworkItem = ({ homework, navigation, onDonePressHandler, index, total }
setMainLoaded(true);
}, [homework.done]);


const contentLines = homework.content.split("\n");

const renderCategoryOrReturnType = () => {
if (category) {
Expand Down Expand Up @@ -186,10 +188,23 @@ const HomeworkItem = ({ homework, navigation, onDonePressHandler, index, total }
entering={FadeIn.duration(200)}
exiting={FadeOut.duration(200).delay(50)}
>
<HTMLView
value={`<body>${homework.content.replaceAll("<br>", " ")}</body>`}
stylesheet={stylesText}
/>

<View style={{ position: "relative" }}>
<HTMLView value={`<body>${parse_homeworks(homework.content).replace("\n", "")}</body>`} stylesheet={stylesText} />
{contentLines.length > 5 && (
<LinearGradient
colors={[theme.colors.background + "00", theme.colors.background + "80"]}
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
height: "100%",
zIndex: 1,
}}
/>
)}
</View>
{route.name === "HomeScreen" && (
<View style={{ flex: 1, flexDirection: "row", gap: 4, paddingBottom: 4, paddingTop: 8, alignItems: "center", alignSelf: "flex-start" }}>
<Clock
Expand All @@ -209,7 +224,7 @@ const HomeworkItem = ({ homework, navigation, onDonePressHandler, index, total }
flexDirection: "row",
alignItems: "center",
gap: 6,
marginTop: 4,
marginTop: 8,
borderWidth: 1,
alignSelf: "flex-start",
borderColor: theme.colors.text + "33",
Expand Down
5 changes: 4 additions & 1 deletion src/views/account/Homeworks/Document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { AutoFileIcon } from "@/components/Global/FileIcon";
import { Paperclip, CircleAlert } from "lucide-react-native";
import LinkFavicon, { getURLDomain } from "@/components/Global/LinkFavicon";
import { timestampToString } from "@/utils/format/DateHelper";
import parse_homeworks from "@/utils/format/format_pronote_homeworks";

const HomeworksDocument: Screen<"HomeworksDocument"> = ({ route }) => {
const theme = useTheme();
Expand All @@ -47,8 +48,10 @@ const HomeworksDocument: Screen<"HomeworksDocument"> = ({ route }) => {
});

const homework: Homework = route.params.homework || {};

const account = useCurrentAccount((store) => store.account!);


const openUrl = (url: string) => {
if (
account.service === AccountService.EcoleDirecte &&
Expand Down Expand Up @@ -171,7 +174,7 @@ const HomeworksDocument: Screen<"HomeworksDocument"> = ({ route }) => {

<NativeItem>
<HTMLView
value={`<body>${homework.content.replaceAll("<br>", " ")}</body>`}
value={`<body>${parse_homeworks(homework.content)}</body>`}
stylesheet={stylesText}
onLinkPress={(url) => openUrl(url)}
/>
Expand Down

0 comments on commit 12d37ad

Please sign in to comment.