All GTK 3 Style Properties

All GTK 3 Style Properties

【摘要】提供一個能將所有 GTK 3 style properties 收集成一個檔案的 BASH 指令,並詳細解析之。


【目錄】

    【前言
    【指令解析
        A. 基本設定
        B. 主要指令
        C. 加入 html5 檔尾並結束程式
    【後語
    【附錄

【前言】

一、設定 GTK 3 的樣式時,一定會用到 CSS nodes 和 style properties。但這些資料分散在各個 widget 的說明中,不利查詢。如果集中到一個檔案裡,會比較方便。本文敘述收集 style properties 的方法,另一篇敘述收集 CSS nodes 的方法


二、本文約半年前曾在 Google 的 Blogger 發表過,近日再度檢視,更新後發表於此。


三、來源資料是官網的 “GTK 3 Reference Manual“,目前的版本是 3.24.13。下載的檔案應是 gtk3-html-3.24.13.tar.gz,以下假設解開在自家的 $HOME/Documents/gtk3-html-3.24.13/ 目錄中。


四、收集的方法是用常見的 BASH 和 Linux 指令,作業系統是 Debian GNU/Linux 10


五、輸出的資料不含過時不用的 (deprecated) 項目。


六、最後的【附錄】有完整的指令,可以複製到一個空白檔案中;假設檔名是 get_style_prop.sh,執行 bash get_style_prop.sh 即可。


【指令解析】

仔細觀察參考手冊 widget 的說明,可以知道每個都是 .html 檔,而且語法結構相當規律。html 文件有固定的 tags (標籤),我們就利用這些特性,搜尋各個 html 文件中的某些特定標籤,將相關的內容輸出到一個檔案裡。以下依序說明每個指令。

A. 基本設定

⒈ 指定參考手冊所在的目錄

PathIn=$HOME/Documents/gtk3-html-3.24.13

⒉ 指定輸出檔的目錄和檔名

假設是自己的 Documents 目錄,檔名可以自訂。

PathOut=$HOME/Documents
FileOut=GTK3-style_prop.html

提醒:若已有此檔,會被覆寫。


⒊ 複製樣式檔

官方參考手冊中,每個 widget 的 html 檔都使用同一個 CSS 樣式檔。我們從這些 html 檔取出資料,也要用這個樣式檔,才能正確顯示結果。

cp ${PathIn}/style.css ${PathOut}

⒋ 新增或清空輸出檔

: > ${PathOut}/${FileOut}

⒌ 加入 html5 檔頭

因為輸出的檔案也是 html 格式,所以頭尾要有基本的 elements。

echo '<!DOCTYPE html>' >> ${PathOut}/${FileOut}
echo '<html>' >> ${PathOut}/${FileOut}
echo '<head>' >> ${PathOut}/${FileOut}
echo '  <title>Style Properties</title>' >> ${PathOut}/${FileOut}
echo '  <meta charset="UTF-8">' >> ${PathOut}/${FileOut}
echo '  <link rel="stylesheet" href="style.css" type="text/css">' >> ${PathOut}/${FileOut}
echo '</head>' >> ${PathOut}/${FileOut}
echo '<body>' >> ${PathOut}/${FileOut}

B. 主要指令

⒈ 每個 widget 的 html 檔名都是以 Gtk 開頭,所以可以很容易地找出來。

for FileIn in $(ls ${PathIn}/Gtk*.html)
do

⒉ 這些說明檔在敘述 style properties 時,都分在 “Style Property Details" 一節中,所以逐行讀入時,就檢查是否有此內容。一開始還沒有時,先將標記設為 0。

Flag1=0

⒊ “Style Property Details" 一節的內容是由 <div class="refsect2″> 開始;這也要有個標記,才知道內容的開始與結束。

Flag2=0

⒋ 因為要去除過時的項目,而一個項目是否過時並不是標在內容的第一行,所以必需把一個樣式的內容先儲存起來,再來檢查。若非過時,便將內容輸出;若已過時,則清除之。一開始先設為空字串。

Content=""

⒌ 逐行讀入。

while read
do

⒍ 檢查所需資料是否開始。

if [[ ${REPLY} =~ .*\>Style\ Property\ Details\<.* ]]

${REPLY} 就是剛讀入的那一行。但其他地方也可能有 “Style Property Details",所以連前後的角括號(<h2>Style Property Details</h2>)也包括在內。


⒎ 若是,表示所需內容開始。

then
Flag1=1

⒏ 取出 Widget 名稱;先從全路徑中取出檔名,再去掉副檔名。

FileIn=`basename ${FileIn}` && WidgetName=${FileIn::(-5)}

⒐ 輸出 Widget 名稱並設為標題放大字體,以便區別各個 widget。

echo "<h3>${WidgetName}</h3>" >> ${PathOut}/${FileOut}

