[{"data":1,"prerenderedAt":471},["ShallowReactive",2],{"blog-right-to-left-text":3,"blog-related-right-to-left-text":133},{"id":4,"title":5,"author":6,"body":7,"category":117,"date":118,"description":119,"draft":120,"extension":121,"featured":120,"image":122,"imageAlt":122,"meta":123,"navigation":124,"ogImage":122,"path":125,"seo":126,"stem":127,"tags":128,"updated":122,"__hash__":132},"blog\u002Fblog\u002Fright-to-left-text.md","The bug that printed confident nonsense","team",{"type":8,"value":9,"toc":107},"minimark",[10,14,17,22,25,28,31,35,38,45,51,57,60,64,67,70,78,82,87,90,94,97],[11,12,13],"p",{},"A school sent us a report card and asked why the Arabic subject names came out as nonsense.",[11,15,16],{},"They were not nonsense. They were confident, well-spaced, correctly-kerned Latin letters, printed\nneatly in the place where Arabic should have been. That distinction is the whole story, because it is\nwhat made the problem hard to see from our end. It did not look like a rendering failure. It looked\nlike a school that had typed something wrong.",[18,19,21],"h2",{"id":20},"why-a-pdf-does-this","Why a PDF does this",[11,23,24],{},"The fonts built into the PDF standard are WinAnsi-encoded. They cover Latin and not much else.",[11,26,27],{},"Hand one of them Arabic and it does not draw a box, and it does not refuse. It takes each byte, maps\nit to whatever Latin glyph sits at that position in its own encoding, and draws that, at full\nquality. The output is a finished-looking document that nobody at the school can read.",[11,29,30],{},"A missing-glyph box would have been a better outcome. A row of boxes is obviously broken and gets\nreported on the first day. Plausible-looking Latin gets filed, and the school assumes the fault is\ntheirs.",[18,32,34],{"id":33},"three-separate-problems","Three separate problems",[11,36,37],{},"Getting Arabic onto the page needs three things, and skipping any one of them still produces a wrong\ndocument rather than an obviously broken one.",[11,39,40,44],{},[41,42,43],"strong",{},"A font that has the glyphs."," Without an embedded face that actually contains Arabic, you are back\nto the Latin substitution above.",[11,46,47,50],{},[41,48,49],{},"Shaping."," Arabic letters change form depending on what sits either side of them: initial, medial,\nfinal, isolated. Draw the isolated forms in sequence and you get disconnected letters. A reader can\ndecode it, in the way you can decode a word with the letters spaced out, and nobody would accept it\non a document their child brings home.",[11,52,53,56],{},[41,54,55],{},"Bidirectional ordering."," The shaper does not do this, which is the part most often missed. A line\nthat mixes Arabic with a pupil's Latin name or a numeric mark has to have its runs put in the right\norder first, and then the glyphs inside each run ordered by the shaper. Get it wrong and the mark\nends up on the wrong side of the subject it belongs to.",[11,58,59],{},"So the order is: work out the run order, then let the shaper order what is inside each run.",[18,61,63],{"id":62},"where-we-put-the-fix","Where we put the fix",[11,65,66],{},"At the single point where the platform creates a PDF document, not in each renderer.",[11,68,69],{},"A renderer that has to opt in to correct text is a renderer somebody eventually forgets, and the one\nthey forget is the certificate. Patching the one place a document is created means every PDF that\nlibrary draws got this at once: invoices, receipts, the family's own copies of both, the exam\ntimetable and our own subscription receipt.",[11,71,72,73,77],{},"Four of our documents render through headless Chromium rather than the PDF library, and they needed\nthe other half of the same problem solved: an inlined Arabic face, and ",[74,75,76],"code",{},"unicode-bidi: plaintext"," on\nthe elements that hold a school's own words. Those are the ones whose direction we cannot know in\nadvance, because they are whatever the school typed.",[18,79,81],{"id":80},"the-bar-for-shipping-it","The bar for shipping it",[11,83,84],{},[41,85,86],{},"A school with no Arabic gets byte-identical documents to the ones it got before.",[11,88,89],{},"That was the condition. A change to the text engine underneath every document the platform produces\nis exactly the sort of thing that shifts a margin by a point, re-wraps a line on someone's invoice,\nand turns into a fortnight of reports from schools who have nothing to do with Arabic.",[18,91,93],{"id":92},"if-your-school-teaches-arabic","If your school teaches Arabic",[11,95,96],{},"Nothing to switch on. Type Arabic into subject names, teacher remarks, class names or the head\nteacher's comment and it prints properly, mixed with Latin and with numbers on the same line.",[98,99,104],"screenshot",{"alt":100,"height":101,"src":102,"width":103},"A rendered report card PDF for Fatima Abdullahi of JSS 1A, First Term 2026\u002F2027. Four of her six subjects are named in Arabic and two in English, and the Arabic names sit right-aligned in the same column as Computer Science and English Language, each row carrying the same total, grade and remark. Both remark panels below are written in Arabic and set right to left: the teacher's runs across two lines and contains the numeral 91 and the Latin words Computer Science inside the Arabic sentence, each placed in reading order rather than at the end of the line.",2339,"\u002Fblog\u002Fright-to-left-text\u002Freport-card.png",1656,[11,105,106],{},"It pairs with the Hijri calendar option, which lets a school read and enter dates in the Umm al-Qura\ncalendar, the Gregorian one, or both, without changing a single stored date. Both are the same idea:\na school should be able to run in the language and the calendar it actually uses, and neither should\nrequire a separate version of the product.",{"title":108,"searchDepth":109,"depth":109,"links":110},"",3,[111,113,114,115,116],{"id":20,"depth":112,"text":21},2,{"id":33,"depth":112,"text":34},{"id":62,"depth":112,"text":63},{"id":80,"depth":112,"text":81},{"id":92,"depth":112,"text":93},"Guides","2026-08-16","A school asked why the Arabic on its report cards was gibberish. It was not gibberish, and that is what made it hard to spot. What it takes to print Arabic properly in a PDF.",false,"md",null,{},true,"\u002Fblog\u002Fright-to-left-text",{"title":5,"description":119},"blog\u002Fright-to-left-text",[129,130,131],"report-cards","internationalisation","product","hhNFq4YguQCpT35AUSKtoYrKGXURJ6UNf3aOCq1DCXY",[134,308],{"id":135,"title":136,"author":6,"body":137,"category":117,"date":300,"description":301,"draft":120,"extension":121,"featured":124,"image":122,"imageAlt":122,"meta":302,"navigation":124,"ogImage":122,"path":303,"seo":304,"stem":305,"tags":306,"updated":122,"__hash__":307},"blog\u002Fblog\u002Freport-card-designer.md","Design the report card your school actually prints",{"type":8,"value":138,"toc":293},[139,142,145,148,151,155,161,170,173,179,190,196,200,203,206,213,216,223,227,230,233,242,245,249,255,261,267,271,281,284],[11,140,141],{},"Ask ten schools what belongs on a report card and you will get ten answers.",[11,143,144],{},"Some rank every child in the class and print the position in bold. Some think ranking a nine-year-old\nis the worst thing a school can do to them, and want the column gone. Some print the highest and\nlowest score in each subject so a parent can see where their child sits without a rank. Some print\nthree assessment columns, some print one. Some want the head teacher's remark at the bottom under a\nsignature line, and some want it at the top, because it is the part parents actually read.",[11,146,147],{},"Until this release, 1410SMS had one opinion about all of that, and it was ours.",[11,149,150],{},"The card was a good card. It was also the same card in Kaduna and in Lekki, in a nursery and in a\nsixth form, and every school that wanted something slightly different had the same conversation with\nus: could you move this, could you take that off, we do not use positions here.",[18,152,154],{"id":153},"what-changed","What changed",[11,156,157,160],{},[41,158,159],{},"Report Cards → Designer"," is now a page where a school lays out its own card and watches it redraw\nas it goes.",[98,162,167],{"alt":163,"height":164,"src":165,"width":166},"The Report Card Designer: a list of the school's designs and the card's sections on the left, a live preview of a real student's report card in the middle, and a properties panel on the right showing the template's name, style, report title, heading typeface, border and logo position",1736,"\u002Fblog\u002Freport-card-designer\u002Fdesigner.png",2832,[11,168,169],{},"The designer. Sections on the left, the card in the middle, and the settings for whatever you have\nselected on the right.",[11,171,172],{},"Three things are going on there.",[11,174,175,178],{},[41,176,177],{},"The section list on the left is the card's running order."," Every band of the card is an item you\ncan move up, move down, hide, or place: full width, the wide column, the narrow column beside it,\nor half width next to its neighbour. Move the remarks above the subject table and the remarks print\nabove the subject table. There is no fixed skeleton underneath waiting to reassert itself.",[11,180,181,184,185,189],{},[41,182,183],{},"The middle is not a mock-up."," It is the real card, rendered by the same code that produces the\nPDF, using a real pupil's real marks. We debated a tidy sample student with three subjects and a\nshort name, and decided against it: the question a head teacher is actually asking is ",[186,187,188],"em",{},"will this fit\nour card",", and a school with fourteen subjects and double-barrelled surnames needs that answered\nhonestly. Pick any graded pupil from the dropdown at the top.",[11,191,192,195],{},[41,193,194],{},"The right-hand panel is whatever you have selected."," Select the subject table and you get its\ncolumns: total, grade, remark, highest, lowest, class average, position, previous terms. Select the\nskills grid and you get rows or a grid, and how many columns. Select nothing and you get the card\nitself: its style, its title band, its heading typeface, its border, where the logo sits.",[18,197,199],{"id":198},"colours","Colours",[11,201,202],{},"The card follows your school's brand colours by default, which is right almost all the time and\noccasionally wrong. A school whose brand is a bright orange may not want a report card in bright\norange, and a school with a formal crest often wants the card darker and quieter than the website.",[11,204,205],{},"So the card's two colours can be set on their own.",[98,207,210],{"alt":208,"height":164,"src":209,"width":166},"The Colours panel of the Report Card Designer, with the main colour left following the school's brand colour and the accent colour overridden to the blue #1D4ED8, and the preview beside it showing a blue title band and seal","\u002Fblog\u002Freport-card-designer\u002Fcolours.png",[11,211,212],{},"The main colour still follows the school's brand. The accent has been set to a blue of its own, and\nthe title band in the preview has already changed.",[11,214,215],{},"They are described by where they print rather than by their names, because \"secondary colour\" tells\nyou nothing about what will move. The main colour is the header band and the totals bar. The accent\nis the title strip, the seal, the rules between sections, the remark headings and the footer.",[11,217,218,219,222],{},"Each one is off by default and says which school colour it is inheriting. That is deliberate: a\npre-filled colour picker cannot express ",[186,220,221],{},"follow the school",", so a school that rebrands next year\nwould find its report card still printing last year's colour with nothing on screen to explain why.\nLeave it off and the card follows. Switch it on and it does not.",[18,224,226],{"id":225},"one-school-several-cards","One school, several cards",[11,228,229],{},"A school is often several schools. The nursery, the junior school and the sixth form do not\nnecessarily want the same document, and a boarding house report is not a termly academic report.",[11,231,232],{},"You can keep more than one design and say which classes print on which.",[98,234,239],{"alt":235,"height":236,"src":237,"width":238},"A drawer titled Which classes print on this design, explaining that a class with no design of its own prints on the school-wide one, and listing the school's classes from JSS 1A to SS 3A with SS 1A and SS 2A ticked",1816,"\u002Fblog\u002Freport-card-designer\u002Fclasses.png",3400,[11,240,241],{},"SS 1A and SS 2A print on the senior design. Everything else falls through to the school-wide one.",[11,243,244],{},"A class can only ever be on one design, which is enforced in the database rather than by asking you\nto be careful. Anything you have not assigned prints on your school-wide card, so a school that\nwants one card for everybody never has to open this at all.",[18,246,248],{"id":247},"what-has-not-changed","What has not changed",[11,250,251,254],{},[41,252,253],{},"If you never open the designer, nothing about your report cards changes."," The card every school\nhas been printing is now called the Standard Report Card, it is what every school starts on, and it\nis the same document it was last term. It cannot be edited or deleted, which is what makes it\nsomewhere to go back to: customising means duplicating it, and if the copy turns out to be a mistake,\nthe original is still sitting there.",[11,256,257,260],{},[41,258,259],{},"The maths is still ours."," Totals, averages, grades, positions, class highs and lows, cumulative\naverages across terms. None of that is affected by how the card is laid out, and none of it is\ncomputed twice. The design decides what is shown and where. It never decides what a number is.",[11,262,263,266],{},[41,264,265],{},"The phone gets it for free."," The mobile app displays the PDF the server produces, so a design\nsaved on a laptop at four o'clock is what a parent opens on their phone at five.",[18,268,270],{"id":269},"where-to-find-it","Where to find it",[11,272,273,276,277,280],{},[41,274,275],{},"Report Cards"," in the sidebar, then the ",[41,278,279],{},"Designer"," tab. It sits beside the report card directory\nand the skills and traits catalogue, which used to be three separate pages and are now one workspace.",[11,282,283],{},"Teachers see the directory and nothing else. Designing the school's card is an administrator's job,\nand the tabs a teacher cannot use are not shown to them at all.",[11,285,286,287,292],{},"There is a fuller walkthrough in the ",[288,289,291],"a",{"href":290},"\u002Fdocs\u002Freport-card-designer","Report Card Designer\ndocumentation",", including what every section's settings do.",{"title":108,"searchDepth":109,"depth":109,"links":294},[295,296,297,298,299],{"id":153,"depth":112,"text":154},{"id":198,"depth":112,"text":199},{"id":225,"depth":112,"text":226},{"id":247,"depth":112,"text":248},{"id":269,"depth":112,"text":270},"2026-08-05","Schools do not agree on what belongs on a report card, and until now ours only had one opinion. The Report Card Designer lets each school decide what appears, where it sits, and what it says.",{},"\u002Fblog\u002Freport-card-designer",{"title":136,"description":301},"blog\u002Freport-card-designer",[129,131],"wa5voYXTIlAT5mIKniMmx4JKuSHIly04kdZW96eINLs",{"id":309,"title":310,"author":6,"body":311,"category":461,"date":118,"description":462,"draft":120,"extension":121,"featured":120,"image":122,"imageAlt":122,"meta":463,"navigation":124,"ogImage":122,"path":464,"seo":465,"stem":466,"tags":467,"updated":122,"__hash__":470},"blog\u002Fblog\u002Fexams-workspace.md","Nobody should draw an exam timetable in pencil",{"type":8,"value":312,"toc":455},[313,316,319,323,326],[11,314,315],{},"The exam timetable is drawn on paper, in pencil, by one person, in a week that nobody else wants.",[11,317,318],{},"Then a teacher goes on leave, one paper moves to the Thursday, and the whole grid needs checking\nagain by eye. Usually it is not checked, because checking it means reading forty rows against each\nother twice. So a class sits two papers at once in the third week, and everybody finds out in the\nhall.",[18,320,322],{"id":321},"a-series-checked-before-it-goes-out","A series, checked before it goes out",[11,324,325],{},"An exam series in 1410SMS is a set of sittings: a class, a subject, a date, a time, a room, an\ninvigilator. Building one is ordinary data entry. What makes it worth having is what happens next.",[98,327,332,338,344],{"alt":328,"height":329,"src":330,"width":331},"The Exams page with four tabs across the top, Exam Series, Builder, Reports and Settings, with Builder selected. To the right of the tabs an exam picker reads First Term Examination 2026\u002F2027, followed by a draft badge and the label Terminal Examination. Below, the series heading gives its term, session and dates beside a Publish and notify button; then a panel headed Worth checking before you publish, listing three amber Check findings and reading 0 to fix, 3 to consider; then the Generate the timetable panel, open at step one of four, Who is sitting.",1416,"\u002Fdocs\u002Fexams-workspace\u002Fworkspace.png",1832,[11,333,334,337],{},[41,335,336],{},"One action checks the whole series."," It reports every clash it can find, including the two that\nmatter most: the same class sitting two papers at once, and the same invigilator in two halls at\nonce. Clash detection runs on the weekly timetable engine's own logic rather than a second\nimplementation of it, so the two cannot drift apart and start disagreeing about what a conflict is.",[11,339,340,343],{},[41,341,342],{},"Publishing runs the same check and refuses on errors",", with the findings on the response rather\nthan a shrug and a support ticket. You cannot publish a broken series by accident.",[98,345,349,353,356,367,371,374,381,385,388,395],{"alt":346,"height":347,"src":348,"width":331},"A panel headed 'This timetable cannot be published yet' at the top of an exam page for First Term Examination, First Term 2026\u002F2027, dated 22 to 24 July 2026. It lists eleven findings, with '1 to fix, 10 to consider' on the right. The first carries a red Fix badge and reads that JSS 1A's Computer Science paper is on 2026-07-24, a day the school calendar says it is closed. Below it, amber Check badges list seven subjects JSS 1A takes that have no paper in the exam, and three papers with no invigilator.",936,"\u002Fdocs\u002Fexam-validation\u002Ffindings.png",[18,350,352],{"id":351},"publishing-is-its-own-permission","Publishing is its own permission",[11,354,355],{},"Building a draft and telling four hundred families are not the same act, so they are not the same\npermission. A member of staff can be given the series to build and not the button that sends it.",[11,357,358,359,362,363,366],{},"This pairs with the rule that makes drafts usable at all: ",[41,360,361],{},"a draft announces nothing."," Move papers\naround in a draft as much as you like and the world stays quiet. Move or drop a paper ",[186,364,365],{},"after","\npublication and that class's families are told, because they have already written the old date in a\ndiary.",[18,368,370],{"id":369},"several-papers-move-together","Several papers move together",[11,372,373],{},"A cascade is the normal case. The Chemistry paper moves, so the Physics paper has to move to make\nroom, so the room booking changes.",[11,375,376,377,380],{},"Moving them one at a time through a clash checker means passing through arrangements that are not\nvalid and being told so at each step, which teaches you to ignore the checker. So a bulk move takes\nthe whole proposal and checks it against the series ",[41,378,379],{},"as it would be",", not as it is.",[18,382,384],{"id":383},"a-whole-series-can-be-generated","A whole series can be generated",[11,386,387],{},"If you would rather not place forty papers by hand, the workspace will do it, using the same\nconstruction core the weekly timetable generator uses.",[11,389,390,391,394],{},"You describe the shape you want, under ",[41,392,393],{},"Settings → Examinations",", rather than tuning six numeric\nweights: balanced, spread out, finished quickly, or mornings first. That distinction is most of the\nreason the feature is usable, because a scheduler that asks a bursar to balance six weights is a\nscheduler that gets used once. The weights are still there, behind a Custom option, for the school\nin fifty that wants them.",[98,396,401,405,408,411,415,431,434,438,441,448,452],{"alt":397,"height":398,"src":399,"width":400},"Step three of the generation wizard, What is in the way, with the four steps shown as pills reading Who is sitting, Which days, What is in the way and How to weigh it. Under a line saying what the engine needs in place, checked against this exam and the classes named above, a Re-check button sits on the right. The verdict reads Ready, with 1 thing worth knowing, above an amber note that JSS 1B has no pupils on its roll so no room can be checked against its size, and Back and Next buttons below.",542,"\u002Fdocs\u002Fexam-timetable-generation\u002Fgenerate.png",1754,[18,402,404],{"id":403},"a-paper-can-be-the-online-test-that-is-that-paper","A paper can be the online test that is that paper",[11,406,407],{},"If a subject is examined on the computer-based testing module, the sitting can be linked to that\ntest. The sitting then owns the test's window and its class list, so there is one thing to keep\ncorrect rather than two that must be kept in step.",[11,409,410],{},"On the phone that paper carries an \"Online\" tag, ahead of the room, which is still shown beside it.",[18,412,414],{"id":413},"four-documents-all-of-them-printable-from-a-phone","Four documents, all of them printable from a phone",[416,417,418,422,425,428],"ul",{},[419,420,421],"li",{},"A class's papers, for the noticeboard and the parents.",[419,423,424],{},"An invigilator's list, so they know their duties.",[419,426,427],{},"A room's day, for whoever is running that hall.",[419,429,430],{},"The attendance roster a paper is registered on.",[11,432,433],{},"All four print from the mobile app as well as the web, which is not a box-ticking exercise. An\ninvigilator wants their roster on the way into the hall, not at a desk twenty minutes earlier, and\nthat is the whole reason it is on a phone.",[18,435,437],{"id":436},"one-naming-decision","One naming decision",[11,439,440],{},"Internally the object is a \"diet\", which is what examination boards call a round of exams.",[11,442,443,444,447],{},"Every screen a school reads calls it an ",[41,445,446],{},"exam series",", because \"diet\" is a word that costs a bursar\nthirty seconds and teaches them nothing. The technical term survives in our code and nowhere a\ncustomer looks.",[18,449,451],{"id":450},"what-stayed-on-the-web","What stayed on the web",[11,453,454],{},"Generation, the module's settings, linking a CBT test, and cloning a series or building it a class at\na time are web-only, deliberately. They are the parts done sitting down, once, with a spreadsheet\nopen. Everything done standing up, in a corridor, in the week of the exams, is on the phone.",{"title":108,"searchDepth":109,"depth":109,"links":456},[457,458,459,460],{"id":321,"depth":112,"text":322},{"id":351,"depth":112,"text":352},{"id":369,"depth":112,"text":370},{"id":383,"depth":112,"text":384},"Operations","One person draws the exam grid, one paper moves, and the whole thing needs checking again by eye. Usually it is not. Here is the workspace that replaced the pencil.",{},"\u002Fblog\u002Fexams-workspace",{"title":310,"description":462},"blog\u002Fexams-workspace",[468,469,131],"exams","timetable","jFxF93HEcP_aRPykpnno8RN7mJtKB84r5Q-_-kMGy9o",1787681163376]