האם עורך הטקסט שלכם מסוגל לעשות את זה?

פוסט זה כולל טיפ קצר על כלי עבודה בסביבת Linux. בשביל ללמוד יותר על עבודה בסביבת Linux ו Unix אני ממליץ לכם לבדוק את קורס Linux שיש לנו כאן באתר. הקורס כולל מעל 50 שיעורי וידאו והמון תרגול מעשי ומתאים גם למתחילים.
 

נניח שאתם רוצים לבנות גלריית תמונות מבוססת HTML מתוך תיקיית תמונות על המחשב. עבור כל תמונה נצטרך לרשום אלמנט img מתאים עם src ו alt, עטוף בכמה אלמנטי div כדי שיהיה קל לעצב אותו. עכשיו נניח ויש לכם כמה עשרות תמונות כאלו בתיקייה —כיצד נבנה את קובץ ה HTML ?

1. מה כבר ביקשתי

כך נראות השורות הרלוונטיות בקובץ ה HTML עבור תמונה ספציפית:

<div class="col-md-3">
  <div class="gallery-item">
    <img src="/img/demo-01.png" class="img-responsive" alt="demo image" />
  </div>
</div>

שם התמונה על הדיסק הוא demo-01.png. עבור תוכן מאפיין alt ארצה להסיר את הסיומת והמספר המלווה (במידה ומופיע). המעטפת מגיעה מ Twitter Bootstrap והופכת את העיצוב לנוח. הבעייה היא שיש כמה עשרות תמונות כאלו וחצי שעה של קופי-פייסט לא היתה בתוכנית העבודה להיום. 

2. וים מציל את היום

הבה נפתח וים ונראה מה אפשר לעשות. נכתוב את הבלוק עבור תמונה אחת בראש קובץ ה HTML. לאחר מכן נדביק פנימה את כל שמות התמונות מהדיסק. וים מאפשר הרצת פקודת יוניקס והדבקת התוצאה ל Buffer באמצעות פקודת read. הפקודה:

:r! ls *.png

עשתה את העבודה והוסיפה את שמות כל קבצי ה png מהתיקייה לסוף הקובץ. זה מה שקיבלנו:

<div class="col-md-3">
  <div class="gallery-item">
    <img src="/img/demo-01.png" class="img-responsive" alt="demo image" />
  </div>
</div>

flowers-01.png
table-01.png
trees-03.png
water-02.png
zoo-01.png
 

כעת עלינו להפריד את שם התמונה מהסיומת והמספר כדי שנוכל להדביק כל חלק במקום הנכון. אני בחרתי בהחלפת ביטוי רגולרי על שמות הקבצים. באמצעות V סימנתי את כל שמות הקבצים והפעלתי את הפקודה:

:'<,'>s/\v(\w+)(.*)/\1\2\t\1/

התוצאה היא החלפת כל שם קובץ בשתי מילים, תחילה שם הקובץ המלא ולאחריו רק המילה המתאימה לתוכן ה alt. כך נראה הקובץ כעת:

<div class="col-md-3">
  <div class="gallery-item">
    <img src="/img/" class="img-responsive" alt=" image" />
  </div>
</div>


flowers-01.png  flowers
table-01.png  table
trees-03.png  trees
water-02.png  water
zoo-01.png  zoo

עכשיו מגיע החלק המעניין — יש לקחת את הבלוק מהכותרת ולשכפל אותו עבור כל שורה, כאשר בכל שורה נרצה ״לשתול״ את הטקסט במקום הנכון. אני לא בטוח שהפתרון שלי הוא הפשוט ביותר אבל אני בחרתי להשתמש במקרו: הקלטת רצף פעולות והפעלתו מחדש שוב ושוב על כל אחת מהשורות. אנו מקליטים מקרו באמצעות המקש q ולאחריו אות המייצגת את שם המקרו. אני אוהב להשתמש ב qq כי זה קרוב. סיום הקלטת המקרו גם כן באמצעות q.

לפני ההקלטה העתקתי את בלוק ה HTML לרגיסטר a באמצעות סימונו והקלדת:

"ay

