diff --git a/public/content/annotations/mel-kaye-bio/index.he.md b/public/content/annotations/mel-kaye-bio/index.he.md index b6231b45..6d393345 100644 --- a/public/content/annotations/mel-kaye-bio/index.he.md +++ b/public/content/annotations/mel-kaye-bio/index.he.md @@ -1 +1 @@ -מל קיי (מלוין קורניצקי, 2018-1931) נולד בברוקלין למשפחה יהודית ובילדותו עבר עם משפחתו ללוס אנג'לס. בקיץ 1956 הצטרף מל למחלקה המסחרית של ליברסקופ, חטיבה טכנולוגית בתוך ג׳נרל פרסישן, שהחזיקה בחוזים צבאיים וממשלתיים לבניית מיכשור צבאי. מל החל עבד במשרת מהנדס אפליקציות בקבוצת הפיתוח המסחרי בבניין 3 החדיש והמפואר באתר בנייני החברה בגלנדייל, קליפורניה, ובין היתר סייע בהדרכת לקוחות על ה-LGP-30. בתוך חודש מגיוסו, יחד עם רבים במחלקה המסחרית, הועבר לרויאל-מק׳בי, שותפה עסקית של ג׳נרל פרסישן שקידמה את ייצור, שיווק ומכירת ה-LGP-30. ברויאל-מק'בי כתב את תוכנת הבלאק ג׳ק שהפכה לתוכנת הדגל של החברה. עם השקת ה-RPC-4000, שיכתב מל את תוכנת הבלאק ג׳ק כדי להתאימה למחשב החדש, עבורו כתב גם את שפת הסף, ואף סייע לאד ניית׳ר בכתיבת מהדר פורטרן למחשב. לאחר חילוקי דעות עם הנהלת החברה עזב מל את רויאל-מק׳בי בתחילת שנות ה-60. השרידים שנותרו מעבודתו הם "הסיפור על מל", שני צילומי קטעי קוד בכתב יד, ומבוא פרי עטו לתוכנת הבלאק ג׳ק המשוכתבת. +**מל קיי** (מלוין קורניצקי, 2018-1931) נולד בברוקלין למשפחה יהודית ובילדותו עבר עם משפחתו ללוס אנג'לס. בקיץ 1956 הצטרף מל למחלקה המסחרית של ליברסקופ, חטיבה טכנולוגית בתוך ג׳נרל פרסישן, שהחזיקה בחוזים צבאיים וממשלתיים לבניית מיכשור צבאי. מל החל עבד במשרת מהנדס אפליקציות בקבוצת הפיתוח המסחרי בבניין 3 החדיש והמפואר באתר בנייני החברה בגלנדייל, קליפורניה, ובין היתר סייע בהדרכת לקוחות על ה-LGP-30. בתוך חודש מגיוסו, יחד עם רבים במחלקה המסחרית, הועבר לרויאל-מק׳בי, שותפה עסקית של ג׳נרל פרסישן שקידמה את ייצור, שיווק ומכירת ה-LGP-30. ברויאל-מק'בי כתב את תוכנת הבלאק ג׳ק שהפכה לתוכנת הדגל של החברה. עם השקת ה-RPC-4000, שיכתב מל את תוכנת הבלאק ג׳ק כדי להתאימה למחשב החדש, עבורו כתב גם את שפת הסף, ואף סייע לאד ניית׳ר בכתיבת מהדר פורטרן למחשב. לאחר חילוקי דעות עם הנהלת החברה עזב מל את רויאל-מק׳בי בתחילת שנות ה-60. השרידים שנותרו מעבודתו הם "הסיפור על מל", שני צילומי קטעי קוד בכתב יד, ומבוא פרי עטו לתוכנת הבלאק ג׳ק המשוכתבת. diff --git a/public/content/codex/index.he.md b/public/content/codex/index.he.md index 83268bc8..99e081c6 100644 --- a/public/content/codex/index.he.md +++ b/public/content/codex/index.he.md @@ -15,7 +15,7 @@ credits: "תרגם מאנגלית וביאר: תומר ליכטש | ייעוץ בירה לייט, מחשבוני כיס[^](annotations/calculators), ותוכנה "ידידותית-למשתמש"[^](annotations/user-friendly-quatations) אך בימים ההם[^](annotations/story-timeline-estimation), כשהמונח "תוכנה" עוד היה נשמע מצחיק, -ומחשבים אמיתיים[^](annotations/real-computers) נבנו ב[תופים](glossary/drum-memory) וב[שפופרות](glossary/vaccum-tube), +ומחשבים אמיתיים[^](annotations/real-computers) נבנו ב[תופים](glossary/drum-memory) וב[שפופרות](glossary/vacuum-tube), מתכנתים אמיתיים כתבו ב[שפת מכונה](glossary/assembly-language). לא [פוֹרְטְרַן](glossary/fortran). לא [ראטפוֹר](glossary/ratfor). אפילו לא [שפת סף](glossary/assembly-language). שפת מכונה. diff --git a/public/content/docs/blackjack-writeup/index.en.md b/public/content/docs/blackjack-writeup/index.en.md index 58573e01..bf89d140 100644 --- a/public/content/docs/blackjack-writeup/index.en.md +++ b/public/content/docs/blackjack-writeup/index.en.md @@ -2,6 +2,8 @@ title: "BLACKJACK GAME By Mel Kaye of Librascope Inc. RPC 4000 Program W1-01.0" author: Mel Kaye # date: "2020-01-02" +source_name: Mel's Writeup for the Blackjack Program +source_url: http://bitsavers.trailing-edge.com/pdf/royalPrecision/RPC-4000/programWriteups/W1-01.0_Blackjack_Game.pdf --- This program is designed to simulate a game of Blackjack between one player (the machine operator) and a dealer a dealer (the computer). This write-up is intended to provide the player with the information necessary to play the game. diff --git a/public/content/docs/blackjack-writeup/index.he.md b/public/content/docs/blackjack-writeup/index.he.md index 6d75e2eb..ffd92318 100644 --- a/public/content/docs/blackjack-writeup/index.he.md +++ b/public/content/docs/blackjack-writeup/index.he.md @@ -1,6 +1,8 @@ --- title: 'משחק בלאק ג׳ק מאת מל קיי מחברת ליברסקופ בע"מ, תוכנת RPC 4000 W1-01.0' author: מל קיי +source_name: Mel's Writeup for the Blackjack Program +source_url: http://bitsavers.trailing-edge.com/pdf/royalPrecision/RPC-4000/programWriteups/W1-01.0_Blackjack_Game.pdf --- תוכנה זו נועדה לדמות משחק בלאק ג׳ק בין שחקנ/ית אחד (מפעיל המחשב) לבין הדילר (המחשב). מסמך זה מבקש לספק לשחקנ/ית את המידע הדרוש כדי לשחק את המשחק. diff --git a/public/content/docs/preface/index.en.md b/public/content/docs/preface/index.en.md index 6721887a..60f184b6 100644 --- a/public/content/docs/preface/index.en.md +++ b/public/content/docs/preface/index.en.md @@ -1,13 +1,12 @@ --- -title: "Preface to The Story of Mel" +title: "A Software Legend That Really Happened" +abstract: "A Preface to The Story of Mel" author: "Tomer Lichtash" date: Wed Apr 7 2021 13:45 GMT+0300 --- <!--  --> -## Introduction - If this is your first encounter with _The Story of Mel_, odds are you will not understand it. There are numerous barriers along the way: Most of the technologies and programming languages featured in the story have either gone extinct, or were relegated to esoteric niches in the software universe; a general understanding of digital computing hardware is required, but this is no longer part of the curriculum of CS students; Familiarity with early computing history can help, but that period is mostly undocumented. Thus, reading _The Story of Mel_ is likely to be an uncomfortable experience, but even so, one can hardly miss the sense of elation out of which the words were born. It is clearly the result of a noble encounter between man, machine and language. The cathartic experience hinges on rather complex technical understanding, but it is clearly the "desired outcome" of reading a story. Therefore, when faced with the gap between the undeniable charm of this tale and your ability to understand the details that make it up, please remember: it is neither a story nor a poem, but rather an ancient post, an early net relic, conceived to impart some basic computing sense to the generation of reckless coders that sprung up in the early 80's. Since then, the story has been preserved across various network archives, hidden in broad daylight, visible to few and coherent to even fewer, until its present status as a computing myth. @@ -19,7 +18,7 @@ When Mel left the company, apparently due to an ongoing conflict of values, Ed w It's almost too easy to to view this story as a classic "good vs evil" conflict: a lone "genius" standing his ground against the "evil corporation", or a technological knight deflecting the moral depravity of the rising big business. However, it is also a story about collegial respect, shifting perspectives and the precedental mental encounter between first generation computers and coders. Beyond these perspectives, the story showcases the budding tension between mamangement and marketing on the one hand, and software engineers on the other. This atmosphere of plots, deviance and often stupidity is reminiscent of comics strips like xkcd and Dilbert that capture the awkward encounters between bureaucracy and technology. -## The Story of Mel and Hacker Folklore +## Hacker Folklore _The Story of Mel_ is an epic text in hacking folklore, an unofficial genre which includes an eclectic and rather substantial collection of relics from the early digital sphere; This period spans the first three decades of the computer era, from the first machines to the commercial production of personal computers and the birth of the global network (~1950-1983). Hacking folklore stories are anecdotal tales, written and published in what was then a budding ultra modern medium; they document various events and cases from the forefront of the computing revolution; they often showcase conflicts between the values of individuals, systems and the latest arrival to the global stage - the computer. Most importantly - they sometimes capture moments in which the border between logic and magic blurs away. @@ -37,4 +36,4 @@ The translation of _The Story of Mel_ required a significant effort on my part, ## Thanks -I'm grateful to David Frenkiel, my partner in this project. Ten years ago, he (virtually) handed me a copy of the story, with a simple and assertive demand: "read". His contribution to deciphering archaic code and obsolete technology, as well as understanding the spirit of the "real programmer", enlightened me time and again both as a reader and as a translator of this epic. +I'm grateful to **David Frenkiel**, my partner in this project. Ten years ago, he (virtually) handed me a copy of the story, with a simple and assertive demand: "read". His contribution to deciphering archaic code and obsolete technology, as well as understanding the spirit of the "real programmer", enlightened me time and again both as a reader and as a translator of this epic. diff --git a/public/content/docs/preface/index.he.md b/public/content/docs/preface/index.he.md index fe217628..4a8c2f4c 100644 --- a/public/content/docs/preface/index.he.md +++ b/public/content/docs/preface/index.he.md @@ -1,29 +1,36 @@ --- -title: "מבוא" +title: "על אגדת תוכנה שקרתה באמת" +abstract: "מבוא לסיפור על מל" author: "תומר ליכטש" -date: "2021" +date: Wed Apr 7 2021 13:45 GMT+0300 --- סביר להניח כי רבים מקוראי _הסיפור על מֵל_ לא יבינו אותו. המכשלות רבות: הטכנולוגיות ושפות התכנות המתוארות בו כבר חלפו מן העולם, וממילא להבנת הסיפור נדרשת היכרות עם מבנה המחשב, עם שפות ושיטות תכנות ועם ההיסטוריה של ראשית עידן המחשב, אשר עדיין, ברובה, בלתי מתועדת. בנסיבות כאלה, כאמור, יש לשער שקריאה בסיפור הזה עשויה לעורר תחושה של אי נחת ביחס לידע שהכותב מניח אצל קוראיו. ובכל זאת, הוא נולד מתוך התרוממות רוח גדולה לנוכח זיכרון ישן של נוכחות אצילה במפגש בין אדם, שפה ומכונה. התרוממות רוח מעין זו, על אף תלותה בידע טכני מורכב, היא ״התוצאה הרצויה״ בקריאת הסיפור. על כן, לכשתתעורר אי נחת כזו לנוכח התהום הפעורה בין סיפור האגדה שלפנינו לבין יכולתנו, כקוראים מן השורה, להבין את הדברים האמורים בה – ראוי לזכור שזהו לא שיר ולא סיפור, אלא פוסט ישן נושן, שריד רשת מוקדם, שנולד כדי להרביץ תורה בדור הפחזות הטכנולוגית המתעורר בשנות ה-80. עם השנים נשתמר הסיפור ברשת, חבוי באור היום, נגלה למעטים, עד שהפך לאגדת רשת עלומה. -הסיפור מתאר מפגש בין שני מתכנתים צעירים: המחבר אד ניית׳ר, ומל, בסוף שנות ה-50 בלוס אנג׳לס, בחברה שייצרה מחשב אלקטרוני מדור ראשון. במרכז הסיפור נמצא משחק בלאק ג׳ק שמל תיכנת לפני כ-60 שנים. המשחק הפך במהירות להצלחה גדולה, שימש כתוכנת הדגל של החברה, גרר תשואות בהדגמות פומביות בתערוכות מחשבים ואף הביא סטודנטים למדעי המחשב לערוך אירועים של משחקי קלפים דיגיטליים בחדרי המחשבים של.MIT כאשר מל עזב את החברה על רקע משבר ערכי מתמשך, אד נאלץ לצלול אל נבכי הקוד של משחק הבלאק ג׳ק על מנת לבצע שינוי קטן שדרשה מחלקת השיווק, ונשאב אגב כך אל מסע בלשי המבקש לגלות איזו תמונה בהירה בתוך הקוד של מל, אך מוצא במקומה קוד מבוכי שבמרכזו לולאה אינסופית חסרת פשר, שלא עושה דבר. אט אט נאלץ אד לשנות את נקודת מבטו, עד שהתגלה לפניו הקסם. ״כשראיתי את האור״, יכתוב 30 שנים מאוחר יותר, ״כמעט הסתנוורתי״. +## הסיפור + +הסיפור מתאר מפגש בין שני מתכנתים צעירים: המחבר **אד ניית׳ר**, ומל, בסוף שנות ה-50 בלוס אנג׳לס, בחברה שייצרה מחשב אלקטרוני מדור ראשון. במרכז הסיפור נמצא משחק בלאק ג׳ק שמל תיכנת לפני כ-60 שנים. המשחק הפך במהירות להצלחה גדולה, שימש כתוכנת הדגל של החברה, גרר תשואות בהדגמות פומביות בתערוכות מחשבים ואף הביא סטודנטים למדעי המחשב לערוך אירועים של משחקי קלפים דיגיטליים בחדרי המחשבים של.MIT כאשר מל עזב את החברה על רקע משבר ערכי מתמשך, אד נאלץ לצלול אל נבכי הקוד של משחק הבלאק ג׳ק על מנת לבצע שינוי קטן שדרשה מחלקת השיווק, ונשאב אגב כך אל מסע בלשי המבקש לגלות איזו תמונה בהירה בתוך הקוד של מל, אך מוצא במקומה קוד מבוכי שבמרכזו לולאה אינסופית חסרת פשר, שלא עושה דבר. אט אט נאלץ אד לשנות את נקודת מבטו, עד שהתגלה לפניו הקסם. ״כשראיתי את האור״, יכתוב 30 שנים מאוחר יותר, ״כמעט הסתנוורתי״. קל (מדי) לחשוב על הסיפור הזה כעל סיפור בין מתרסים, ״הטובים נגד הרעים״, ״גאון״ העומד לבדו מול ״תאגיד מרושע״, או אביר הטכנולוגיה הדוחה כל ניסיון להשחתה מוסרית אל מול טחנת הרוח האיתנה של גל הביג ביזנס המתעורר. עם זאת, זהו סיפור על הערכה קולגיאלית, על שינוי פרספקטיבה, על המפגש המנטלי בין מחשב לאדם, שניהם בני דור ראשון מסוגם, שניהם חסרי תקדים. מעבר לכך, בסיפור הזה מתקיים המתח הבסיסי של תככים ומזימות בין מנהלים, אנשי מכירות ואנשי תוכנה; משהו שמזכיר ברוחו קומיקס כמו XKCD אוDilbert , העוסקים ברגעי הנאיביות, ולעיתים אף הטיפשות היזומה, המתעוררים במסגרות ביורוקרטיות תחת מעטה של קידמה טכנולוגית מואצת. +## פולקלור האקינג + _הסיפור על מל_ הוא טקסט אפי בפולקלור ההאקינג, סוגה לא רשמית הכוללת מבחר אקלקטי ולא מבוטל של שרידים מהמרחב הדיגיטלי המוקדם, קרי שלושת העשורים הראשונים מראשית עידן המחשב ועד לייצור ולשיווק מסחרי של מחשב אישי ולידתה של הרשת בת זמננו (1950-1983~). סיפורי פולקלור האקינג הם סיפורי מעשייה אנקדוטליים שנכתבו ופורסמו במדיום דיגיטלי חדיש ומתעורר (דאז) המתעדים אירועים ומקרים שונים מחזית מהפכת המחשוב, בהם קונפליקטים ערכיים, הומניים, כלכליים ואחרים, בין אינדיבידואלים, מערכות והדמות החדשה על במת העולם – המחשב. הטקסטים האלה נכתבו ברובם בידי אנשי תוכנה במוסדות אקדמיים וממשלתיים, והם מתארים רגעים שבהם מיטשטש הגבול בין לוגיקה וקסם. במסגרת הזו, _הסיפור על מל_ הוא הטקסט הנרחב ביותר שנשתמר, ובו מפורט רגע בריאת ההייטק, תקופה שכמעט אין לה תיעוד או שריד, ושממנה התפתחה באופן ישיר התרבות הדיגיטלית בת זמננו. המתח הבסיסי המתואר בסיפור אולי התעצב לאורך השנים, אך מהותו נשמרה – בין טהרנות של כותב תוכנה, המדבר את שפת המכונה ולפיכך מייצג אותה, לבין עולם עסקי מתפתח, המעודד חופש מחשבתי ופריצת דרך מחד, ומאידך מעמיד דרישה בלתי מתפשרת לתקתוק קצבי של גחמותיו עד לשביעות רצונו הבלעדית; זהו סיפור של מאבק על סגנון, ועל הלגיטימיות של סגנון עצמאי, המבקש לפרוץ את גבולות השפה ואת הנורמות המקובלות, מתוך הכרה באפשרות החדשה, ובחתירה לשלמות פנימית, כפי שהוא רואה לנכון. הסיפור הזה מעמיד דלת לעולם ישן ומיושן שבו חושל, ביט אחר ביט, עולמנו אנו. ככל שנוקפות השנים תופס הקיום הממוחשב עוד ועוד חלקים בחיינו; הפרספקטיבה האצורה ב״סיפור על מל״ שייכת לעולם שבו מתעורר לראשונה הקשר בין החיים עצמם לבין המחשב, באופן ספונטני, לא מבוקר, חד כמו ברק, וכמוהו גם רגעי, מסנוור ונעלם, ומותיר אחריו רעם מתמשך המרעיד את אדוות התקיימותנו הדיגיטלית עד היום. --- +## מחקר ותרגום -במהלך העבודה על תרגום הסיפור חזרתי שוב ושוב לשאלות רבות שנותרו ללא מענה ולתדהמתי נדמה שאפילו לא נשאלו קודם לכן: מתי בדיוק התרחש הסיפור? היכן? מה קרה אחרי? מה קרה לפני? ושאלת השאלות – איפה מל, והאם קרא את הסיפור? כמו כן, על אף שלימים התברר כי שמו המלא הוא מל קיי, לא נודע דבר נוסף על אודותיו. שאלות בלתי פתורות אלה והמסתורין סביב דמותו של מל גררו אותי למחקר נוסף. +במהלך העבודה על תרגום הסיפור חזרתי שוב ושוב לשאלות רבות שנותרו ללא מענה ולתדהמתי נדמה שאפילו לא נשאלו קודם לכן: מתי בדיוק התרחש הסיפור? היכן? מה קרה אחרי? מה קרה לפני? ושאלת השאלות – איפה מל, והאם קרא את הסיפור? כמו כן, על אף שלימים התברר כי שמו המלא הוא **מל קיי**, לא נודע דבר נוסף על אודותיו. שאלות בלתי פתורות אלה והמסתורין סביב דמותו של מל גררו אותי למחקר נוסף. -אחד הפרטים המשמעותיים שביקשתי להבהיר (תחילה לעצמי) הוא אמיתות הסיפור ואמיתות זהותו של מל. כיום אני משוכנע במאת האחוזים שזהו לא משל ולא צ׳יזבט אלא תיעוד נאמן, ומל – שנולד בשם מלוין קורניצקי (1931-2018), אכן היה חי וקיים. מל נולד למשפחה יהודית בברוקלין, בילדותו עבר עם משפחתו לקליפורניה ובמהלך חייו שינה את שמו פעמיים (מלוין קורניצקי > מלוין קיי > מל קיי), אולי על מנת להצניע את יהדותו מטעמיו שלו, ואולי כדי שיוכל, כמו כוכב של ממש, להבריק בשמי סצנת הטכנולוגיה של החוף המערבי, ולהיעלם. במסע בלשי משל עצמי חקרתי את עקבותיו המטושטשים של מל והעליתי בחכתי סיפורים רבים הקשורים, בדרגה כזו או אחרת, לרשת האירועים הכללית. +אחד הפרטים המשמעותיים שביקשתי להבהיר (תחילה לעצמי) הוא אמיתות הסיפור ואמיתות זהותו של מל. כיום אני משוכנע במאת האחוזים שזהו לא משל ולא צ׳יזבט אלא תיעוד נאמן, ומל – שנולד בשם **מלוין קורניצקי** (1931-2018), אכן היה חי וקיים. מל נולד למשפחה יהודית בברוקלין, בילדותו עבר עם משפחתו לקליפורניה ובמהלך חייו שינה את שמו פעמיים (מלוין קורניצקי > מלוין קיי > מל קיי), אולי על מנת להצניע את יהדותו מטעמיו שלו, ואולי כדי שיוכל, כמו כוכב של ממש, להבריק בשמי סצנת הטכנולוגיה של החוף המערבי, ולהיעלם. במסע בלשי משל עצמי חקרתי את עקבותיו המטושטשים של מל והעליתי בחכתי סיפורים רבים הקשורים, בדרגה כזו או אחרת, לרשת האירועים הכללית. -דווקא סיפורו הלא מסופר של מל ריתק וסיקרן אותי – הנה מתכנת חסר תקדים, טכנולוג ״פרהיסטורי״ בעל אינטואיציה של רב-מאג, אינטואיטיבי וחד, שפיתח שפה ובא בה לידי ביטוי אבסורדי ומבריק, המתרחש בקוד, מבעד לפעולת מכונה. מרגע שהחלקים הפועלים מתבהרים אי אפשר להכחיש את ערכו האסתטי של ברק זה. עולם ראשית המחשוב הוא עולם מרתק ונעלם, אך קצרה יריעתה של הקדמה זו. לשם כך יצרתי והעליתי לרשת את פרויקט ״לולאת מל״ (melsloop.com) לתיעוד והנגשת ההיסטוריה מאחורי האפוס, ביאור העובדות מאחורי הקסם וחקר עולמו הפרהיסטורי־דיגיטלי של מל. +דווקא סיפורו הלא מסופר של מל ריתק וסיקרן אותי – הנה מתכנת חסר תקדים, טכנולוג ״פרהיסטורי״ בעל אינטואיציה של רב-מאג, אינטואיטיבי וחד, שפיתח שפה ובא בה לידי ביטוי אבסורדי ומבריק, המתרחש בקוד, מבעד לפעולת מכונה. מרגע שהחלקים הפועלים מתבהרים אי אפשר להכחיש את ערכו האסתטי של ברק זה. עולם ראשית המחשוב הוא עולם מרתק ונעלם, אך קצרה יריעתה של הקדמה זו. לשם כך יצרתי והעליתי לרשת את פרויקט [״לולאת מל״](melsloop.com) לתיעוד והנגשת ההיסטוריה מאחורי האפוס, ביאור העובדות מאחורי הקסם וחקר עולמו הפרהיסטורי־דיגיטלי של מל. במהלך תרגום הסיפור נדרשתי למאמץ רב כדי להשלים פערי ידע היסטוריים וטכנולוגיים, שכלל נבירה בארכיונים, ראיונות, אימות עובדות וקריאת מדריכי מחשבים ישנים. לכן גם צירפתי ביאורים בגוף הטקסט, על מנת להקל את קריאת הסיפור ואת הבנתו. עם הבאת תרגום הסיפור לדפוס, כולי תקווה שהוא ישמש כדלת כניסה לפולקלור ההאקינג גם עבור קוראי העברית הלא טכנולוגיים. עד כה, מעולם לא נדון הסיפור בהקשר ספרותי. פרסומו בכתב עת לספרות הוא צעד חסר תקדים בהיסטוריה של הסיפור. -תודה גדולה לדוד פרנקל, שותפי לתרגום הסיפור ולפרויקט ״לולאת מל״, שלפני כעשור הניח בידי את הסיפור וציווה: ״קרא!״. בתרומתו לפענוח הטכנולוגיות ושפות התכנות העתיקות, והבנת רוח ״המתכנת האמיתי״, האיר דוד את עיניי שוב ושוב, הן כקורא והן כמתרגם, ואיפשר לאפוס הזה, על חלקיו המאובקים ביותר, לבוא לידי תרגום ולהיפרש לפניי כאגדה שהייתה באמת, אגדה על מתכנת אמיתי. +## תודות + +תודה גדולה ל**דוד פרנקל**, שותפי לתרגום הסיפור ולפרויקט ״לולאת מל״, שלפני כעשור הניח בידי את הסיפור וציווה: ״קרא!״. בתרומתו לפענוח הטכנולוגיות ושפות התכנות העתיקות, והבנת רוח ״המתכנת האמיתי״, האיר דוד את עיניי שוב ושוב, הן כקורא והן כמתרגם, ואיפשר לאפוס הזה, על חלקיו המאובקים ביותר, לבוא לידי תרגום ולהיפרש לפניי כאגדה שהייתה באמת, אגדה על מתכנת אמיתי. diff --git a/public/content/docs/resources/index.en.md b/public/content/docs/resources/index.en.md index 6b2c3f4e..e4ff92d7 100644 --- a/public/content/docs/resources/index.en.md +++ b/public/content/docs/resources/index.en.md @@ -4,7 +4,8 @@ title: "Resources" ### Story Source -- [Jargon File](http://www.catb.org/jargon/) +- [The Story in the Jargon File](http://www.catb.org/jargon/html/story-of-mel.html) +- [The Story of Mel in Wikipedia](https://en.wikipedia.org/wiki/The_Story_of_Mel) ### Guides and References @@ -17,7 +18,6 @@ title: "Resources" ### Archives - [Librascope Memories](https://librascopememories.blogspot.com/) -- [The Old Clculator Museum](https://www.oldcalculatormuseum.com/index.html]) - [Vintage Computing](http://www.e-basteln.de/computing/) ### Mel @@ -37,30 +37,22 @@ title: "Resources" - [RPC-4000 Manuals, Code Samples and Other Documents Archive](http://www.bitsavers.org/pdf/royalPrecision/RPC-4000/) -### Wikipedia - -- [The Story of Mel](https://en.wikipedia.org/wiki/The_Story_of_Mel) -- [Royal McBee](https://en.wikipedia.org/wiki/Royal_Typewriter_Company#Computers) -- [Real Programmers Don't Use Pascal](https://en.wikipedia.org/wiki/Real_Programmers_Don%27t_Use_Pascal) -- [Librascope](https://en.wikipedia.org/wiki/Librascope) - ### Other - [Vacuum Tube Blackjack](https://twitter.com/ewbarnard/status/1034892590003482626?ref_src=twsrc%5Etfw) - - [Less Is More in the Fifties: Encounters between Logical Minimalism and Computer Design during the 1950s](https://hal.univ-lille.fr/hal-01345592v3/document) - - [Awesome Computer History](https://github.com/watson/awesome-computer-history) +<!-- TODO: Sort and Edit --> <!--- Global resources ---> - -[ycombinator discussion]: https://news.ycombinator.com/item?id=20489273 - -### Online resources - -- [YCombinator discussion] claiming that the hack was pefromed on the LGP-30 emulator -- A detailed attempt by David Nugent to [reconstruct] the hack, based on real rpc-4000 data - +<!-- [ycombinator discussion]: https://news.ycombinator.com/item?id=20489273 --> +<!-- ### Online resources --> +<!-- - [YCombinator discussion] claiming that the hack was pefromed on the LGP-30 emulator --> +<!-- - A detailed attempt by David Nugent to [reconstruct] the hack, based on real rpc-4000 data --> <!-- ### Discussions --> - <!-- - [YCombinator discussion] --> +<!-- ### Wikipedia --> +<!-- - [Royal McBee](https://en.wikipedia.org/wiki/Royal_Typewriter_Company#Computers) --> +<!-- - [Real Programmers Don't Use Pascal](https://en.wikipedia.org/wiki/Real_Programmers_Don%27t_Use_Pascal) --> +<!-- - [Librascope](https://en.wikipedia.org/wiki/Librascope) --> +<!-- - [The Old Clculator Museum](https://www.oldcalculatormuseum.com/index.html]) --> diff --git a/public/content/docs/resources/index.he.md b/public/content/docs/resources/index.he.md index 4d40be2f..27845114 100644 --- a/public/content/docs/resources/index.he.md +++ b/public/content/docs/resources/index.he.md @@ -2,4 +2,57 @@ title: "מקורות" --- -TBA +### מקור הסיפור + +- [הסיפור על מל בקובץ הז׳רגון](http://www.catb.org/jargon/html/story-of-mel.html) +- [הסיפור בוויקיפדיה](https://en.wikipedia.org/wiki/The_Story_of_Mel) + +### מדריכים, הסברים וניתוחים + +- [הסיפור על מל עם הסברים / ג׳יימס סייבל](https://jamesseibel.com/the-story-of-mel/) +- [הסיפור על מל - מתכנת אמיתי, מהדורה מוערת / אריק ברונוונד](https://www.cs.utah.edu/~elb/folklore/mel-annotated/mel-annotated.html) +- [מתכנתים מאצ׳ואיסטים, תופי זיכרון וניתוח פורנזי של קוד מכונה מ-1960](https://www.freecodecamp.org/news/macho-programmers-drum-memory-and-a-forensic-analysis-of-1960s-machine-code-6c5da6a40244/) +- [עידן התוכנה השני - הברזל הגדול](https://hackernoon.com/https-medium-com-it-explained-for-normal-people-big-iron-6aee4e32ed51) +- [שפופרת זמן: מל, בלאקג׳ק, וה-LGP-30](http://tubetime.us/index.php/2014/06/14/mel-blackjack-and-the-lgp-30/) + +### Archives + +- [ארכיון ליברסקופ](https://librascopememories.blogspot.com/) +- [ארכיון מחשבי וינטג׳](http://www.e-basteln.de/computing/) + +### Mel + +- [משחק בלאק ג׳ק מאת מל קיי מחברת ליברסקופ בע"מ, תוכנת RPC 4000 W1-01.0](http://bitsavers.trailing-edge.com/pdf/royalPrecision/RPC-4000/programWriteups/W1-01.0_Blackjack_Game.pdf) +- [צילומים של דפי קוד מאת מל קיי](https://www.bemorehealthy.com/LGP-30Computer/The30.htm) +- [ביל פול הייגן - רפרנסים למל](http://foldoc.org/pub/misc/MelKaye.txt) + +### LGP-30 + +- [מדריכים למחשב ה-LGP-30](http://www.bitsavers.org/pdf/royalPrecision/LGP-30/) +- [LGP-30 - ספר הוראות](http://ed-thelen.org/comp-hist/lgp-30-man.html) +- [קטע תוכנה בשפת ACT III עבור ה-LGP-30](https://theworld.com/~reinhold/comp-hist/actiiisample.html) +- [ה-LGP-30 במוזיאון הטכניקום](https://technikum29.de/en/computer/lgp30) + +### RPC-4000 + +- [ארכיון מדריכים, דוגמאות קוד ומסמכים אחרים ל-RPC-4000](http://www.bitsavers.org/pdf/royalPrecision/RPC-4000/) + +### Other + +- [ואקום ובלאקג׳ק - שרשור טוויטר מאת אד ברנארד](https://twitter.com/ewbarnard/status/1034892590003482626) +- [פחות זה יותר בשנות החמישים: מפגשים בין לוגיקה מינימליסטית ועיצוב מחשבים במהלך שנות החמישים](https://hal.univ-lille.fr/hal-01345592v3/document) +- [ארכיון היסטוריה של מחשבים](https://github.com/watson/awesome-computer-history) + +<!-- TODO: Sort and Edit --> +<!--- Global resources ---> +<!-- [ycombinator discussion]: https://news.ycombinator.com/item?id=20489273 --> +<!-- ### Online resources --> +<!-- - [YCombinator discussion] claiming that the hack was pefromed on the LGP-30 emulator --> +<!-- - A detailed attempt by David Nugent to [reconstruct] the hack, based on real rpc-4000 data --> +<!-- ### Discussions --> +<!-- - [YCombinator discussion] --> +<!-- ### Wikipedia --> +<!-- - [Royal McBee](https://en.wikipedia.org/wiki/Royal_Typewriter_Company#Computers) --> +<!-- - [Real Programmers Don't Use Pascal](https://en.wikipedia.org/wiki/Real_Programmers_Don%27t_Use_Pascal) --> +<!-- - [Librascope](https://en.wikipedia.org/wiki/Librascope) --> +<!-- - [The Old Clculator Museum](https://www.oldcalculatormuseum.com/index.html]) --> diff --git a/public/content/posts/07-04-21-hebrew-edition/index.en.md b/public/content/posts/07-04-21-hebrew-edition/index.en.md index c2d1286c..38208d3f 100644 --- a/public/content/posts/07-04-21-hebrew-edition/index.en.md +++ b/public/content/posts/07-04-21-hebrew-edition/index.en.md @@ -1,18 +1,17 @@ --- -title: Hebrew Edition is Here +title: New Website Launch author: Tomer Lichtash date: Wed Apr 7 2021 13:45 GMT+0300 -cover: https://res.cloudinary.com/dcajl1s6a/image/upload/c_scale,w_786/v1646486680/mels-loop/9f8e9214adaaa4b57b29_yx777b.jpg --- - - -We're happy to announce the first publication of The Story of Mel in Hebrew. + +_The Story of Mel Hebrew Translation first fold, published in Dehak Literary Periodical_ -The publication sees first light within the 13th volume of the literary periodical [Dehak](https://mitzlolpoetry.wixsite.com/dehak/13). +-- -This is the first time the story sees light within an actual literary platform, as a piece of actual folklore. +We're happy to announce the first publication of The Story of Mel in Hebrew. The publication sees first light within the 13th volume of the literary periodical [Dehak](https://mitzlolpoetry.wixsite.com/dehak/13). This is the first time the story sees light within an actual literary platform, as a piece of actual folklore. -Along with the translation we've added an introductory preface, and 50-some sidenotes, to ease the read for the non-tech reader. +Along with the translation we've added an introductory preface, and 50-some sidenotes, to ease the read for the non-tech reader. Full text, with preface and comments will soon be published on Mel's Loop website. -Full text, with preface and comments will soon be published on Mel's Loop website. + +_Dehak Literary Periodical #13 cover_ diff --git a/public/content/posts/07-04-21-hebrew-edition/index.he.md b/public/content/posts/07-04-21-hebrew-edition/index.he.md index fea4f5c9..31b1cbec 100644 --- a/public/content/posts/07-04-21-hebrew-edition/index.he.md +++ b/public/content/posts/07-04-21-hebrew-edition/index.he.md @@ -2,9 +2,13 @@ title: גרסה בעברית לסיפור על מל author: תומר ליכטש date: Wed Apr 7 2021 13:45 GMT+0300 -cover: https://res.cloudinary.com/dcajl1s6a/image/upload/c_scale,w_786/v1646486680/mels-loop/9f8e9214adaaa4b57b29_yx777b.jpg --- - + + +אנו שמחים להודיע על פירסום ספרותי ראשון לתרגום לעברית של ״הסיפור על מל״ בגליון 13 החגיגי לכתב העת ״דחק״ בעריכת יהודה ויזן. זהו הפירסום הראשון של הסיפור במסגרת ספרותית, ואנו מברכים על מבט חדש זה אל עבר הסיפור, המבשר מבט ביקורתי ואסתטי אל עבר ז׳אנר ההאקינג פולקלור כולו. -TBD +לצד התרגום הוספנו כ-50 הערות שוליים המבארות את הסיפור על חלקיו הטכניים וההיסטוריים השונים, לצד [מאמר מבוא, המצורף כאן באתר במלואו](/he/docs/preface). + + +_כריכת כתב העת ״דחק״ #13_ diff --git a/public/content/posts/14-01-21-project-launch/index.en.md b/public/content/posts/14-01-21-here-we-go/index.en.md similarity index 96% rename from public/content/posts/14-01-21-project-launch/index.en.md rename to public/content/posts/14-01-21-here-we-go/index.en.md index 8e1c61c0..ccc7b16e 100644 --- a/public/content/posts/14-01-21-project-launch/index.en.md +++ b/public/content/posts/14-01-21-here-we-go/index.en.md @@ -1,5 +1,5 @@ --- -title: Project Launch +title: Here We Go! author: Tomer Lichtash date: Thu Jan 14 2021 12:30:00 GMT+0300 --- diff --git a/public/content/posts/14-01-21-here-we-go/index.he.md b/public/content/posts/14-01-21-here-we-go/index.he.md new file mode 100644 index 00000000..32632a6f --- /dev/null +++ b/public/content/posts/14-01-21-here-we-go/index.he.md @@ -0,0 +1,9 @@ +--- +title: יוצאים לדרך +author: תומר ליכטש +date: Thu Jan 14 2021 12:30:00 GMT+0300 +--- + +אנו משיקים היום את תחילת הדרך של פרויקט ״לולאת מל״, בציון יום הולדתו ה-90 של מל קיי, **מתכנת אמיתי**, שהלך לעולמו לפני כשלוש שנים. סיפורו של מל עוד חי כאפוס הגדול של פולקלור ההאקינג משנות השמונים, וממשיך איתנו עד היום, כאשר גילו הוא כגילו של האינטרנט. + +מטרת הפרויקט היא לצלול אל ימי ראשית המיחשוב בקליפורניה, למקום בו התרחש הסיפור על מל, ולעקוב אחר הדמויות, האירועים וטכנולוגיות שיצרו את הסיפור הזה, בעידן של פיתוח תוכנה ללא חוקים, בה תוכנה חושלה בגחמות של שקדנות וגאונות. diff --git a/public/content/posts/14-01-21-project-launch/index.he.md b/public/content/posts/14-01-21-project-launch/index.he.md deleted file mode 100644 index c81bf4fd..00000000 --- a/public/content/posts/14-01-21-project-launch/index.he.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: יוצאים לדרך -author: תומר ליכטש -date: Thu Jan 14 2021 12:30:00 GMT+0300 ---- - -TBD diff --git a/public/content/posts/21-05-22-project-launch/index.en.md b/public/content/posts/21-05-22-project-launch/index.en.md new file mode 100644 index 00000000..3b5bcf93 --- /dev/null +++ b/public/content/posts/21-05-22-project-launch/index.en.md @@ -0,0 +1,28 @@ +--- +title: New Website Launch +author: Tomer Lichtash +date: Wed May 21 2021 12:0 GMT+0300 +--- + +**TL;DR: 39 years ago The Story of Mel was published on Usenet by its author. Today, we launch the Mel’s Loop project, with some fascinating details about the epic hacker folklore tale. +** + + + +Today we celebrate the 39th anniversary of the first publication of The Story of Mel by **Ed Nather**. The Story of Mel was written as a memoir about the era of early computing of the late 1950s, creating a fresh memory of the days when Hackership was first forged. It continued to live through the years as an epic hacker folklore. + +Little is known about the origins of The Story of Mel, its characters, and technical aspects. Over the past few years, we've spent a lot of time researching the story. We interviewed people who were related to it, and discovered some interesting details about the life and origins of Mel, Ed, and their stories, as well as the company where it all happened, and developed a deep perspective of Mel’s famous hack. + +To celebrate this research, we launch today a new project: [Mel’s Loop](https://melsloop.com), which includes an annotated version of the story, along with articles and other materials that are soon to be added to this web companion – related to The Story of Mel, and to the Hacker Folklore genre in general. + +During the research we were privileged to publish the translation of The Story of Mel into Hebrew, in an actual literary publication of a print literary periodical, last year. The Hebrew translation, together with Hebrew and English annotations, are now available on the Mel’s Loop website. I believe this is the first translation of the story, and hope the project will attract more translators of other languages. + +Here’s a short excerpt from the initial biography entry for Mel Kaye (or as I later found out, Melvin Kornitzky, may he rest in peace) as it appears in annotation next to Mel’s name, on the project’s website: + +> **Mel Kaye** (**Melvin Kornitzky**, 1931-2018) was born in Brooklyn to a family of Jewish immigrants. During his childhood, the family moved to Los Angeles. In the Summer of 1956, Mel joined the commercial department of _Librascope_, a technology division within General Precision, which held government and army contracts. Mel worked as an Application Engineer in the Commercial Development department at the company's new and fancy Building 3 in Glendale, California. He also provided support to the company's clients on the LGP-30. Within a month from his hiring date, Mel was transferred, along with a few other engineers, to Royal-McBee, a business partner of General Precision that had taken the task of marketing and selling the LGP-30. During his time in Royal-McBee, Mel wrote a Blackjack game that ran on the LGP-30, which soon became the flagship demo program for the new machine and was widely used by the company. + +> When the RPC-4000 was launched, Mel re-wrote (or 'ported') the Blackjack program to be compatible with the RPC-4000, for which he also wrote parts of the Assembly. As we know from The Story of Mel, Mel also helped **Ed Nather** with the task of writing a Fortran Compiler to that machine. Due to some differences of opinion with the company's management, Mel left Royal-McBee in the early 1960s. Some relics remained of his work, including a few hand-written code sheets and a usage guide to the Blackjack program for the RPC-4000. + +-- + +_Cover Photo: Left to right – Portraits of young **Mel Kaye** and **Ed Nather**, circa 1959. Illusration by **Nir Yaniv**, made according to photos and materials provided by Mel's Loop project._ diff --git a/public/content/posts/21-05-22-project-launch/index.he.md b/public/content/posts/21-05-22-project-launch/index.he.md new file mode 100644 index 00000000..7fb20fe4 --- /dev/null +++ b/public/content/posts/21-05-22-project-launch/index.he.md @@ -0,0 +1,25 @@ +--- +title: השקת אתר חדש +author: תומר ליכטש +date: Wed May 21 2021 12:0 GMT+0300 +--- + + + +**אמ;לק: לפני 39 שנים פורסם ב-Usenet "הסיפור על מל". היום אנחנו משיקים את הפרויקט "לולאת מל", הכולל פרטים מרתקים על הסיפור שהפך עם הזמן לטקסט אפי בפולקלור ההאקינג.** + +אנחנו חוגגים היום את יום השנה ה-39 לפעם הראשונה שבה פורסם "הסיפור על מל" של **אד נייתר**. הסיפור על מל נכתב כסיפור על תולדות עידן המחשוב, מסוף שנות ה-50, ויצר זיכרון טרי מהימים שבהם ההאקינג התהווה. לאורך השנים, הסיפור המשיך להתקיים כאפוס בפולקלור ההאקינג. + +מידע מועט ידוע על על ״הסיפור על מל״, על הדמויות שבו או ההיבטים הטכניים שלו. בשנים האחרונות עסקנו בחקר הסיפור, ראיינו אנשים שהיו קשורים אליו, וגילינו פרטים מעניינים על החיים והשורשים של מל, אד והסיפורים שלהם, וגם על החברה שבה הסיפור התרחש, וכך גם התפתחה אצלנו הבנה עמוקה של ההאק המפורסם של מל. + +לציון המחקר שלנו, אנחנו משיקים היום את האתר החדש של פרויקט [״לולאת מל״](https://melsloop.com), הכולל גרסה מוערת של הסיפור, לצד מאמרים וחומרים אחרים שבקרוב נוסיף לאתר – כאלה שקשורים לסיפור על מל ולסוגה של פולקלור ההאקינג בכלל. + +במסגרת המחקר היה לנו הכבוד לפרסם בשנה שעברה את התרגום של הסיפור על מל לעברית, בגיליון פיזי מודפס של כתב עת ספרותי. התרגום לעברית, לצד ההערות בעברית ובאנגלית, זמינים עכשיו באתר "לולאת מל". זהו התרגום הראשון של הסיפור, ואנו תקווה שהפרויקט ימשוך עוד תרגומים, לשפות נוספות. + +הנה קטע קצר מתוך הערך הביוגרפי של מל קיי (או, מתברר, מלוין קורניצקי, ז"ל), כפי שהוא מופיע בהערה לצד שמו של מל בגוף הסיפור באתר הפרויקט: + +> **מל קיי** (מלוין קורניצקי, 2018-1931) נולד בברוקלין למשפחה יהודית ובילדותו עבר עם משפחתו ללוס אנג'לס. בקיץ 1956 הצטרף למחלקה המסחרית של ליברסקופ, חטיבה טכנולוגית בתוך ג׳נרל פרסישן, שהחזיקה בחוזים צבאיים וממשלתיים לבניית מיכשור צבאי. מל עבד כמהנדס אפליקציות בקבוצת הפיתוח המסחרי בבניין 3 החדיש והמפואר באתר בנייני החברה בגלנדייל, קליפורניה, ובין היתר סייע בהדרכת לקוחות על ה-LGP-30. בתוך חודש מגיוסו, יחד עם רבים במחלקה המסחרית, הועבר לרויאל-מק׳בי, שותפה עסקית של ג׳נרל פרסישן שקידמה את הייצור, השיווק והמכירה של ה-LGP-30. ברויאל-מק'בי הוא כתב את תוכנת הבלאק ג׳ק שהפכה לתוכנת הדגל של החברה. עם השקת ה-RPC-4000, מל שיכתב את תוכנת הבלאק ג׳ק כדי להתאים אותה למחשב החדש, שעבורו כתב גם את שפת הסף, ואף סייע לאד ניית׳ר בכתיבת מהדר פורטרן למחשב. בתחילת שנות ה-60, לאחר חילוקי דעות עם הנהלת החברה, מל עזב את רויאל-מק׳בי. השרידים שנותרו מעבודתו הם "הסיפור על מל", שני צילומי קטעי קוד בכתב יד ומבוא פרי עטו לתוכנת הבלאק ג׳ק המשוכתבת. + +- + +_תמונה ראשית: משמאל לימין - מל קיי ואד ניית׳ר הצעירים, סביבות 1959. איור: **ניר יניב**, ע״פ חומרים ממערכת ״לולאת מל״_ diff --git a/src/components/content/content-blocks/link-selector/link-selector.tsx b/src/components/content/content-blocks/link-selector/link-selector.tsx index a75f5648..6e3b2c2f 100644 --- a/src/components/content/content-blocks/link-selector/link-selector.tsx +++ b/src/components/content/content-blocks/link-selector/link-selector.tsx @@ -5,9 +5,9 @@ import { IContentComponentInitData, NODE_DISPLAY_TYPES, } from "../../../../interfaces/models"; -import { ContentIterator } from "../../content-iterator"; import { Link } from "../link/link"; import AnnotationLink from "../annotation-link"; +import TermLink from "../term-link"; import Popover from "../../../popover"; import { ReactLocaleContext } from "../../../../contexts/locale-context"; import { ReactQueryContext } from "../../../../contexts/query-context"; @@ -23,7 +23,7 @@ const getTriggerComp = ( case DynamicContentTypes.Annotation: return <AnnotationLink className={className} componentData={data} />; default: - return <ContentIterator className={className} componentData={data} />; + return <TermLink className={className} componentData={data} />; } }; diff --git a/src/components/content/content-blocks/list-item/list-item.tsx b/src/components/content/content-blocks/list-item/list-item.tsx index 881eeea4..6fc7840a 100644 --- a/src/components/content/content-blocks/list-item/list-item.tsx +++ b/src/components/content/content-blocks/list-item/list-item.tsx @@ -10,6 +10,7 @@ export const ListItem = (props: ContentComponentProps): JSX.Element => { componentData={{ ...props.componentData, }} + className={props.className} /> </li> ); diff --git a/src/components/content/content-blocks/term-link/index.ts b/src/components/content/content-blocks/term-link/index.ts new file mode 100644 index 00000000..ee914185 --- /dev/null +++ b/src/components/content/content-blocks/term-link/index.ts @@ -0,0 +1,3 @@ +import { TermLink } from "./term-link"; + +export default TermLink; diff --git a/src/components/content/content-blocks/term-link/term-link.st.css b/src/components/content/content-blocks/term-link/term-link.st.css new file mode 100644 index 00000000..b2eead54 --- /dev/null +++ b/src/components/content/content-blocks/term-link/term-link.st.css @@ -0,0 +1,3 @@ +@namespace "TermLink"; + +.root {} diff --git a/src/components/content/content-blocks/term-link/term-link.tsx b/src/components/content/content-blocks/term-link/term-link.tsx new file mode 100644 index 00000000..a9ebdca1 --- /dev/null +++ b/src/components/content/content-blocks/term-link/term-link.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import { ContentComponentProps } from "../../../../interfaces/models"; +import { ContentIterator } from "../../content-iterator"; +import { classes } from "./term-link.st.css"; + +export const TermLink = ({ + componentData, +}: ContentComponentProps): JSX.Element => { + return ( + <ContentIterator componentData={componentData} className={classes.root} /> + ); +}; + +export default TermLink; diff --git a/src/components/content/content-component-mixin.st.css b/src/components/content/content-component-mixin.st.css new file mode 100644 index 00000000..26001cce --- /dev/null +++ b/src/components/content/content-component-mixin.st.css @@ -0,0 +1,23 @@ +@namespace "ContentComponent"; + +@st-import ContentComponent from "./content-component.st.css"; + +:vars { + LinkColor: inherit; + LinkColor_Hover: inherit; +} + +.root { + -st-extends: ContentComponent; +} + +.root:type(link) { + color: value(LinkColor); +} +.root:type(link):hover { + color: value(LinkColor_Hover); +} + +.root:type(paragraph) { + margin-bottom: 1rem; +} diff --git a/src/components/content/content-component.st.css b/src/components/content/content-component.st.css index 602003ad..41f7bafc 100644 --- a/src/components/content/content-component.st.css +++ b/src/components/content/content-component.st.css @@ -13,6 +13,7 @@ blockquote, text, list, + list-item, item, link, image, diff --git a/src/components/content/content-iterator.tsx b/src/components/content/content-iterator.tsx index 08f0a174..b7a0b18d 100644 --- a/src/components/content/content-iterator.tsx +++ b/src/components/content/content-iterator.tsx @@ -42,6 +42,7 @@ export const ContentIterator = ({ <ContentComponent key={mlUtils.uniqueId()} componentData={{ node }} + className={className} /> ); })} diff --git a/src/components/content/dynamic-content-viewer/dynamic-content-viewer-mixin.st.css b/src/components/content/dynamic-content-viewer/dynamic-content-viewer-mixin.st.css index d9d1d511..1d8b513a 100644 --- a/src/components/content/dynamic-content-viewer/dynamic-content-viewer-mixin.st.css +++ b/src/components/content/dynamic-content-viewer/dynamic-content-viewer-mixin.st.css @@ -12,15 +12,3 @@ .root { -st-extends: DynamicContentViewer; } - -.root::contentComponent:type(link) { - color: value(ButtonTextColor); -} - -.root::contentComponent:type(link):hover { - color: value(ButtonTextColor_Hover); -} - -.root::contentComponent:type(paragraph) { - margin-bottom: 1rem; -} diff --git a/src/components/content/generic-page.tsx b/src/components/content/generic-page.tsx index b20686be..de6f092e 100644 --- a/src/components/content/generic-page.tsx +++ b/src/components/content/generic-page.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useContext } from "react"; import { IContentComponentData, IMLParsedNode, @@ -8,12 +8,16 @@ import Layout from "../layout"; import Head from "next/head"; import { ContentIterator } from "./content-iterator"; import { usePageData } from "../usePageData"; -import { classes } from "../../pages/page-base.st.css"; +import { TimeFormat } from "../ui"; +import { ReactLocaleContext } from "../../contexts/locale-context"; +import { st, classes } from "../../pages/page-base.st.css"; export default function GenericPage(props: IContentComponentData) { + const { locale } = useContext(ReactLocaleContext); const { pageData } = usePageData(props.pageProps); const page = pageData && pageData[0]; const metaData = page?.metaData; + const { author, date, abstract } = metaData; const node: IMLParsedNode = page && { children: page.parsed, key: page.id, @@ -26,7 +30,20 @@ export default function GenericPage(props: IContentComponentData) { <title>{metaData?.title}</title> </Head> <article className={classes.root}> - <h1 className={classes.title}>{metaData?.title}</h1> + <header className={classes.header}> + <h1 className={classes.title}>{metaData?.title}</h1> + {abstract && <div className={classes.abstract}>{abstract}</div>} + <div className={st(classes.meta, { hasContent: !!author || !!date })}> + {author && <div className={classes.byline}>{author}</div>} + {date && ( + <TimeFormat + dateStr={date} + locale={locale} + className={classes.date} + /> + )} + </div> + </header> {node ? ( <ContentIterator componentData={{ node }} diff --git a/src/components/menu/menu-mixin.st.css b/src/components/menu/menu-mixin.st.css index bfe27208..4e4d0400 100644 --- a/src/components/menu/menu-mixin.st.css +++ b/src/components/menu/menu-mixin.st.css @@ -27,7 +27,7 @@ ItemLabelLineHeight: inherit; ItemLabelTextWeight: inherit; ItemSubtitleColor: inherit; - /* ItemSubtitleLineHeight: inherit; */ + AbstractTextColor: inherit; ItemSubtitleTextSize: inherit; ItemLabelIconMargin: 0; ViewPortShadow: none; @@ -43,24 +43,19 @@ .root::menuContent { padding: value(ContentPadding); - -st-mixin: bodyTextNormal; + -st-mixin: bodyTextNormal( + BodyTextColor value(AbstractTextColor) + ); } .root::more { - /* -st-mixin: ButtonMixin( - ButtonRadius value(ItemRadius), + -st-mixin: ButtonMixin( ButtonTextColor value(ItemTextColor), ButtonTextColor_Hover value(ItemTextColor_Hover), - ButtonLabelTextColor value(ItemLabelTextColor), - ButtonLabelTextColor_Hover value(ItemLabelTextColor_Hover), - ButtonBgColor_Hover value(ItemBgColor_Hover), - ButtonLabelTextSize value(ItemLabelTextSize), - ButtonLabelLineHeight value(ItemLabelLineHeight), - ButtonLabelTextWeight value(ItemLabelTextWeight), - ButtonSubtitleTextSize value(ItemSubtitleTextSize), - ButtonLabelIconMargin value(ItemLabelIconMargin), - ButtonChildrenTextColor value(ItemSubtitleColor) - ); */ + ButtonPadding 0 + ); + margin-top: 1rem; + display: inline !important; } .root::arrow { @@ -111,11 +106,3 @@ ButtonChildrenTextColor value(ItemSubtitleColor) ); } - -/* .root::more { - -st-mixin: ButtonMixin( - ItemBgColor_Hover red, - ButtonPadding 1rem, - ButtonBgColor_Hover blue - ) -} */ \ No newline at end of file diff --git a/src/components/mobile-menu/mobile-menu.tsx b/src/components/mobile-menu/mobile-menu.tsx index e4015d03..67991413 100644 --- a/src/components/mobile-menu/mobile-menu.tsx +++ b/src/components/mobile-menu/mobile-menu.tsx @@ -1,7 +1,7 @@ import React, { useMemo } from "react"; import { push as Menu } from "react-burger-menu"; import Header from "../header"; -import ThemeSelector from "../theme-selector"; +// import ThemeSelector from "../theme-selector"; import LocaleSelector from "../locale-selector"; import { mlUtils } from "../../lib/ml-utils"; import { renderMenuItem } from "../menu-provider"; @@ -127,9 +127,9 @@ export const MobileMenu = ({ <LocaleSelector className={st(classes.toolbarItem, classes.localeSelector)} /> - <ThemeSelector + {/* <ThemeSelector className={st(classes.toolbarItem, classes.themeSelector)} - /> + /> */} </div> </div> <div className={classes.content}>{menuItems}</div> diff --git a/src/components/post/index.ts b/src/components/post/index.ts new file mode 100644 index 00000000..a7b5c5aa --- /dev/null +++ b/src/components/post/index.ts @@ -0,0 +1,3 @@ +import { Post } from "./post"; + +export default Post; diff --git a/src/components/post/post-mixin.st.css b/src/components/post/post-mixin.st.css new file mode 100644 index 00000000..3ec1663f --- /dev/null +++ b/src/components/post/post-mixin.st.css @@ -0,0 +1,46 @@ +@namespace "PostMixin"; + +@st-import Post from "./post.st.css"; +@st-import [bodyTextNormal] from "../../theme/common/typography.st.css"; + +:vars { + PostTitleColor: inherit; + PostTitleColor_Hover: inherit; + PostTextColor: inherit; + BlogPostShadow: none; + PostTitleBorderColor: inherit; + PostDateTextColor: inherit; +} + +.root { + -st-extends: Post; +} + +.root::wrapper { + margin-top: 4rem; +} + +.root::header { + border-top: 2px solid value(PostTitleBorderColor); + margin-bottom: 2rem; +} + +.root::title { + color: value(PostTitleColor); + padding: 1rem 0 0; +} +.root::title:hover { + color: value(PostTitleColor_Hover); +} + +.root::contentComponent:type(paragraph) { + -st-mixin: bodyTextNormal( + BodyTextColor value(PostTextColor) + ); + margin-bottom: 1rem; +} + +.root::date { + font-size: 12px; + color: value(PostDateTextColor) +} diff --git a/src/components/post/post.st.css b/src/components/post/post.st.css new file mode 100644 index 00000000..4440cdcc --- /dev/null +++ b/src/components/post/post.st.css @@ -0,0 +1,36 @@ +@namespace "Post"; + +@st-import Button from "../ui/button/button.st.css"; +@st-import ContentComponent from "../content/content-component.st.css"; +@st-import [boxSizing] from "../../theme/mixins.st.css"; + +:vars { +} + +.root { + -st-states: textDirection(enum(ltr, rtl)); +} + +.root img { + -st-mixin: boxSizing; + width: 100%; + border: 1px solid black; + margin-bottom: 2rem; + padding: 2px; +} + +.wrapper {} + +.main {} + +.header {} + +.heading {} + +.title {} + +.date {} + +.contentComponent { + -st-extends: ContentComponent +} diff --git a/src/components/post/post.tsx b/src/components/post/post.tsx new file mode 100644 index 00000000..4b26ca82 --- /dev/null +++ b/src/components/post/post.tsx @@ -0,0 +1,58 @@ +import React from "react"; +import { ComponentProps, IParsedPageData } from "../../interfaces/models"; +import { mlUtils } from "../../lib/ml-utils"; +import { ContentComponent } from "../content"; +import { Button, TimeFormat } from "../ui"; +// import { ReactLocaleContext } from "../../contexts/locale-context"; +import { st, classes } from "./post.st.css"; + +export interface IBlogPostProps extends ComponentProps { + title: string; + date: Date; + locale: string; + path: string; + content: IParsedPageData; +} + +export const Post = ({ + title, + date, + locale, + path, + content, + className, +}: IBlogPostProps): JSX.Element => { + // const { siteTitle, siteSubtitle, textDirection } = + // useContext(ReactLocaleContext); + return ( + <div className={st(classes.root, className)}> + <article className={classes.wrapper}> + <header className={classes.header}> + <h2 className={classes.heading}> + <Button label={title} link={`/${path}`} className={classes.title} /> + </h2> + {date && ( + <TimeFormat + dateStr={date} + locale={locale} + className={classes.date} + /> + )} + </header> + <main className={classes.main}> + {content.parsed.map((node) => { + return ( + <ContentComponent + key={mlUtils.uniqueId()} + className={classes.contentComponent} + componentData={{ node }} + /> + ); + })} + </main> + </article> + </div> + ); +}; + +export default Post; diff --git a/src/components/ui/time-formart/time-format.tsx b/src/components/ui/time-formart/time-format.tsx index 07141318..ee7fdd78 100644 --- a/src/components/ui/time-formart/time-format.tsx +++ b/src/components/ui/time-formart/time-format.tsx @@ -15,7 +15,11 @@ const localeFormats = { const getLocaleFormat = (locale: string): string => localeFormats[locale]; -export const TimeFormat = ({ dateStr, locale }: DateProps): JSX.Element => { +export const TimeFormat = ({ + dateStr, + locale, + className, +}: DateProps): JSX.Element => { if (!dateStr) { return null; } @@ -23,7 +27,7 @@ export const TimeFormat = ({ dateStr, locale }: DateProps): JSX.Element => { const date = new Date(dateStr); return ( - <time dateTime={date.toString()} className={st(classes.root)}> + <time dateTime={date.toString()} className={st(classes.root, className)}> {format(date, getLocaleFormat(locale))} </time> ); diff --git a/src/config/pages-data.ts b/src/config/pages-data.ts index 092770a8..0a79b958 100644 --- a/src/config/pages-data.ts +++ b/src/config/pages-data.ts @@ -42,6 +42,11 @@ export const SITE_PAGES: SitePage[] = [ locale: BLOG_PAGE_LOCALE, targetPathname: "/posts", }, + { + id: "post", + locale: BLOG_PAGE_LOCALE, + targetPathname: "/posts/[id]", + }, { id: "error", locale: ERROR_GENERAL_LOCALE, diff --git a/src/contexts/locale-page-context.tsx b/src/contexts/locale-page-context.tsx index 0d4a58b6..a3187330 100644 --- a/src/contexts/locale-page-context.tsx +++ b/src/contexts/locale-page-context.tsx @@ -20,17 +20,17 @@ export default class LocalePageContext implements ILocalePageContext { Record<keyof ComponentKeyMap, string> > | null { const pathData = this.getPathData(this.route); - if (!pathData.locale) { + if (!pathData?.locale) { return null; } return pathData.locale; } public get pageName(): string { - return this.pathLocale.pageName; + return this.pathLocale?.pageName; } public get sectionName(): string { - return this.pathLocale.sectionName; + return this.pathLocale?.sectionName; } } diff --git a/src/interfaces/models.ts b/src/interfaces/models.ts index 5046251f..db2a5ec1 100644 --- a/src/interfaces/models.ts +++ b/src/interfaces/models.ts @@ -136,6 +136,10 @@ export interface IPageMetaData { * Title metadata, if present in the MD */ readonly title: string; + /** + * Abstract metadata, if present in the MD + */ + readonly abstract: string; /** * Moto metadata, if present in the MD */ diff --git a/src/lib/markdown-driver.ts b/src/lib/markdown-driver.ts index ec54c686..17b59668 100644 --- a/src/lib/markdown-driver.ts +++ b/src/lib/markdown-driver.ts @@ -249,6 +249,7 @@ class PageMetaData implements IPageMetaData { public glossary_key = ""; public date: Date = null; public title = ""; + public abstract = ""; public moto = ""; public author = ""; public credits = ""; diff --git a/src/locales/languages/en/locale.ts b/src/locales/languages/en/locale.ts index f7b61e89..3725f7cd 100644 --- a/src/locales/languages/en/locale.ts +++ b/src/locales/languages/en/locale.ts @@ -34,6 +34,11 @@ export const Locale: Language = { SECTION_LABEL_PAGES: "Pages", SECTION_LABEL_LINKS: "Links", + /** + * POSTS + */ + POSTS_BACK_TO_POSTS_LIST: "Back", + /** * MENU SECTIONS */ diff --git a/src/locales/languages/he/locale.ts b/src/locales/languages/he/locale.ts index 79882166..067499e9 100644 --- a/src/locales/languages/he/locale.ts +++ b/src/locales/languages/he/locale.ts @@ -34,6 +34,11 @@ export const Locale: Language = { SECTION_LABEL_PAGES: "דפים", SECTION_LABEL_LINKS: "קישורים", + /** + * POSTS + */ + POSTS_BACK_TO_POSTS_LIST: "חזרה לבלוג", + /** * MENU SECTIONS */ diff --git a/src/locales/languages/types/locale.ts b/src/locales/languages/types/locale.ts index ee1506b9..dc7f6e9e 100644 --- a/src/locales/languages/types/locale.ts +++ b/src/locales/languages/types/locale.ts @@ -18,6 +18,7 @@ export interface ILanguageKeys { SECTION_LABEL_POSTS: "SECTION_LABEL_POSTS"; SECTION_LABEL_PAGES: "SECTION_LABEL_PAGES"; SECTION_LABEL_LINKS: "SECTION_LABEL_LINKS"; + POSTS_BACK_TO_POSTS_LIST: "POSTS_BACK_TO_POSTS_LIST"; MENU_SECTION_LABEL_ARTICLES: "MENU_SECTION_LABEL_ARTICLES"; MENU_SECTION_LABEL_INFO: "MENU_SECTION_LABEL_INFO"; MENU_SECTION_LABEL_CONTACT: "MENU_SECTION_LABEL_CONTACT"; diff --git a/src/pages/page-base-mixin.st.css b/src/pages/page-base-mixin.st.css index 7d8b7f82..41f463da 100644 --- a/src/pages/page-base-mixin.st.css +++ b/src/pages/page-base-mixin.st.css @@ -1,6 +1,7 @@ @namespace "PageBaseMixin"; @st-import PageBase from "./page-base.st.css"; +@st-import [TextNode] from "../theme/mixins.st.css"; @st-import [ heading1, heading2, @@ -23,11 +24,12 @@ Heading1Margin: 2rem; Heading2Margin: 1rem; Heading3Margin: 1rem; - Heading4Margin: 0; + Heading4Margin: 2rem; Heading5Margin: 0; Heading6Margin: 0; SectionMargin: 2rem; ParagraphMargin: 2rem; + ContentHeaderMetaBorderColor: #c0c0c0; } .root { @@ -76,15 +78,30 @@ ); } -.root::contentComponent:type(list) { +.root::contentComponent:type(paragraph) { -st-mixin: bodyTextNormal( BodyTextColor value(BodyTextColor) ); + margin-bottom: value(ParagraphMargin); } -.root::contentComponent:type(paragraph) { - -st-mixin: bodyTextNormal( - BodyTextColor value(BodyTextColor) +.root::abstract { + -st-mixin: heading3( + h3_color value(HeadingColor3) ); - margin-bottom: value(ParagraphMargin); +} + +.root::meta { + -st-mixin: TextNode( + TextSize 1.041vmax, + TextColor value(HeadingColor2) + ); + margin: 2vmax 0 0; + border-color: value(ContentHeaderMetaBorderColor); +} +.root::byline { + text-transform: uppercase; +} +.root::date { + font-weight: 400; } diff --git a/src/pages/page-base.st.css b/src/pages/page-base.st.css index 7e39743e..9fa5887e 100644 --- a/src/pages/page-base.st.css +++ b/src/pages/page-base.st.css @@ -4,8 +4,34 @@ .root {} +/* Header Components */ + +.header { + margin-bottom: 2rem; +} + .title {} +.abstract {} + +.meta { + -st-states: hasContent(boolean); +} +.meta:hasContent { + padding: 1vmax 0; + border-top: 2px solid; + border-bottom: 2px solid; + display: flex; + align-items: center; + align-content: space-between; + justify-content: space-between; +} + +.byline {} +.date {} + +/* ---------------- */ + .genericPage { -st-states: type(string); } diff --git a/src/pages/posts-mixin.st.css b/src/pages/posts-mixin.st.css index 496fe247..71602253 100644 --- a/src/pages/posts-mixin.st.css +++ b/src/pages/posts-mixin.st.css @@ -1,15 +1,13 @@ @namespace "PostsMixin"; @st-import Posts from "./posts.st.css"; +@st-import [heading2, heading3, bodyTextNormal] from "../theme/common/typography.st.css"; -:vars { - BlogPostShadow: none; -} .root { -st-extends: Posts; } -.root::post { - box-shadow: value(BlogPostShadow); +.root::sectionTitle { + -st-mixin: heading2; } diff --git a/src/pages/posts.st.css b/src/pages/posts.st.css index 51fde88f..2f3b0d20 100644 --- a/src/pages/posts.st.css +++ b/src/pages/posts.st.css @@ -1,6 +1,7 @@ @namespace "Posts"; @st-import Button from "../components/ui/button/button.st.css"; +@st-import Post from "../components/post/post.st.css"; @st-import ContentComponent from "../components/content/content-component.st.css"; @st-import FigureBlock from "../components/content/content-blocks/figure/figure.st.css"; @@ -8,31 +9,10 @@ .sectionTitle {} -.post { - margin-bottom: 2rem; - /* border: 1px solid #e0e0e0; */ - /* padding: 4rem; */ - /* box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); */ -} - -.postHeader { - margin-bottom: 2rem; -} - -.postMain {} - -.postHeading { - margin: 0; -} - -.postTitle { - -st-extends: Button; +.contentComponent { + -st-extends: ContentComponent; } -.postTitle:hover {} - -.postDate {} - -.postContent { - -st-extends: ContentComponent; +.post { + -st-extends: Post; } diff --git a/src/pages/posts.tsx b/src/pages/posts.tsx index cc36020c..f9666c9b 100644 --- a/src/pages/posts.tsx +++ b/src/pages/posts.tsx @@ -7,12 +7,11 @@ import { CONTENT_TYPES } from "../consts"; import { mlNextUtils } from "../lib/next-utils"; import { IPageProps, IParsedPageData } from "../interfaces/models"; import { usePageData } from "../components/usePageData"; -import { Button, TimeFormat } from "../components/ui"; -import { ContentComponent } from "../components/content"; import { ReactLocaleContext } from "../contexts/locale-context"; import orderBy from "lodash.orderby"; import { mlUtils } from "../lib/ml-utils"; import { classes } from "./posts.st.css"; +import Post from "../components/post"; export default function Blog(props: IPageProps) { const { locale, siteTitle, pageName, sectionName } = @@ -32,35 +31,15 @@ export default function Blog(props: IPageProps) { const { metaData, path } = page; const { title, date } = metaData; return ( - <article className={classes.post} key={mlUtils.uniqueId()}> - <header className={classes.postHeader}> - <h3 className={classes.postHeading}> - <Button - label={title} - link={`/${path}`} - className={classes.postTitle} - /> - </h3> - {date && ( - <TimeFormat - dateStr={date} - locale={locale} - className={classes.postDate} - /> - )} - </header> - <main className={classes.postMain}> - {page.parsed.map((node) => { - return ( - <ContentComponent - key={mlUtils.uniqueId()} - className={classes.postContent} - componentData={{ node }} - /> - ); - })} - </main> - </article> + <Post + key={mlUtils.uniqueId()} + title={title} + date={date} + path={path} + locale={locale} + content={page} + className={classes.post} + /> ); } )} diff --git a/src/pages/posts/[id].tsx b/src/pages/posts/[id].tsx index b884108c..91a965e9 100644 --- a/src/pages/posts/[id].tsx +++ b/src/pages/posts/[id].tsx @@ -1,12 +1,51 @@ import { GetStaticProps, GetStaticPaths, GetStaticPropsContext } from "next"; import { IPageProps } from "../../interfaces/models"; import { CONTENT_TYPES } from "../../consts"; -import GenericPage from "../../components/content/generic-page"; import { mlNextUtils } from "../../lib/next-utils"; import { LoadFolderModes } from "../../interfaces/parser"; +import Layout from "../../components/layout"; +import Head from "next/head"; +import { usePageData } from "../../components/usePageData"; +import { Button } from "../../components/ui"; +import { mlUtils } from "../../lib/ml-utils"; +import { ReactLocaleContext } from "../../contexts/locale-context"; +import { useContext } from "react"; +import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons"; +import Post from "../../components/post"; +// import { classes } from "../../pages/page-base.st.css"; export default function Doc(props: IPageProps) { - return <GenericPage pageProps={props} />; + const { pageData } = usePageData(props); + const page = pageData && pageData[0]; + const { locale, siteTitle, translate, textDirection } = + useContext(ReactLocaleContext); + const { metaData, path } = page; + const { title, date } = metaData; + + return ( + <Layout> + <Head> + <title> + {siteTitle} - {metaData.title} + </title> + </Head> + <Button + label={translate("POSTS_BACK_TO_POSTS_LIST")} + icon={ + textDirection === "ltr" ? <ChevronLeftIcon /> : <ChevronRightIcon /> + } + link={"/posts"} + /> + <Post + key={mlUtils.uniqueId()} + title={title} + date={date} + path={path} + locale={locale} + content={page} + /> + </Layout> + ); } export const getStaticPaths: GetStaticPaths = async (context) => { diff --git a/src/theme/common/typography.st.css b/src/theme/common/typography.st.css index d0ff3b96..c506807a 100644 --- a/src/theme/common/typography.st.css +++ b/src/theme/common/typography.st.css @@ -9,7 +9,7 @@ fontSize6: 0.833vmax; fontSize7: 0.875rem; fontSize8: 0.75rem; - lineHeight1: 60px; + lineHeight1: 3vmax; lineHeight2: 49px; lineHeight3: 39px; lineHeight4: 31px; @@ -78,7 +78,7 @@ TextWeight value(h1_weight), TextColor value(h1_color) ); - margin-bottom: value(h1_margin); + margin-bottom: 1.302vmax; } .heading2 { diff --git a/src/theme/light/style.st.css b/src/theme/light/style.st.css index c2b690b2..e099804c 100644 --- a/src/theme/light/style.st.css +++ b/src/theme/light/style.st.css @@ -6,6 +6,8 @@ @st-import PostsMixin from "../../pages/posts-mixin.st.css"; @st-import StoryPage from "../../pages/index.st.css"; @st-import StoryPageMixin from "../../pages/index-mixin.st.css"; +@st-import Post from "../../components/post/post.st.css"; +@st-import PostMixin from "../../components/post/post-mixin.st.css"; @st-import Scrollbar from "../../components/scrollbar/scrollbar.st.css"; @st-import ScrollbarMixin from "../../components/scrollbar/scrollbar-mixin.st.css"; @st-import Layout from "../../components/layout/layout.st.css"; @@ -38,6 +40,8 @@ @st-import AnnotationLinkMixin from "../../components/content/content-blocks/annotation-link/annotation-link-mixin.st.css"; @st-import DynamicContentViewer from "../../components/content/dynamic-content-viewer/dynamic-content-viewer.st.css"; @st-import DynamicContentViewerMixin from "../../components/content/dynamic-content-viewer/dynamic-content-viewer-mixin.st.css"; +@st-import ContentComponent from "../../components/content/content-component.st.css"; +@st-import ContentComponentMixin from "../../components/content/content-component-mixin.st.css"; @st-import [ level0, @@ -66,12 +70,20 @@ ] from "./vars.st.css"; @st-scope .root { + ContentComponent { + -st-mixin: ContentComponentMixin( + LinkColor value(LINK_TEXT_COLOR), + LinkColor_Hover value(LINK_TEXT_COLOR_HOVER) + ); + } + PageBase { -st-mixin: PageBaseMixin( HeadingColor1 value(level7), HeadingColor2 value(level6), HeadingColor3 value(level6), - BodyTextColor value(BODY_TEXT_COLOR) + BodyTextColor value(BODY_TEXT_COLOR), + ContentHeaderMetaBorderColor value(level4) ); } @@ -84,6 +96,15 @@ Posts { -st-mixin: PostsMixin( + ); + } + Post { + -st-mixin: PostMixin( + PostTitleColor value(LINK_TEXT_COLOR), + PostTitleColor_Hover value(LINK_TEXT_COLOR_HOVER), + PostTitleBorderColor value(level3), + PostTextColor value(level6), + PostDateTextColor value(BODY_TEXT_COLOR), BlogPostShadow value(shadow3) ); } @@ -130,7 +151,8 @@ ItemSubtitleLineHeight 1rem, ItemSubtitleTextSize 0.85rem, ItemLabelIconMargin 0.35rem, - ViewPortShadow value(shadow1) + ViewPortShadow value(shadow1), + AbstractTextColor value(level6) ); }