⒑ 去讀下一行。

continue
fi

⒒ 以上的 if 是找到開頭處,以下收集內容,並看內容是否結束。

if [[ ${Flag1} -eq 1 ]]
then

⒓ 若欲收集的資料已開始,會有多種狀況,一一處理。這些狀況全憑多次試驗而來。

第一種狀況:若開始一個 <div class="refsect2″>,要加以標記,因為 “Style Property Details" 一節的內容由此開始。

if [[ ${REPLY} =~ .*class=\"refsect2.* ]]
then
Flag2=1

⒔ 既然所需資料已經開始,就開始收集內容。

Content="${REPLY}"

⒕ 去讀下一行。

continue
fi

⒖ 第二種狀況:若是一個樣式的下一行,就繼續累積內容。

if [[ ${Flag2} -eq 1 ]]
then
Content="${Content}\n${REPLY}"

⒗ 第三種狀況:若是一個樣式的結束,就先做記號,再輸出累積的內容。資料輸出後,清除內容,才繼續。

if [[ ${REPLY} =~ .*\</div.* ]]
then
Flag2=0
echo -e "${Content}" >> ${PathOut}/${FileOut}
Content=""
continue
fi

⒘ 第四種狀況:是否過時?若是,就先做記號,再清除已累積的過時內容,才繼續。

if [[ ${REPLY} =~ .*been\ deprecated.* ]]
then
Flag2=0
Content=""
continue
fi
fi

⒙ 第五種狀況:下一節開始或已到頁腳,表示所需資料結束。畫一條線隔開不同的 widget,以利閱讀,並結束此檔。

if [[ ${REPLY} =~ .*class=\"refsect1.* || ${REPLY} =~ .*class=\"footer.* ]]
then
echo "<hr>" >> ${PathOut}/${FileOut}
break
fi
fi

done < ${FileIn}

這是讀入某一檔。

done

這是結束讀入所有 Gtk*.html。


C. 加入 html5 檔尾並結束程式

echo '</body>' >> ${PathOut}/${FileOut}
echo '</html>' >> ${PathOut}/${FileOut}

exit

【後語】

從上述的內容可知,指令決定於官方參考手冊的 html 語法。所以,可以預見的是當這些語法改變時,指令可能也要修正。


【附錄】

#!/usr/bin/bash
 
PathIn=$HOME/Documents/gtk3-html-3.24.13
PathOut=$HOME/Documents
FileOut=GTK3-style_prop.html
 
cp ${PathIn}/style.css ${PathOut}
 
: > ${PathOut}/${FileOut}
 
echo '<!DOCTYPE html>' >> ${PathOut}/${FileOut}
echo '<html>' >> ${PathOut}/${FileOut}
echo '<head>' >> ${PathOut}/${FileOut}
echo '  <title>Style Properties</title>' >> ${PathOut}/${FileOut}
echo '  <meta charset="UTF-8">' >> ${PathOut}/${FileOut}
echo '  <link rel="stylesheet" href="style.css" type="text/css">' >> ${PathOut}/${FileOut}
echo '</head>' >> ${PathOut}/${FileOut}
echo '<body>' >> ${PathOut}/${FileOut}
 
for FileIn in $(ls ${PathIn}/Gtk*.html)
do
  Flag1=0
  Flag2=0
  Content=""
  while read
  do
    if [[ ${REPLY} =~ .*\>Style\ Property\ Details\<.* ]]
    then
      Flag1=1
      FileIn=`basename ${FileIn}` && WidgetName=${FileIn::(-5)}
      echo "<h3>${WidgetName}</h3>" >> ${PathOut}/${FileOut}
      continue
    fi
 
    if [[ ${Flag1} -eq 1 ]]
    then
 
      if [[ ${REPLY} =~ .*class=\"refsect2.* ]]
      then
        Flag2=1
        Content="${REPLY}"
        continue
      fi
 
      if [[ ${Flag2} -eq 1 ]]
      then
        Content="${Content}\n${REPLY}"
 
        if [[ ${REPLY} =~ .*\</div.* ]]
        then
          Flag2=0
          echo -e "${Content}" >> ${PathOut}/${FileOut}
          Content=""
          continue
        fi
 
        if [[ ${REPLY} =~ .*been\ deprecated.* ]]
        then
          Flag2=0
          Content=""
          continue
        fi
      fi
 
      if [[ ${REPLY} =~ .*class=\"refsect1.* || ${REPLY} =~ .*class=\"footer.* ]]
      then
        echo "<hr>" >> ${PathOut}/${FileOut}
        break
      fi
    fi
 
  done < ${FileIn}
done
 
echo '</body>' >> ${PathOut}/${FileOut}
echo '</html>' >> ${PathOut}/${FileOut}
 
exit

發表留言