המקרו עצמו כולל העתקת המילה הראשונה לרגיסטר z והמילה השניה לרגיסטר x. לאחר מכן הדבקת הבלוק באמצעות "ap ואז תנועה למקום הנכון בבלוק והדבקת רגיסטרים z ו x במקומות המתאימים. חשוב לסיים את המקרו במצב בו אתם מוכנים להפעיל אותו על השורה הבאה, לכן בסוף שורת המקרו המשכתי לשורה הבאה לפני סיום ההקלטה. בהקלטת מקרו מומלץ להשתמש בכפתורי התנועה hjkl ולא בחיצים, כך שאפשר להציג אותו יותר בקלות בהמשך.
כך נראה המקרו:

"zdEw"xdEdd"aPjjf";"zP;;;;"xpjjj0

מקרו נשמר ברגיסטר רגיל ולכן אין בעיה להציג את תוכנו באמצעות הפקודה reg q. את המקרו אפשר להפעיל שוב ושוב באמצעות @q בפעם הראשונה, ולאחר מכן באמצעות @@ להפעלה חוזרת של המקרו האחרון שהפעלתם. מאחר והמקרו מסתיים בשורה הבאה קל מאוד ללחוץ @q ולאחר מכן @@ עד סוף הקובץ, או אם אתם יודעים כמה שורות יש אפשר להריץ את המקרו עם מספר הפעלות, לדוגמא 4@q.

3. ומכאן זה רק משתפר

רוצים להריץ את המקרו עד סוף הקובץ בלי לספור כמה שורות יש? גם אפשרי, פשוט צריך להקליט את המקרו קצת אחרת. וים יפסיק הרצת מקרו אם אחת הפקודות נכשלה, ולכן אנו יכולים להתחיל את המקרו בפקודה שתכשל בסוף הקובץ אבל לא תשנה את המיקום, למשל הפקודה jk. 
כדי לעדכן מקרו לאחר הקלטתו אין צורך להקליט מחדש. הקלידו באחת השורות בקובץ את המקרו עם התיקון:

jk"zdEw"xdEdd"aPjjf";"zP;;;;"xpjjj0

כעת לכו לתחילת השורה והעתיקו אותה לרגיסטר q (הרגיסטר שמחזיק את המקרו שלנו) באמצעות "qy$.
כעת אפשר להמשיך לשם הקובץ הבא ולהשתמש בפקודה 100@q כדי להריץ את המקרו 100 פעמים. יש פחות שורות? לא נורא, וים יעצור בסוף הקובץ. כך נראה הקובץ בסיום התהליך:

<div class="col-md-3">
  <div class="gallery-item">
    <img src="/img/flowers-01.png" class="img-responsive" alt="flowers image" />
  </div>
</div>
<div class="col-md-3">
  <div class="gallery-item">
    <img src="/img/table-01.png" class="img-responsive" alt="table image" />
  </div>
</div>
<div class="col-md-3">
  <div class="gallery-item">
    <img src="/img/trees-03.png" class="img-responsive" alt="trees image" />
  </div>
</div>
<div class="col-md-3">
  <div class="gallery-item">
    <img src="/img/water-02.png" class="img-responsive" alt="water image" />
  </div>
</div>
<div class="col-md-3">
  <div class="gallery-item">
    <img src="/img/zoo-01.png" class="img-responsive" alt="zoo image" />
  </div>
</div>

 

4. סיכום וקריאת המשך

עורך טקסט טוב נמצא שם בשבילכם ברגעים הקשים וחוסך עבודת הקלדה מייגעת. גם אם כלי מסוים נראה מורכב או מרתיע ממבט ראשון, החסכון בזמן של עורך טקסט טוב בטווח הרחוק עולה על ההשקעה בלמידה שלו.

יש עוד דרכים רבות נוספות לבצע את הפעולה שהצגתי, גם בעורכי טקסט אחרים וגם מחוץ לעורך הטקסט, לדוגמא באמצעות Shell Script. בפוסט ה Shell Script הראשון שלי הצגתי הצעה לבניית סקריפט הכותב לקובץ מידע משתנה על בסיס תבנית.

הבלוג usevim פרסם בעבר פוסט ידידותי למתחילים על שימוש במקרואים אותו אפשר למצוא בקישור:
http://usevim.com/2012/08/10/macros

סקירה מתקדמת יותר של מקרואים והיכולות שלהם אפשר למצוא בקישור:
http://blog.sanctum.geek.nz/advanced-vim-macros

ונסיים עם מדריך להקלטת מקרו רקורסיבי:
http://vim.wikia.com/wiki/Record_a_recursive_macro