teleren/devto huggingface dataset:
Understanding the Rest and Spread operators
Tags: javascript, tutorial, codenewbie
Published: 2021-06-04 02:56:55

> I wrote this post because I was [requested](https://dev.to/siddharthshyniben/what-js-concept-function-should-i-explain-51na#:~:text=Could,?) here. If you have any more requests, just put them on the same post!

In this post I will show you what the rest and spread operators are.

## Rest operator (aka Rest parameters)

The `rest parameter` (`...variable`) is used to select an infinite number of arguments and convert them to an array.

```js
// put three dots behind a variable to make it a rest parameter
function sum(...numbers) {

  // `numbers` is an array of all the arguments
  // It is similar to the `arguments` property

  // The array is a real array, not an array-like
  // So you can use any array functions
  return numbers.reduce((previous, current) => {
    return previous + current;
  });
}

sum(1, 2, 3);
// Here the numbers property will be equal to [1, 2, 3]
```

In plain english, the rest argument converts all comma separated arguments (`1, 2, 3`) and adds brackets to the sides (`[1, 2, 3]`)

You can also add more arguments in functions which use rest parameters.

```js
function map(mapFunc, ...args) {
  return args.map(mapFunc)
}

map(thing => thing*2, 1, 2, 3)
// Here mapFunc is `thing => thing*2`, and args is [1, 2, 3]
```

Just note that only the last argument can be a rest parameter.

```js
foo(...a, ...b)
// Where to stop a and where to start b?

foo(...args, a, b)
// Where to start a?
// You may say this should be allowed and I think the same but it's not allowed.

foo(arg1, arg2, ...correct)
// OK
```

## Spread operator (aka Spread syntax)

Think of this as the opposite of the rest operator

```js
function sum(x, y, z) {
  return x+y+z;
}

let numbers = [1, 2, 3];

// We can't just sum(numbers) because numbers is an array
// So we `spread` the arguments (remove the brackets by putting three dots `...` behind the array) so [1, 2, 3] => 1, 2, 3

sum(...numbers)
```

In plain english, the spread syntax takes an array (`1, 2, 3`) and adds brackets to the sides (`[1, 2, 3]`)

This operator is really useful if you want to merge two arrays 
```js
let arr1 = [1, 2, 3]
let arr2 = [4, 5, 6]

let arr1AndArr2 = [...arr1, ...arr2] 
// => [1, 2, 3, 4, 5, 6]
```

And did you know that the spread syntax can also be used for objects?
```js
let obj1 = { 1: "one", 2: "two" }
let obj2 = { 3: "three", 4: "four" }

let obj1AndObj2 = { ...obj1, ...obj2 }
// => { 1: "one", 2: "two", 3: "three", 4: "four" }
```

That's it! You learned what the spread and rest operators are.
Git Graft: A NPX Tool & Git Hook in TypeScript & Node
Tags: git, githook, typescript, cli
Published: 2021-06-04 02:38:20

# Introduction
I decided I was tired of a GitFlow process. Every time I had to write a commit I had to prepend the JIRA ticket to the commit message, "It's in the branch, why can't it just take it from the branch!?" I kept asking myself. Finally, I said, I will just make that happen.

# The Idea 
Enter in the concept of Git Hooks, more famously known through tooling like Husky (awesome tool btw), however, there is a Git Hook for just about any part of the process of Git, and they have examples (written in shell, I'll get more into that later) in the `.git/hooks` directory. Ok so it's right there, I made a hook what is the big deal? I thought to myself "It took me forever to do this because of the overhead what if I removed that for others?" So I did. 

# The Tool 
[![NPM](https://nodei.co/npm/git-graft.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/git-graft/)

Technologies:
 - TypeScript 
 - NPM/NPX 
 - [Oclif](https://oclif.io/) 
 - [Enquirer](https://github.com/enquirer/enquirer#-getting-started)

So it might come as a bit of a surprise but there are only 2 shell files in this whole CLI tool. They really just execute the JavaScript. Even crazier, I made the `commit-msg` hook entirely JavaScript little trick that I will get into later.

I will go over the CLI & Git Commit Message Hook in the following 2 more blog articles in the series. I want to keep this one short and more of a summary.
ผมเขียน code ห่วย พอเขียน test ก็เจอ bug ตลอด
Tags: bug, coding
Published: 2021-06-04 01:18:13

---
title: ผมเขียน code ห่วย พอเขียน test ก็เจอ bug ตลอด
published: true
description: 
tags: bug,coding
//cover_image: https://direct_url_to_image.jpg
---
(22 สิงหาคม 2562)

code แค่นี้เลย

```Rust
fn cnt_links(s: usize, e: usize, tu: &Textunit, en_sent: &RTok) -> usize {
    tu.links.iter()
        .filter(|link| link.target > s && link.target < e)
        .filter(|link| link.source >= en_sent.s && link.source < en_sent.e)
        .count()
}
```

พอเขียน test แบบยาว ก็เจอจุดพัง

```Rust
#[test]                                                                                                                                                
    fn cnt_links_simple() {
        let tu = Textunit {
            bi_text: BiText { source: String::from(""),
                              target: String::from(""),
            },
            bi_rtoks: BiRToks {
                source: vec![RTok {s:100, e:101, text: String::from(" ")},
                             RTok {s:102, e:103, text: String::from(" ")},],
                target: vec![RTok {s:300, e:301, text: String::from(" ")},
                             RTok {s:302, e:303, text: String::from(" ")},],
            },
            links: vec![Link {source: 0, target: 1},
                        Link {source: 1, target: 0}],

        };
        let en_sent = RTok {s: 302, e:303, text: String::from(" ")};
        assert_eq!(cnt_links(0, 1, &tu, &en_sent), 1);
    }
```

ระบบ type ช่วยอะไรไม่ค่อยได้เพราะมันเป็น integer หมด ยกเว้นจะใช้ type แบบที่มีหน่วยได้ แต่แบบนั้นก็ไม่รู้ว่าโปรแกรมจะยาวกว่านี้อีกเปล่า 

รู้สึกว่าปัญหาของโปรแกรมนี้หลัก ๆ เลยคือ test มันยาวเกิน
Class And Object Concept
Tags: javascript, java, programming
Published: 2021-06-04 02:12:41

Task: You have to build a house on empty land.


- 
The first thing - create structure (how the house will look like) - will go to the architect for a blueprint of the house
![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1622770201057/R7hm299Vs.png)


- 
So, **the blueprint is the class**, you only have a blueprint it's not the actual house.


- 
Now, gather all the materials and other stuff to **build the house according to the blueprint** 

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1622771634908/ZLZwAq1DP.png)


- 
The final build product - **House** - is Object
Is Bitwise operations are faster than Arithmetic operations?
Published: 2021-06-04 02:08:34

Yes, Bitwise operations are alot faster than any arithmetic operations because these operations are performed directly on the bits that is 0 and 1.

There are few examples of bitwise operators: &, |, ~, ^, <<, >>

Here is an example of Bitwise operation for finding even and odd,
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aoss1gvzcaaqxpm5w8pm.png)
In this operation we will get the output Odd.
Intro to Ruby Sinatra
Tags: ruby, sinatra
Published: 2021-06-04 02:08:25

In Python there is Django, the big batteries included web framework. There there is Flask, the minimalist web framework similar ExpressJS on node. In the Ruby world, along with the batteries included Rails framework, there is the Sinatra web framework. Let's take it for a spin.

## Pre-requisites

- Ruby Installed 

## Getting Started

- Create an empty folder

- Install Sinatra `gem install sinatra`

- create a file `server.rb` with the following

```rb
require 'sinatra'

get '/' do
    {"msg": "Hello World"}.to_json
end
```

Run the file `ruby server.rb` and checkout localhost:4567.

As you can see getting a Sinatra server started makes Express and Flask look like Rocket science. We literally just installed a gem and wrote 4 lines of code, no virtual environments, no passing environmental variables, no initiating an application object. Just simplicity.

## Using URL Params

We can designate parts of the url as params with a colon like in express then access the params via the params hash.

```rb
get '/cheese/:type' do
    {"cheese": params["type"]}.to_json
end
```

Let's create another route. In this case visit /route/this?query=that after updating your code.

```rb
get '/route/:param' do
    {"param": params["param"], query: params["query"]}.to_json
end
```

## Learn More

As you can see Sinatra is pretty simple a straightforward. Learn more by [reading the documentation](http://sinatrarb.com/intro.html).
Avoiding old data in Rust channel
Tags: rust, channel
Published: 2021-06-04 01:24:13

---
title: Avoiding old data in Rust channel
published: true
description: 
tags: rust,channel
//cover_image: https://direct_url_to_image.jpg
---

(2019-06-02)

Sometimes a consumer takes a long time to finish a task, and producers keep sending data. This situation can cause a memory leak. Keep processing out-dated data makes no sense in some applications. 

So I write a program to keep receiving data within 10ms time frame, and discard old data. 

````Rust
use std::sync::mpsc::channel;
use std::{thread, time};

fn main() {
    let (tx, rx) = channel();
    thread::spawn(move || {
        let tx_delay_time = time::Duration::from_millis(100);
        loop {
            for i in 1..1000 {
                tx.send(i).expect("Cannot send");
                if i % 10 == 0 {
                    thread::sleep(tx_delay_time);
                }
            }
        }
    });

    let timeout = time::Duration::from_millis(10);
    loop {
        println!("LOOP");
        let mut i = None;
        loop {
            match rx.recv_timeout(timeout) {
                Ok(j) => {
                    i = Some(j);
                },
                Err(_) => {
                    if i.is_some() {
                        break;
                    }
                }
            }
        }
        // long task ...
        println!("{:?}", i);
        i = None;
    }
}
````

I feel that the program look too complicated. Perhaps I shouldn't a channel at all in this case.  🤣
Using Mutex instead of Channel in Rust
Tags: rust, mutex, channel
Published: 2021-06-04 01:21:19

---
title: Using Mutex instead of Channel in Rust
published: true
description: 
tags: rust,mutex,channel
//cover_image: https://direct_url_to_image.jpg
---

(2019-06-02)

When the producer sends messages too frequently, and the producer takes too much time to process each message. I wrote a code for 

I want to discard aging messages and process only the latest one. So I wrote a code for repeating receive messages until the channel is empty for a short duration. However, I found my code was too complicated. So I use shared memory with mutex-lock for inter-thread communication instead of a channel.

````Rust
use std::sync::{Mutex, Arc};
use std::{thread, time};
use std::collections::HashMap;

fn main() {
    let r_shared_data = Arc::new(Mutex::new(None));
    let w_shared_data = r_shared_data.clone();
    
    thread::spawn(move || {
        let tx_delay_time = time::Duration::from_millis(100);
        loop {
            for i in 1..1000 {
                let mut h = HashMap::new();
                h.insert("X", i);
                let mut w = w_shared_data.lock().unwrap();
                *w = Some(h);
                if i % 10 == 0 {
                   thread::sleep(tx_delay_time);
                }                
            }
        }
    });

    let task_proc_time = time::Duration::from_millis(500);
    loop {
         let r = r_shared_data.lock().unwrap();
        dbg!(r);
        // long task
        thread::sleep(task_proc_time);
    }
}

````
ทดลองใช้ speech-to-text ของ Google ถอดเสียงประชุมสภาผู้แทนราษฎร
Tags: asr, google
Published: 2021-06-04 01:19:38

---
title: ทดลองใช้  speech-to-text ของ Google ถอดเสียงประชุมสภาผู้แทนราษฎร
published: true
description: 
tags: asr,google
//cover_image: https://direct_url_to_image.jpg
---

(25 กรกฎาคม 2562)

มันเป็น API อยู่ที่ https://cloud.google.com/speech-to-text/ มีวิธีใช้พร้อม ผมเปลี่ยน config นิดหน่อย ตามนี้ครับ

เขามี[ไฟล์ PDF](http://edoc.parliament.go.th/getfile.aspx?id=708651&file=%E0%B8%84%E0%B8%B3%E0%B9%81%E0%B8%96%E0%B8%A5%E0%B8%87%E0%B8%99%E0%B9%82%E0%B8%A2%E0%B8%9A%E0%B8%B2%E0%B8%A2.pdf&download=1)ให้อ่านด้วยนะครับ

แต่แค่อยากลองว่า Google มันจะฟังออกแค่ไหน

```Ruby
config = { encoding:          :FLAC,
           sample_rate_hertz: 16_000,
           language_code:     "th-TH" }
```

## ไฟล์เสียง

เพื่อใช้ในการวิจัยและไม่ได้มีการหาผลประโยชน์อะไรเลยนะครับ ตามนี้
https://file.veer66.rocks/nlp/sample1min7.flac

## วิธีเตรียมไฟล์เสียงเพื่องานวิจัยและไม่ได้มีการหาผลประโยชน์


อันนี้เอาไฟล์เตรียมไฟล์ video ก่อนเพื่องานวิจัยและไม่ได้มีการหาผลประโยชน์

```
ffmpeg -i http://live.parliament.go.th/livestream/encoder3/playlist.m3u8 -c copy -bsf:a aac_adtstoasc output.mp4
```

แล้วก็แปลงเป็นเสียงเพื่องานวิจัยและไม่ได้มีการหาผลประโยชน์

```
ffmpeg -i output.mp4 sample.mp3
```

หลังจากนั้นผมใช้ [Audacity](https://www.audacityteam.org/) แก้เสียง sample.mp3 ให้เป็น mono 16-bit แล้ว save เป็น .flac ครับ เพื่องานวิจัยและไม่ได้มีการหาผลประโยชน์อีกเช่นเคย

## ผลออกมาได้งี้

>ชาติแห่งชาติขุนกลางยึดมั่นในหลักจริยธรรมและธรรมาภิบาลมีสมรรถนะและความรู้ความสามารถพร้อมต่อการเปิดงานดำเนินการปรับปรุงสวัสดิการสวัสดิภาพชีวิตขวัญกำลังใจความเป็นอยู่ให้เกิดความปลอดภัยในการทำงาน
ลองใช้ Tantivy ซึ่งเอาไว้ทำ Search Engine เขียนด้วย Rust
Tags: tantivy, searchengine, rust
Published: 2021-06-04 01:15:23

---
title: ลองใช้ Tantivy ซึ่งเอาไว้ทำ Search Engine เขียนด้วย Rust
published: true
description: 
tags: tantivy,searchengine,rust
//cover_image: https://direct_url_to_image.jpg
---

(โพสต์เก่า 22 ตุลาคม 2562)

ผมทำตามตัวอย่างที่ https://tantivy-search.github.io/examples/basic_search.html แต่โมพวก field แล้วก็แก้ให้เป็นสองไฟล์แบบที่อยากใช้งาน


## Cargo.toml
````toml
[package]
name = "v_search"
version = "0.1.0"
authors = ["Vee Satayamas <vee.sa@protonmail.com>"]
edition = "2018"

[dependencies]
tantivy = "0.10.2"

[[bin]]
name = "make_index"
path = "src/make_index.rs"

[[bin]]
name = "search"
path = "src/search.rs"
````


## make_index.rs

ส่วนที่ผมงงแรก ๆ เลยคือ STORED อ่านมาบอกว่าสามารถอ่านข้อมูลคืนมาด้วย id เข้าใจว่าถ้า field ไหนไม่ STORED คือทำ index อย่างเดียวจริง ๆ แต่ข้อมูลต้นฉบับหาย แต่ผมก็ยังไม่ลองว่าถ้าไม่ใส่มันจะไม่ได้เชียวหรือ ?

````rust
use tantivy::doc;
use tantivy::schema::*;
use tantivy::Index;

fn main() -> tantivy::Result<()> {
    let index_path = "idx"; 
    let mut schema_builder = Schema::builder();
    schema_builder.add_text_field("textunit", TEXT | STORED);
    let schema = schema_builder.build();
    let textunit = schema.get_field("textunit").unwrap();
    let index = Index::create_in_dir(&index_path, schema.clone())?;
    let mut index_writer = index.writer(50_000_000)?;

    index_writer.add_document(doc!(
        textunit => "A",
    ));

    index_writer.commit()?;
    Ok(())
}
````


## search.rs

````rust
use tantivy::collector::TopDocs;
use tantivy::query::QueryParser;
use tantivy::schema::*;
use tantivy::Index;
use tantivy::ReloadPolicy;

fn main() -> tantivy::Result<()> {
    let index_path = "idx"; 
    let mut schema_builder = Schema::builder();
    schema_builder.add_text_field("textunit", TEXT | STORED);
    let schema = schema_builder.build();
    let textunit = schema.get_field("textunit").unwrap();
    let index = Index::open_in_dir(index_path)?;
    let reader = index
        .reader_builder()
        .reload_policy(ReloadPolicy::OnCommit)
        .try_into()?;
    let searcher = reader.searcher();

    let query_parser = QueryParser::for_index(&index, vec![textunit]);
    let query = query_parser.parse_query("A")?;
    let top_docs = searcher.search(&query, &TopDocs::with_limit(10))?;
    for (_score, doc_address) in top_docs {
        let retrieved_doc = searcher.doc(doc_address)?;
        println!("{}", schema.to_json(&retrieved_doc));
    }
    Ok(())
}
````

อันนี้ผมก็คือทำ index ไว้ใน directory ชื่อ idx แล้ว แล้วอีกไฟล์ก็มา search แค่นี้เลย
backup และ restore index ของ ElasticSearch
Tags: elasticsearch
Published: 2021-06-04 01:07:09

---
title: backup และ restore index ของ ElasticSearch 
published: true
description: 
tags: elasticsearch
//cover_image: https://direct_url_to_image.jpg
---

(โพสต์เก่า 13 พฤศจิกายน 2562)

โพสต์นี้คนอ่านที่เป็นเป้าหมายหลักก็คือผมเอง

อย่างแรกเลยสมมุติว่า ElasticSearch ที่รันอยู่แล้ว

สร้าง dir ที่จะเก็บ snapshot และ chown ให้เป็นของ user เดียวกับที่ daemon ของ elasicsearch รันอยู่

แก้ elasticsearch.yml ที่ path.repo ให้ชี้ไปที่ dir ที่สร้างไว้ในข้อ 1 เช่น ["/bak/b1"] ไรงี้

## backup/snapshot

สร้าง repo

```sh
curl -X PUT "localhost:9200/_snapshot/my_backup?pretty" -H 'Content-Type: application/json' -d'
{
  "type": "fs",
  "settings": {
    "location": "/bak/b1"
  }
}
'
```

## restore

สร้าง repo

```sh
curl -X PUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true&pretty"
```

ตอนนี้ก็คือจะเสร็จแล้ว สิ่งที่ผมทำคือ rsync /bak/b1 ไปเครื่องอื่นแล้วลอง restore เพื่อไม่ให้น่าเบื่อเครื่องอื่นที่ว่าก็จะใช้ docker ด้วย 

พอ rsync มาแล้ว ก็ chown -R 1000:1000 $(pwd)/bak/b1

สร้าง elasticsearch.yml 

```sh
cluster.name: "docker-cluster"
network.host: 0.0.0.0
path.repo: ["/usr/share/elasticsearch/bak"]
```

รัน ElasticSearch ผ่าน Docker

```sh
docker run \
       --name=es6 \
       --net=host \
       -e "discovery.type=single-node" \
       -v $(pwd)/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
       -v $(pwd)/bak/b1:/usr/share/elasticsearch/bak \
       docker.elastic.co/elasticsearch/elasticsearch:6.8.4
```

สร้าง repo

```sh
curl -X PUT "localhost:9200/_snapshot/my_backup?pretty" -H 'Content-Type: application/json' -d'
{
  "type": "fs",
  "settings": {
    "location": "/usr/share/elasticsearch/bak"
  }
}
'
```

สั่ง restore

```sh
curl -X PUT "localhost:9200/_snapshot/my_backup?pretty" -H 'Content-Type: application/json' -d'
{
  "type": "fs",
  "settings": {
    "location": "/usr/share/elasticsearch/bak"
  }
}
'
```

เสร็จแล้ว

คำสั่งต่าง ๆ ก็มาจาก [guide](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html) ครับ
ใช้ Google Drive บน Colab
Tags: google, colab, drive
Published: 2021-06-04 01:05:58

---
title: ใช้ Google Drive บน Colab
published: true
description: 
tags: google,colab,drive
//cover_image: https://direct_url_to_image.jpg
---

(โพสต์เก่า 22 พฤศจิกายน 2562)

```python
from google.colab import drive
drive.mount('/content/drive')
```

```python
import os
os.listdir('/content/drive/My Drive')
```
ความมีรูปแบบอย่างเดียวกัน
Published: 2021-06-04 01:04:58

---
title: ความมีรูปแบบอย่างเดียวกัน 
published: true
description: 
tags: 
//cover_image: https://direct_url_to_image.jpg
---

(จาก qua.name 25 พฤศจิกายน 2562)

ใน Python ตาม code ข้างล่าง append เป็น method ของ object a แต่พอมานับจำนวนสมาชิกใช้ len(a) ซึ่ง len เป็น built-in function แทน ถ้าอยากให้มีรูปแบบเดียวกันเปลี่ยนจาก len(a) ไปเป็น a.\_\_len\_\_() ก็ได้ แต่ก็จะมี ____ เกินมาอีก ใน Python เองก็คงจะมีหลักเกณฑ์ว่าเมื่อไหร่อะไรจะเป็น function อะไรจะเป็น method ซึ่งก็อาจจะต้องเรียนรู้หรือจำไว้

```python
a = [1, 2, 3, 4, 5]
a.append(10)
print(len(a))
```

ใน JavaScript ก็มีรูปแบบที่ต่างกันคือ push เป็น method แต่ length เป็น property สังเกตได้จากว่าตอนเรียกไม่มีวงเล็บ ใน JavaScript ก็คงมีหลักการว่าเมื่อไหร่อะไรจะเป็น method หรือเป็น property ซึ่งก็ต้องเรียนรู้หรือจำไว้

```javascript
a = [1, 2, 3, 4, 5]
a.push(10)
console.log(a.length)
```

ใน Ruby ทีนี้เหมือนกันแล้วคือ push ก็เป็น method และ length ก็เป็น method 

```ruby
a = [1, 2, 3, 4, 5]
a.push(10)
p(a.length)
```

แต่ก็ยังมีประเด็นต่อไปอีกว่าทำไมใน Ruby เขียนแบบนี้

```ruby
10 + 20 + 30 + 40 + 50
```

ไม่เป็น method และเรียกเหมือนอย่างอื่นบ้างล่ะ

```
10.+(20).+(30).+(40).+(50)
```

(Emacs) Lisp จะต่างกับอันอื่นหน่อย ตรงที่ push มันไปต่อหน้าแทนที่จะต่อหลัง

```Lisp
(setq a '(1 2 3 4 5))
(push 10 a)
(print (length a))
(+ 10 20 30 40 50)
```

เขียน Lisp นี่ทุกอย่างก็จะเรียงเหมือนกันหมดเลย ได้แก่ (push ...) (length ...) (+ ...) ไม่เดี๋ยวต่อหน้า len(...) หรือเดี๋ยวต่อหลังเป็น a.length หรือว่าเดี๋ยวมีหรือไม่มีวงเล็บ เช่น a.length กับ a.length 

แต่ปัญหาที่มันจะเจอคือหลายท่านรับไม่ได้ที่วงเล็บไปอยู่ข้างหน้าชื่อ function ถึงกับว่ามันวงเล็บย้ายที่แล้วเขียนไม่ได้เลย 

แต่ Julia ก็เขียนแบบนี้ได้ append! ก็เป็น length ก็เป็น function ทั้งคู่ แถมตอนบวกก็เขียนแบบ function ได้ด้วย 

```Julia
a = [1,2,3,4,5]
append!(a,10)
print(length(a))
+(10,20,30,40,50) # จะเขียนแบบ 10 + 20 + 30 + 40 + 50 ก็ได้
```

แต่ก็อาจจะคิดได้ว่าทำเวลาสร้าง array ไม่เป็น function บ้าง ก็อาจจะเปลี่ยน [1,2,3,4,5] เป็น push!([],1,2,3,4,5) แทน ทีนี้ก็จะเหลือแต่ = แล้วที่ดูไม่เหมือนอย่างอื่น ซึ่งอันนี้ผมก็นึกวิธีแก้ให้มันเหมือนกันไม่ออก
เปลี่ยน default font ของ MX Linux
Tags: font, linux, gnulinux
Published: 2021-06-04 01:04:16

---
title: เปลี่ยน default font ของ MX Linux
published: true
description: 
tags: font,linux,gnulinux
//cover_image: https://direct_url_to_image.jpg
---

(จาก qua.name 24 มิถุนายน 2563) 

บางทีเปลี่ยน font แล้วลง พวก Noto เรียนร้อยแล้วก็ยังไม่ได้อย่างใจ บางทีเป็นเพราะว่าระบบจะเลือก font ให้เราเอง ซึ่งไปแก้ได้ในไฟล์

ผมชึ้นหัวว่า MX Linux แต่จริง ๆ จะใช้ Void Linux, Ubuntu กระทั่งพวก NetBSD ก็น่าจะเหมือนกันหมด

$HOME/.config/fontconfig/fonts.conf

ซึ่งอันนี้ผมแก้ตาม https://jichu4n.com/posts/how-to-set-default-fonts-and-font-aliases-on-linux/ และ https://wiki.archlinux.org/index.php/Font_configuration/Examples

สมมุติว่าในกรณีที่ลง Noto แต่ไม่มี font ของ TLWG นะครับ ใส่ไปแบบนี้

````xml
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
  <match>
    <test compare="contains" name="lang">
      <string>th</string>
    </test>
    <edit mode="prepend" name="family">
      <string>Noto Sans Thai</string>
    </edit>
  </match>
  <alias>
    <family>serif</family>
    <prefer>
      <family>Noto Serif</family>
    </prefer>    
  </alias>
  <alias>
    <family>sans-serif</family>
    <prefer>
      <family>Noto Sans</family>
    </prefer>    
  </alias>
  <alias>
    <family>sans</family>
    <prefer>
      <family>Noto Sans</family>
    </prefer>    
  </alias>
  <alias>
    <family>monospace</family>
    <prefer>
      <family>Noto Mono</family>
    </prefer>    
  </alias>
</fontconfig>
````

แต่ทำไปทำมาก็รู้สึกว่าไม่ค่อยโดยเท่าไหร่ ผมก็ลง Loma แล้วเปลี่ยน Noto Sans Thai เป็น Loma อยู่ดี
วิธีปรับแต่ง font ของ MX Linux
Tags: font, linux, gnulinux
Published: 2021-06-04 01:02:52

---
title: วิธีปรับแต่ง font ของ MX Linux
published: true
description: 
tags: font,linux,gnulinux
//cover_image: https://direct_url_to_image.jpg
---

(จาก qua.name 17 สิงหาคม 2563)

* sudo apt-get install fonts-noto fonts-noto-extra fonts-noto-core fonts-noto-mono fonts-noto-ui-core fonts-noto-ui-extra fonts-noto-cjk fonts-noto-unhinted fonts-noto-hinted fonts-noto-cjk-extra fonts-noto-color-emoji
* mkdir -p $HOME/.config/fontconfig
* cat > $HOME/.config/fontconfig/fonts.conf

แปะอันนี้ใส่ไป

````
<?xml version='1.0'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
  <match>
    <test compare="contains" name="lang">
      <string>th</string>
    </test>
    <edit mode="prepend" name="family">
      <string>Noto Sans Thai</string>
    </edit>
  </match>
  <alias>
    <family>serif</family>
    <prefer>
      <family>Noto Serif</family>
    </prefer>    
  </alias>
  <alias>
    <family>sans-serif</family>
    <prefer>
      <family>Noto Sans</family>
    </prefer>    
  </alias>
  <alias>
    <family>sans</family>
    <prefer>
      <family>Noto Sans</family>
    </prefer>    
  </alias>
  <alias>
    <family>monospace</family>
    <prefer>
      <family>Noto Mono</family>
    </prefer>    
  </alias>
</fontconfig>
````

* กด control D 

เสร็จ